Enforce the endpoint through client policy
Governing tools takes two layers, and only one of them is yours. Workforce decides what an employee can do once connected: their Groups resolve to a Tool Pack, calls run under their own credentials, and anything outside that surface fails into Requests. Whether their client connects to you at all, and what else it connects to, is decided in the client.
Most AI clients now ship an enterprise policy layer for exactly that: a root-owned file or an admin console fixing which MCP servers load, which employees cannot override. Point it at https://ah-api.merge.dev/mcp and your tool surface arrives on first launch with no setup step, and on the strongest clients nothing arrives beside it. Use this when you want your approved surface to be the only surface, or when you are not deploying the Workforce desktop client.
This page covers tools. Model traffic rolls out separately, in Choose a rollout path.
What arrives when the endpoint lands
Two people who receive a byte-identical config file get different tools, because the endpoint answers according to their Groups rather than according to the file. That is what makes a fixed deployment safe to push: everyone gets the same door, not the same access.
Skills ride the same connection. The client reaches list_skills and retrieve_skill alongside search_tools and request_tool_access once Merge has enabled skill retrieval for your organization, so one push delivers your skills too, with nothing copied to the machine and nothing to sync.
Each employee still signs in once. The endpoint arrives needing authentication, they complete SSO, and they see a consent screen listing what their Group grants. No client here supports pre-seeding a token, which is the right outcome: a shared token would hand everyone one person’s access instead of their own.
How much each client will enforce
Two capabilities matter and get conflated. Delivering the endpoint to everyone is one. Stopping an employee adding an ungoverned server beside it is the other, and it decides whether your Tool Pack is the tool surface or just part of it.
Start with Claude Code and Codex. They cover most employee coding work, and each does both jobs in one mechanism.
Every device-side mechanism below is a file or a managed preference, so your MDM places it and nothing more. Unlike scripting AI client configuration from your MDM, the client reads its own policy continuously and refuses what the policy excludes, so there is no drift window to size.
Clients that deploy a fixed set
Claude Code
Deploy a managed-mcp.json and Claude Code loads the servers in that file and nothing else. Employees cannot add, modify, or use another server, including one from a project .mcp.json, one supplied by a plugin, or one passed with --mcp-config.
Deploy it to the fixed path for each platform
The file has to be root-owned. It is a standalone file rather than a setting, so it cannot travel through server-managed settings.
Confirm it took effect
On a test device, claude mcp list returns the Workforce endpoint alone, and adding anything else is refused:
The URL does not have to be real, because the policy check rejects the command before contacting anything. If the employee’s own servers still appear, the file is not being read: check the path and the ownership.
Two softer variants, if a fixed set is more than you want. To let employees keep the servers they add and receive yours in addition, list the endpoint under managedMcpServers in a managed settings source instead of deploying the file, which needs Claude Code v2.1.259 or later. To run an approved catalog instead, set allowedMcpServers together with allowManagedMcpServersOnly: true. Without that second key, allowlists merge across every settings scope including the employee’s own ~/.claude/settings.json, so they can widen what you permitted.
managed-mcp.json also hides the claude.ai connectors Claude Code fetches for itself, including any you configured for the organization. If you added Workforce as an organization connector as well, set "allowAllClaudeAiMcps": true in a managed settings source so both load. Claude Code honors that key only from admin-controlled tiers, so an employee cannot re-enable suppressed connectors for themselves.
Codex
Codex splits its policy layer in two, and the split is the whole point: managed_config.toml sets defaults an employee can change at runtime, and requirements.toml sets constraints they cannot. Use both.
Install the endpoint as a default:
Then pin it as the only permitted server:
Identity matches on URL rather than on the name you gave the server, which is what makes the allowlist worth having: a server renamed to resemble yours does not pass. An mcp_servers table that is present but empty disables MCP altogether.
Both files live at /etc/codex/ on macOS and Linux, and at ~/.codex/ on Windows. On macOS you can deliver them as a managed preference on the com.openai.codex domain instead, with each file base64-encoded into config_toml_base64 and requirements_toml_base64. On a ChatGPT enterprise workspace you can attach the same policy in the cloud, which reaches anyone signing in to that workspace without touching their machine.
Gemini CLI
A root-owned system settings.json supplies mcpServers that employees cannot override, and mcp.allowed restricts what else may load.
Clients that can only block
These three cannot install the endpoint for an employee, so pair each one with the steps in Connect employee AI clients and use the policy layer to make sure nothing ungoverned sits beside it.
Cursor. The Enterprise dashboard allowlists MCP servers by URL pattern, so permitting the Workforce endpoint blocks the rest. Allowlisting alone tends to disappoint, because Agent still prefers the integrations it already has over a tool surface it has to discover. Add a team rule pointing it at the Workforce tools for the systems in your Tool Pack. The local permissions.json is subordinate to the dashboard, and Cursor documents it as not a security boundary.
Windsurf. The Admin Portal allowlists server IDs by regex, where one entry for the Workforce endpoint excludes every other server.
VS Code with Copilot. Provision the endpoint with a user or workspace mcp.json, then enforce with the ChatMCP=registry device policy plus GitHub’s registry-only organization policy. GitHub documents that name matching here is bypassable by editing config, so treat this as provisioning with a filter rather than exclusive control. ChatMCP=none is the hard stop.
Clients with no MCP policy layer
Claude apps (web and desktop). An Owner adds Workforce once as an organization custom connector under Organization settings → Connectors, and each employee connects it themselves. Claude’s custom connectors authorize per person by design, so this makes your tool surface available to everyone and mandatory for nobody.
This is usually the largest non-technical population in a company, and it is the gap in this path. Govern it on the Workforce side instead: keep the Tool Pack assigned to their Group tight, and read Tool calls to see who connected rather than assuming a config push reached them.
If you already distribute internal Claude Code plugins through Organization settings → Plugins, you can carry the endpoint in one as a .mcp.json at the plugin root and force-enable it with enabledPlugins in managed settings. Mind the precedence: managed-mcp.json suppresses plugin-provided servers, so the two are alternatives rather than layers.
Verify that tools are actually reaching people
A config that deployed and a tool surface that got used are different things, and your MDM cannot tell them apart. Check both:
- Tool calls. Every call an employee’s client made, with the employee, the Tool Pack it came through, and whether it succeeded. This is the evidence that the endpoint is connected and working, and it needs nothing on the device.
- Employees with no calls at all. A client that received your config but never signed in looks exactly like a machine you never reached. Compare the employees appearing in the logs against your SCIM-synced list and chase the difference.
Requests is the third signal and the most useful. A queue filling with the same tool from several people in one Group means the rollout worked and the Group is too narrow.
Run all three against a canary group of five to ten machines before widening. A config that landed on the fleet and produced calls from six people has landed and is being ignored.
Limits worth stating up front
Tell your security team these before they find them:
- The client layer is client-side. An employee with local admin can edit a file, run an older binary, or set an environment variable that dodges policy. Anthropic’s own documentation calls server-managed settings a client-side control rather than a security boundary. You get compliance by default, and drift that is visible and reversible.
- An employee’s own denylist still applies to your server. In Claude Code,
deniedMcpServersmerges from their settings, so someone can block a managed server for themselves. They cannot put a different one in its place. - Version floors fail quietly.
managedMcpServersneeds Claude Code v2.1.259 or later, and Codex managed configuration needs a recent build. Older installs ignore policy rather than erroring, so confirm versions on the canary group. - Cloud sessions are weaker everywhere. A
managed-mcp.jsonon a workstation does not reach a cloud session, and Copilot’s cloud coding agent ignores registry policy. Those need the vendor’s own cloud policy tier. - Network egress rules cannot see a local server. Egress filtering catches direct-to-server MCP traffic but never a server running on the machine, so client policy is the only layer covering those.
- The layer that cannot be bypassed from the device is the Workforce one. An unmanaged config cannot mint a Workforce session, resolve a Group, or reach a Connector’s credentials. An employee who evades every file on this page still does not reach your systems with your data, which is the difference between losing enforcement and losing control.