[BUG] Enterprise managed-mcp.json silently blocks all claude.ai cloud MCP connectors

Status Fixed / completed
Reported on v2.1.81
Maintainer reply ✓ Yes — localden
Activity 9 comments · opened Mar 29, 2026 · closed May 30, 2026
💡 Likely answer: A maintainer (localden, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When /etc/claude-code/managed-mcp.json exists (enterprise MCP configuration), all claude.ai cloud MCP connectors are silently blocked. The cloud MCP fetch function is never called because the enterprise guard short-circuits both code paths:

  • Interactive mode (React hook): if (K || H46()) V = Promise.resolve({}) – skips cloud fetch entirely
  • Print mode: R6 && !A6 && !H46() && !Y9() – guard evaluates false, skips cloud fetch

No error, no warning, no log output. The servers simply don't appear. claude mcp list only shows the enterprise-defined servers. Debug logs contain zero [claudeai-mcp] lines – the fetch function is never reached.

The API endpoint works perfectly – curl to /v1/mcp_servers returns all 5 configured cloud connectors. OAuth token has correct user:mcp_servers scope. Feature gate is true. The claudeai-proxy transport type also works perfectly when servers are manually injected into managed-mcp.json. The only problem is the client never fetches them.

What Should Happen?

Enterprise managed MCP should coexist with claude.ai cloud connectors. The enterprise config controls which local MCP servers are available – it should not silently disable cloud connectors configured at claude.ai/settings/connectors. At minimum, if intentional, there should be a clear log message explaining why cloud connectors are not loading.

Error Messages/Logs

# Sessions BEFORE enterprise config (working, Feb–Mar 7):
[claudeai-mcp] Checking gate (cached)...
[claudeai-mcp] Gate returned: true
[claudeai-mcp] Fetching from https://api.anthropic.com/v1/mcp_servers?limit=1000
[claudeai-mcp] Fetched 5 servers

# Sessions AFTER enterprise config (broken, Mar 27+):
# No [claudeai-mcp] log lines at all. Function never reached.

Steps to Reproduce

  1. Deploy /etc/claude-code/managed-mcp.json with any valid enterprise MCP config (e.g. a few stdio/http servers)
  2. Configure cloud MCP connectors at claude.ai/settings/connectors
  3. Start Claude Code
  4. Run claude mcp list – cloud connectors are missing
  5. Check debug logs – no [claudeai-mcp] output at all
  6. Manually inject claudeai-proxy entries into managed-mcp.jsonclaude mcp list now shows them and they connect successfully
  7. Remove injected entries – cloud connectors disappear again

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.81

Claude Code Version

2.1.87

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

Suggested fix: In gO6() and the React useEffect hook, the enterprise guard should not skip the cloud MCP fetch:

// Current (broken) – enterprise mode skips cloud fetch:
if (H46()) { return only enterprise servers }

// Fixed – enterprise mode should include cloud servers:
if (H46()) { return enterprise servers + cloud servers from pO6() }

Workaround: A SessionStart hook that fetches cloud servers from the API and merges them into managed-mcp.json:

#!/bin/bash
set -euo pipefail
CREDS_JSON="$HOME/.claude/.credentials.json"
MANAGED_MCP="/etc/claude-code/managed-mcp.json"
[ ! -f "$CREDS_JSON" ] || [ ! -f "$MANAGED_MCP" ] && exit 0
ACCESS_TOKEN=$(jq -r '.claudeAiOauth.accessToken // empty' "$CREDS_JSON" 2>/dev/null)
[ -z "$ACCESS_TOKEN" ] && exit 0
CLOUD_SERVERS=$(curl -s --max-time 5 \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "anthropic-beta: mcp-servers-2025-12-04" \
    -H "anthropic-version: 2023-06-01" \
    "https://api.anthropic.com/v1/mcp_servers?limit=1000" 2>/dev/null) || true
[ -z "$CLOUD_SERVERS" ] && exit 0
echo "$CLOUD_SERVERS" | jq -e '.data' &>/dev/null || exit 0
tmp=$(mktemp)
jq --argjson cloud "$CLOUD_SERVERS" '
    ($cloud.data // []) as $servers |
    reduce $servers[] as $srv (.;
        .mcpServers["claude.ai \($srv.display_name)"] = {
            type: "claudeai-proxy", url: $srv.url, id: $srv.id
        }
    )
' "$MANAGED_MCP" > "$tmp" && mv "$tmp" "$MANAGED_MCP"
exit 0

Related issues: #21874, #32955, #24825

View original on GitHub ↗

9 Comments

github-actions[bot] · 5 months ago

Found 1 possible duplicate issue:

  1. https://github.com/anthropics/claude-code/issues/32882

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

toby00001 · 5 months ago
Found 1 possible duplicate issue: 1. Plugin-bundled MCP servers (.mcp.json) silently ignored when allowedMcpServers is configured in managed-settings.json #32882 This issue will be automatically closed as a duplicate in 3 days. If your issue is a duplicate, please close it and 👍 the existing issue instead To prevent auto-closure, add a comment or 👎 this comment 🤖 Generated with Claude Code

Not a duplicate. Similar issue, but impossible to know if root cause is identical without seeing source code. Also a fix for that issue will not guarantee a fix for this issue, and certainly any fix for that issue would not test to reproduce the issue I have reported.

yurukusa · 5 months ago

A Notification start hook can merge cloud MCP servers into the enterprise config:

MANAGED="/etc/claude-code/managed-mcp.json"
[ -f "$MANAGED" ] || exit 0
CLOUD_MCPS=$(jq -r '.mcpServers // {} | keys[]' ~/.claude/settings.json 2>/dev/null)
MANAGED_MCPS=$(jq -r '.mcpServers // {} | keys[]' "$MANAGED" 2>/dev/null)
MISSING=""
for mcp in $CLOUD_MCPS; do
    if ! echo "$MANAGED_MCPS" | grep -qF "$mcp"; then
        MISSING+="$mcp "
    fi
done
if [ -n "$MISSING" ]; then
    echo "⚠️ Cloud MCP servers not in managed config: $MISSING" >&2
    echo "  These connectors may not load due to enterprise guard" >&2
fi
exit 0

If you have write access to managed-mcp.json, a more aggressive approach:

MANAGED="/etc/claude-code/managed-mcp.json"
USER_SETTINGS="$HOME/.claude/settings.json"
[ -f "$MANAGED" ] && [ -f "$USER_SETTINGS" ] || exit 0
LOCAL_MANAGED="$HOME/.claude/managed-mcp-merged.json"
jq -s '.[0].mcpServers = (.[0].mcpServers + .[1].mcpServers) | .[0]' "$MANAGED" "$USER_SETTINGS" > "$LOCAL_MANAGED" 2>/dev/null
echo "Merged $(jq '.mcpServers | length' "$LOCAL_MANAGED") MCP servers" >&2
exit 0
toby00001 · 5 months ago
A Notification start hook can merge cloud MCP servers into the enterprise config: MANAGED="/etc/claude-code/managed-mcp.json" [ -f "$MANAGED" ] || exit 0 CLOUD_MCPS=$(jq -r '.mcpServers // {} | keys[]' ~/.claude/settings.json 2>/dev/null) MANAGED_MCPS=$(jq -r '.mcpServers // {} | keys[]' "$MANAGED" 2>/dev/null) MISSING="" for mcp in $CLOUD_MCPS; do if ! echo "$MANAGED_MCPS" | grep -qF "$mcp"; then MISSING+="$mcp " fi done if [ -n "$MISSING" ]; then echo "⚠️ Cloud MCP servers not in managed config: $MISSING" >&2 echo " These connectors may not load due to enterprise guard" >&2 fi exit 0 If you have write access to managed-mcp.json, a more aggressive approach: MANAGED="/etc/claude-code/managed-mcp.json" USER_SETTINGS="$HOME/.claude/settings.json" [ -f "$MANAGED" ] && [ -f "$USER_SETTINGS" ] || exit 0 LOCAL_MANAGED="$HOME/.claude/managed-mcp-merged.json" jq -s '.[0].mcpServers = (.[0].mcpServers + .[1].mcpServers) | .[0]' "$MANAGED" "$USER_SETTINGS" > "$LOCAL_MANAGED" 2>/dev/null echo "Merged $(jq '.mcpServers | length' "$LOCAL_MANAGED") MCP servers" >&2 exit 0

Hey, did you check my documented workaround?

yurukusa · 5 months ago

@toby00001 Apologies — I missed the workaround you documented in the issue body. Your API-fetch approach (pulling from /v1/mcp_servers with OAuth credentials and injecting as claudeai-proxy transport) is the correct solution here. My settings.json-based suggestion wouldn't cover cloud MCP connectors configured via claude.ai/settings.
Your SessionStart hook handles the real problem: the enterprise guard skips pO6() entirely, so the only way to get cloud servers into managed-mcp.json is to fetch them yourself from the API. Well done on working that out.

JBrown0x90 · 4 months ago

Enterprise account — fleet impact, no viable workaround

Adding this from an enterprise admin perspective. We are a paying Anthropic enterprise customer with hundreds of Claude Code users across our organization. The managed-mcp.json on our machines is not deployed via MDM — it is pushed directly by the Anthropic enterprise platform itself as part of the managed deployment we pay for.

This worked correctly until updating to 2.1.118 today. After the update, all cloud MCP connectors (Atlassian, GitHub, Slack, etc.) configured in the Anthropic enterprise console stopped loading for my users. The connectors are still configured correctly on the platform side — managed-settings.json correctly reflects allowedMcpServers — but managed-mcp.json is present with an empty mcpServers: {} object and the cloud fetch is never reached.

The workaround described in this issue (a SessionStart hook that merges servers into managed-mcp.json) is not a viable solution at fleet scale:

  • managed-mcp.json is root-owned — users cannot write to it
  • Pushing a per-machine hook to hundreds of users is not acceptable for a feature that was working out of the box and is a core part of the enterprise offering we purchased
  • This needs to be fixed in the client, not papered over with a user-side script

Requesting this be escalated and prioritized given enterprise account impact. A client update that breaks managed MCP for paying enterprise customers without a scalable fix is a regression that needs urgent attention.

Environment:

  • Claude Code 2.1.118, macOS 26.2 arm64
  • Last working version: prior to 2.1.118
  • managed-mcp.json pushed by Anthropic enterprise platform (not MDM)
  • mcpServers: {} — empty, cloud connectors never fetched
JBrown0x90 · 4 months ago

Can someone acknowledge this please? Is this someone to bring up through our account rep instead?

localden collaborator · 3 months ago

Thanks for the report. This is fixed in v2.1.149 via the allowAllClaudeAiMcps setting in managed-settings.json. When set to true by the admin, claude.ai cloud connectors are no longer blocked by the managed-MCP allowlist. See the managed settings docs for details.

github-actions[bot] · 1 month ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.