Claude Code Managed MCP: Control Which Servers Your Team Runs

David IyaDavid Iya November 6, 2026 9 min read

What Claude Code managed MCP controls

Claude Code managed MCP is the set of admin controls that decide which MCP servers Claude Code is allowed to load on your team's machines. Out of the box there is no restriction at all: anyone can add any server, and an MCP server can read data, call APIs and run commands on the user's behalf. Nobody security-audits those servers for you. If you are rolling Claude Code out across a company, this is one of the first policies to set.

The controls cover the servers Claude Code loads itself, including the claude.ai connectors it fetches. One exception matters if your team lives in the desktop app: connectors the desktop app delivers to its local and SSH sessions arrive in-process and are governed from your claude.ai organization settings, not from these files. So you set policy in two places, and you should check both.

Pick a pattern first

There are eight patterns, from shutting MCP off to leaving it wide open. Decide which one you want before you touch a file, because the mechanisms behave differently and mixing them by accident is how servers end up loading that you thought were blocked.

Claude Code managed MCP patterns

PatternWhat it doesConfigure
Disable MCPNo servers load except the few that always load under exclusive controlmanaged-mcp.json with an empty server map
Fixed deploymentEveryone gets the same servers and cannot add othersmanaged-mcp.json with your servers
Provided serversEveryone gets your remote servers and keeps their ownmanagedMcpServers in managed settings
Approved catalogUsers add servers from your approved list, anything else is blockedallowedMcpServers plus allowManagedMcpServersOnly: true
Plugin servers onlyUsers cannot add servers through their own config files, plugin servers still loadstrictPluginOnlyCustomization with mcp in the list
Soft allowlistAn allowlist users can broaden in their own settingsallowedMcpServers without allowManagedMcpServersOnly
Denylist onlyBlock known-bad servers, allow everything elsedeniedMcpServers
No restrictionsUsers add anythingDeploy no managed MCP configuration

My recommendation for most teams: the approved catalog, plus managedMcpServers for the two or three servers everyone needs on day one. A fixed deployment sounds safer, but it also blocks plugin servers and claude.ai connectors by default, and people end up working around it. A soft allowlist is not a control at all, since any user can widen it from their own settings.

There is no built-in server registry users can browse. For the catalog pattern, publish the approved list and its claude mcp add commands somewhere your team already looks, like the internal wiki, or ship the servers as plugins through a managed plugin marketplace so people can install them from /plugin. Plugins explained covers how plugins work.

Exclusive control with managed-mcp.json

When a managed-mcp.json file is present, Claude Code loads only the servers in that file, servers you provide through managedMcpServers, in-process servers the host app registers (such as the VS Code extension's own server and connectors the desktop app delivers), and Claude in Chrome if you allow it. Users cannot add or use anything else, including plugin servers and servers passed with the --mcp-config flag.

Where Claude Code looks for managed-mcp.json

PlatformPath
macOS/Library/Application Support/ClaudeCode/managed-mcp.json
Linux and WSL/etc/claude-code/managed-mcp.json
WindowsC:\Program Files\ClaudeCode\managed-mcp.json

It is a standalone file in the same format as a project .mcp.json, with an mcpServers object. Because it is a file on disk, it cannot be delivered through server-managed settings. You push it with whatever already manages your fleet: Jamf or a configuration profile on macOS, Group Policy or Intune on Windows, your usual tooling on Linux. An empty map, mcpServers set to {}, turns MCP off apart from the servers that always load under exclusive control.

Two switches soften exclusive control. allowAllClaudeAiMcps set to true loads the claude.ai connectors Claude Code would have fetched anyway, and it is only read from admin-controlled sources, so users cannot flip it back on themselves. allowClaudeInChromeWithManagedMcp set to true lets the built-in Claude in Chrome server run, but only from the device's own managed settings, not server-managed settings, and it needs Claude Code v2.1.282 or later. Without it, someone who starts Claude Code with --chrome gets an error at startup. Claude Code in the browser covers what that server does.

Hand everyone servers with managedMcpServers

If you want every person to have, say, your internal docs search and your ticketing server, without taking away their own servers, list them under managedMcpServers in a managed settings source: server-managed settings, a gateway policy, an MDM or registry policy, or managed-settings.json. It needs Claude Code v2.1.259 or later. Older clients ignore the key.

  • Remote only. The type must be http or sse and the url must be https. Plain http is refused, even on localhost.
  • No programs. An entry with command, args, env or headersHelper is dropped, so managed settings never start a program on someone's machine.
  • No ${VAR} references. Values are taken literally.
  • Names use letters, numbers, hyphens and underscores only. A bad entry is dropped with a notice in /status, and the rest still load.

Anyone who can read managed settings on the machine can read a header value you set here, so use a credential issued for everyone or let each user sign in with OAuth. Users cannot remove a provided server, but they can switch one off for themselves in /mcp, where it shows under Managed MCPs. When it arrives through server-managed settings, changes reach running interactive sessions without a restart: add a server and it connects, change it and sessions reconnect, remove it and they disconnect.

Allowlists and denylists that actually hold

allowedMcpServers and deniedMcpServers filter servers that have already been added by a user, a plugin or claude.ai. They are not a way to deploy anything. To make the allowlist authoritative, set it together with allowManagedMcpServersOnly: true in a managed settings source. Without that flag, allowlists from every scope merge, including a user's own settings file. Denylists always merge from every scope, so a user can block a server for themselves but never unblock one.

Three ways to match a server

KeyMatchesUse it for
serverUrlA remote server URL, exact or with * wildcardsHTTP and SSE servers
serverCommandThe exact command and arguments that start a stdio server, in orderLocal stdio servers
serverNameThe label the user typed when adding the server, exact match onlyDenylisting claude.ai connectors by display name, not enforcement
  • Unset is not the same as empty. An unset allowedMcpServers allows every server. An empty array [] allows none, apart from the servers that skip the check.
  • The denylist always wins. A server that matches both lists is blocked.
  • Ports matter. https://mcp.example.com/* only matches port 443. To cover every port write https://mcp.example.com:*/*. The same rule applies to denylist entries, so a deny for a staging host on 443 does not block that host on 8443.
  • serverCommand matches every argument exactly. ["npx", "-y", "server"] does not match the same command with an extra flag. The env block is not compared.
  • Your own servers skip the allowlist: every managedMcpServers entry and managed-mcp.json entries that use no ${VAR} expansion outside env. Built-in servers like Claude in Chrome and the IDE server skip it too.

Roll it out without breaking anyone

The part that bites is silence. When a previously configured server becomes blocked, it just disappears from /mcp and claude mcp list. The user gets no message that policy is the reason, so they assume Claude Code is broken. If that sounds familiar, MCP server not working covers the other causes worth ruling out.

  1. Inventory first. Turn on OpenTelemetry export with OTEL_LOG_TOOL_DETAILS=1 so tool events include MCP server and tool names, and see which servers people actually use before you write the allowlist.
  2. Write the list with serverUrl and serverCommand entries, and set allowManagedMcpServersOnly: true.
  3. Tell people which servers are approved, which are blocked and where the approved list lives, before the policy lands.
  4. Validate on one managed machine. claude mcp list should show only what you expect. If you deployed managed-mcp.json, claude mcp add --transport http test https://example.com/mcp should fail with an enterprise MCP configuration error. The URL does not need to be real.
  5. Then roll out to everyone, and keep the wiki page current as you approve new servers.

When a user hits a block, the error tells them which rule fired: not allowed by enterprise policy for allowlist misses, explicitly blocked by enterprise policy for denylist matches, and a message that exclusive control is active when managed-mcp.json is present. Put those three lines in your rollout note so the help desk recognizes them. For the wider question of what to lock down alongside MCP, see permissions explained.

Free Claude Code drops, straight to your inbox

Short, practical drops on skills, MCP, agents, prompts, and more. No spam, unsubscribe anytime.

Frequently asked questions

How do I restrict which MCP servers Claude Code can use?

Set allowedMcpServers with serverUrl and serverCommand entries, plus allowManagedMcpServersOnly: true, in a managed settings source such as server-managed settings or a deployed managed-settings.json. Add deniedMcpServers for anything you want blocked outright. For a fixed set nobody can change, deploy managed-mcp.json instead.

Where does managed-mcp.json go?

On macOS at /Library/Application Support/ClaudeCode/managed-mcp.json, on Linux and WSL at /etc/claude-code/managed-mcp.json, and on Windows at C:\Program Files\ClaudeCode\managed-mcp.json. It needs administrator rights to write and cannot be delivered through server-managed settings.

How do I disable MCP in Claude Code entirely?

Deploy a managed-mcp.json whose mcpServers object is empty. Leave managedMcpServers, allowAllClaudeAiMcps and allowClaudeInChromeWithManagedMcp unset, because servers from those still load under an empty map.

What is the difference between managed-mcp.json and managedMcpServers?

managed-mcp.json takes exclusive control: only its servers and a few in-process ones load. managedMcpServers adds remote servers for everyone while users keep their own, and it can be delivered through any managed settings source, including server-managed settings.

Why did an MCP server disappear from /mcp?

If your organization added an MCP restriction, a blocked server silently drops out of /mcp and claude mcp list with no message about policy. Check with your admin whether the server is on the approved list.

Last reviewed by David Iya on November 6, 2026

David Iya

Written by

David Iya

Forbes 30 Under 30 · Y Combinator

Keep reading

Claude CodeMemory

Why does Claude Code forget everything between sessions?

Claude Code forgets between sessions because every session starts with a fresh, empty working memory. Two things carry over: a file called CLAUDE.md that you write, and notes Claude saves for itself, called auto memory. Here is how each one works, what gets lost when a long conversation is squeezed down, and what to do so you stop repeating yourself.

Duncan Rogoff 9 min
Read article
Claude CodeSetup

How to Roll Out Claude Code to Your Team (6-Step Plan)

To roll out Claude Code to your team, make five admin decisions first (provider, how settings reach devices, what to enforce, how you will see usage, and data handling), verify the policy with /status, run a small pilot, then launch with one real first task and a channel someone owns. Champions carry it from there. Here is the plan in order, with the launch checklist and the errors you will see on day one.

David Iya 9 min
Read article

Ready to build it yourself?

Join Claude Code Club, the #1 community for learning claude code, for $9/month.

← Back to the blog