Independent AI intelligence Two editions daily · ET
Fervor AI

Analysis · September 3, 2026 · concept

Claude Code 2.1.259allowedMcpServersmanagedMcpServersModel Context Protocolmcpmcp-securityclaude-codeagent-securityagent-infrastructure

Claude Code 2.1.259 Changed What Your MCP Allowlist Covers, and the Docs Still Say Otherwise

An MCP allowlist that used to filter every server now filters only the ones users add. Here is what loads after your fleet upgrades, and the one setting that still stops it.

Buried at position 33 in a 37-bullet changelog, one line reverses what an MCP allowlist is for:

Changed allowedMcpServers to govern only servers users add: a literal managed-mcp.json server your allowlist used to filter out now loads on upgrade; use deniedMcpServers to keep it off

Now read what Anthropic's own managed-MCP documentation page says, as of this morning, still published, still the first thing an admin finds when they search:

allowedMcpServers and deniedMcpServers apply to managed servers too, so a managed server that doesn't pass them won't load.

Those two sentences cannot both be true. One of them shipped to npm on September 2 at 21:21 UTC. The other is what your security review read when it signed off on the control.

Why a single changelog bullet is worth your afternoon

Most release notes describe things you have to go do. This one describes something that happens to you.

An allowlist is the control admins actually reason about, because it is the only one shaped like a decision. Denylists require you to imagine every bad thing in advance. Allowlists let you say "these four servers, nothing else," and go home. That mental model is why the change matters more than its position in the changelog suggests: it does not ask you to reconfigure anything. It redefines what your existing configuration means, at the moment your fleet updates.

Here is the specific failure. You wrote an allowlist. A server defined literally in managed-mcp.json did not match it, so it did not load. You read that as intentional, maybe even as the allowlist doing its job on a server some other team pushed. After 2.1.259, that server loads. Your file did not change. Your policy did not change. The meaning of your file changed.

The exposure is staggered in a way that makes it harder to notice. npm's latest tag points at 2.1.259; stable still points at 2.1.236, published August 19. That is 23 releases and two weeks of distance. If your organization pins to stable, nothing has happened yet. If half your engineers run latest because that is what npm install -g gives them, half your fleet has a different allowlist semantic than the other half, and no dashboard shows you which half.

What the allowlist was doing, and what it does now

The pre-2.1.259 evaluation order is documented plainly, and it is worth having in your head before you change anything.

Before loading a server, per the docs, Claude Code runs three checks in order. The denylist comes first, and it is absolute: "A server that matches any denylist entry, by URL, command, or name, is blocked. Nothing overrides a denylist match." Then the allowlist. If allowedMcpServers is not set anywhere, everything that survived the denylist loads. If it is set, the server has to match.

The docs are also honest about a weakness that predates this release, and it is the one most admins get wrong:

Without allowManagedMcpServersOnly, allowlists from every settings scope merge, including a user's own ~/.claude/settings.json, so a user can broaden what your allowlist permits. Denylists merge from every scope regardless.

Read that twice. A user adding an entry to their personal settings file widens the org allowlist. The allowlist was never the hard boundary people treated it as. 2.1.259 does not create that problem, it removes one more class of server from the allowlist's reach entirely.

There is a defensible design argument underneath the change, and I want to give it its due. managed-mcp.json is an administrator artifact. It lives at a system path that regular users cannot write: /Library/Application Support/ClaudeCode/managed-mcp.json on macOS, /etc/claude-code/managed-mcp.json on Linux, C:\Program Files\ClaudeCode\managed-mcp.json on Windows. If an admin deliberately pushed a server there, having a second admin-authored list silently cancel it is confusing. The docs already gesture at this framing: "Allowlists and denylists filter which configured servers are allowed to load. They aren't a registry."

Fine. But "admin-authored" is not one thing in an organization with more than one admin, and the fix ships as a default flip on a patch release rather than as a migration you opt into.

The other half of the release nobody documented

The same release adds managedMcpServers, described as:

organizations can provide HTTP/SSE MCP servers to every user (same entry shape as .mcp.json); entries that name a command to run are skipped

This is a genuinely new delivery channel, not a rename. The existing managed-mcp.json is a standalone file at a system path, and the docs state it "cannot be delivered through server-managed settings." managedMcpServers is a managed setting, which means it rides whatever channel your other managed settings ride. Stdio servers are excluded by design, which is the right call: pushing a command to execute on every developer machine is a different risk class than pushing a URL.

Neither managedMcpServers nor its sibling flag --permission-prompts none appears anywhere in the published Claude Code docs. I checked the full settings reference, the CLI flag table, the MCP page, the IAM page, the permission-modes page, the headless page, the managed-settings page and the admin-setup page. Zero hits for either string. The flag table lists --permission-mode and --permission-prompt-tool, not --permission-prompts.

That flag is worth knowing about on its own if you run agents on schedules. It denies anything that would prompt, while "the active permission mode (including auto mode) keeps deciding" everything else. What it changes is not risk, it is failure shape: a job that used to hang waiting for a human now fails partway through with no operator standing there. Silent hangs are terrible. Silent partial completions are worse, because they look like success in the exit code.

Put this into practice

The whole check takes about fifteen minutes. Do it before your fleet upgrades, not after.

  1. Find out what you are running. claude --version on a few real machines, not just yours. Then npm view @anthropic-ai/claude-code dist-tags to see where latest and stable currently point. If stable is still 2.1.236, you have a window.

  2. Enumerate every managed server. Look at managed-mcp.json on each platform path above, and at any managedMcpServers block in your managed settings. Write the list down. This is the list that no longer passes through your allowlist.

  3. For each one, ask a single question: was the allowlist the only thing keeping this off? If the answer is yes for any server, that server loads after the upgrade. This is the entire finding.

  4. Move those into deniedMcpServers. Not into a narrower allowlist. The denylist is the only gate the docs describe as unconditional, and the changelog names it as the remediation. Denylists also merge from every scope regardless of allowManagedMcpServersOnly, so a user cannot widen around them.

  5. Set allowManagedMcpServersOnly if you have not. Without it, user settings merge into your allowlist and broaden it. This was true before 2.1.259 and is still true.

  6. Test --permission-prompts none on one scheduled host before you put it everywhere. Run a job you know needs a prompt and watch what the failure looks like in your logs. If you cannot tell a denied prompt from a clean run at a glance, add that signal before you rely on the flag.

  7. Check /status after upgrading. The same release makes Claude Code refuse to start when a managed-settings file, a drop-in, the MDM plist or the HKLM value cannot be parsed, and it names the source. That is a good fix, and it means a malformed policy file now fails loudly instead of going unenforced. Be ready for a machine that suddenly will not launch.

Honest limitations

My entire primary evidence for the scoping change is one changelog bullet. I read the full changelog raw from raw.githubusercontent.com with a cache-buster, confirmed the publish timestamp against the npm registry packument, and grepped ten documentation pages. I did not reproduce the behavior on a live MDM-managed fleet, because I do not have one. If you do, and the server still gets filtered, I want to hear about it before anyone repeats this.

The docs contradiction is most likely lag. Anthropic ships fast enough that a page written against 2.1.257 behavior can be a day behind by the time you read it. I am not claiming the documentation is wrong on purpose, and I am not claiming the changelog overstates the change. I am saying that on September 3, 2026, an administrator who reads the docs and an administrator who reads the changelog reach opposite conclusions about the same setting, and only one of them matches the code.

Two things I could not confirm at all. Whether the skipping of command-bearing managedMcpServers entries is silent, warned, or surfaced in /mcp, because the changelog says only that they "are skipped." And which settings scopes managedMcpServers can arrive through, or how it interacts with an existing managed-mcp.json file, because no documentation covers it yet. Do not build a policy on either assumption.

There is also a real chance this change affects almost nobody. It only bites where an allowlist and a managed server disagreed, which requires two admin-authored configurations pointing different directions. Plenty of organizations have one admin and no managed-mcp.json at all. If that is you, the fifteen minutes will end with you confirming there was nothing to find, and that is a good outcome.

The part worth arguing about

The narrower question here has a clean answer: go set deniedMcpServers.

The wider one does not. Agent control planes are being built right now, in public, at patch-release speed, and their semantics are still moving. In the last two weeks the same product changed how symlinks interact with read deny rules, made defaultMode: "bypassPermissions" in project settings get ignored outright, required approval for managed settings that weaken sandbox isolation, and now changed what an allowlist covers. Every one of those is a defensible improvement. Collectively they mean that the security posture you reviewed in August is not the posture you are running in September, and the artifact that tells you so is a changelog bullet rather than a migration notice.

The tooling we use to reason about agent permissions assumes configuration is stable and behavior is derived from it. The reality is the reverse. So the question I keep landing on is whether an organization can even answer, on demand, which MCP servers its agents can reach today, and whether that answer survives the next npm install -g.

If you have a way of testing that continuously rather than reading release notes at 7am, tell me what it looks like. I have not found a good one.


Sources: Claude Code CHANGELOG, npm registry packument for @anthropic-ai/claude-code, Anthropic managed MCP documentation, Anthropic managed settings documentation. All figures verified 2026-09-03.