Skip to content
Agentic Control Plane

Roll ACP out to every Claude Code seat

Claude Code has the cleanest rollout of the four harnesses: managed settings can force-enable a plugin from a marketplace, and Claude Code fetches it at startup. Nothing is copied to any machine, and the claude.ai admin console can deliver the whole thing without MDM. Anthropic’s managed settings, admin setup, hooks, managed MCP, and plugin marketplaces pages are the source for every key below. Read the shape all four harnesses share first if you haven’t.

Before you push

  1. Claim your company domain on the ACP workspace’s Team page so enrollments land in your workspace (why).
  2. Decide the posture for unenrolled seats. The sample sets ACP_REQUIRE_ENROLLMENT to 1 in the managed env, so a seat with no credential blocks each tool call with the enrollment step. Remove the key for the self-serve posture (run, warn, log).
  3. Note what allowManagedHooksOnly takes with it: user, project, local, and plugin hooks other than managed-enabled plugins stop running, and status-line and file-suggestion settings narrow to managed. If teams rely on their own hooks, start without it and add it once you’ve read the audit stream.

The managed settings

{
  "extraKnownMarketplaces": {
    "acp": {
      "source": { "source": "github", "repo": "agentic-control-plane/claude-code-acp-plugin" }
    }
  },
  "enabledPlugins": {
    "agentic-control-plane@acp": true
  },
  "allowManagedHooksOnly": true,
  "env": {
    "ACP_REQUIRE_ENROLLMENT": "1"
  },
  "allowedMcpServers": [
    { "serverUrl": "https://api.agenticcontrolplane.com/*" }
  ],
  "permissions": {
    "disableBypassPermissionsMode": "disable"
  }
}

What each key does:

  • extraKnownMarketplaces registers ACP’s marketplace, the same one the self-serve installer adds with claude plugin marketplace add agentic-control-plane/claude-code-acp-plugin. Pair it with strictKnownMarketplaces if you want this to be the only marketplace users can add.
  • enabledPlugins force-enables the plugin. Plugins enabled in managed settings can’t be disabled from user settings, and the plugin’s PreToolUse, PostToolUse, and SessionStart hooks come with it. The plugin runs the same govern.mjs the installer writes to ~/.acp.
  • allowManagedHooksOnly blocks hooks from every other source. Hooks from plugins force-enabled in managed enabledPlugins are exempt, which is exactly the ACP case.
  • env applies to every session and its subprocesses, so the plugin’s hook sees ACP_REQUIRE_ENROLLMENT without any per-machine wrapper.
  • allowedMcpServers permits ACP’s endpoint by URL. It doesn’t add the server; see below.
  • disableBypassPermissionsMode removes --dangerously-skip-permissions. Not an ACP key, but every fleet should set it: ACP’s hook runs regardless, and this closes the harness-side hole next to it.

Deliver it

Four mechanisms, highest priority first. Within the managed tier the first source that supplies a key wins, unless the top source sets managedSourcesBehavior to merge.

Mechanism Where Notes
Server-managed claude.ai admin console (or a self-hosted gateway) No MDM. Polled by clients. Shell-command settings such as hooks in the settings body prompt an approval dialog in interactive sessions; a plugin enabled from a marketplace is how this sample avoids that.
OS policy macOS: com.anthropic.claudecode managed preferences · Windows: HKLM\SOFTWARE\Policies\ClaudeCode, a REG_SZ value named Settings holding the JSON Same top-level keys, nested as plist dictionaries on macOS. Managed preferences means a configuration profile from your MDM: the same keys written to a user’s own defaults with defaults import are ignored (checked on 2.1.260, where the debug log shows the MDM load finding nothing).
System file macOS /Library/Application Support/ClaudeCode/managed-settings.json · Linux and WSL /etc/claude-code/managed-settings.json · Windows C:\Program Files\ClaudeCode\managed-settings.json Plus a managed-settings.d/ directory merged alphabetically. Claude Code doesn’t read the old C:\ProgramData\ClaudeCode path.
Windows user registry HKCU\SOFTWARE\Policies\ClaudeCode Only when nothing above supplies the key.

Managed settings sit above user, project, local, and --settings values. Array keys such as permissions.deny merge, so developers can add rules but not remove yours.

The MCP endpoint

The allowlist entry above permits ACP’s server; it doesn’t add it. Two ways to get it onto seats:

  • Each user adds it with one command and signs in with MCP OAuth in the browser. Attribution comes with the sign-in.

    claude mcp add --transport http acp https://api.agenticcontrolplane.com/mcp
    
  • managed-mcp.json at the same system path as managed-settings.json pushes server definitions to every seat. It makes that list the only servers Claude Code loads and can’t be delivered through server-managed settings, so use it only if you intend to own the whole MCP list:

    {
      "mcpServers": {
        "acp": { "type": "http", "url": "https://api.agenticcontrolplane.com/mcp" }
      }
    }
    

The hook is what enforces policy on every tool call; the MCP server adds read-only introspection tools and one that drafts a rule for a human to confirm.

Each person enrolls once

The pushed settings identify no one. Each developer opens cloud.agenticcontrolplane.com/plugin/authorize, signs in with their work identity, and pastes the one line it shows:

echo 'gsk_…' > ~/.acp/credentials

Until they do, with ACP_REQUIRE_ENROLLMENT set every tool call is denied with that instruction in the message.

If marketplace access is blocked

Air-gapped or egress-restricted fleets that can’t reach GitHub for the plugin can run the hook directly from managed settings instead. Your MDM drops govern.mjs and a wrapper into a managed directory, as on the Codex and Cursor pages, with ACP_CLIENT=claude-code-plugin in the wrapper, and managed settings declare it:

{
  "allowManagedHooksOnly": true,
  "hooks": {
    "PreToolUse":  [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "/etc/acp/claude-hook.sh", "timeout": 5 }] }],
    "PostToolUse": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "/etc/acp/claude-hook.sh", "timeout": 5 }] }]
  }
}

Delivered server-managed, hooks in the settings body prompt a one-time approval dialog in interactive sessions; delivered by file or OS policy they don’t.

What you’ll see

  • /status inside Claude Code names the setting source that won: (remote), (plist) or (HKLM), (file) or (drop-ins).
  • Console rows with client claude-code-plugin, one per person, with subagent chains attributed to their parent session.
  • On an unenrolled seat: [ACP] Not enrolled… and the call doesn’t run.

What’s verified and what isn’t

The plugin, its hooks, and the enrollment gate are what every self-serve install runs today. The managed-settings keys above are taken from Anthropic’s published reference as of September 2026, linked at the top. What we have checked on a machine: Claude Code looks for the system file at the macOS path above on every start and loads the macOS preferences domain only as managed (MDM) preferences. What we have not yet done: pushed this file through a claude.ai enterprise admin console or an MDM profile ourselves. The issue tracking that is gatewaystack-connect #943.

Run agents? ACP lets you see, control, and price every tool call they make — allow/ask/deny policy, per-session cost, and a full audit log for Claude Code, Cursor, Codex, and OpenClaw, in one command:

curl -sf https://agenticcontrolplane.com/install.sh | bash

Getting started →  ·  see your first governed call →  ·  free up to 5 agents  ·  prefer fully on-device? add --local