[BUG] 3P mode: custom MCP servers blocked — `allowedMcpServers` hardcoded to empty array despite `managedMcpServers` being defined

Open 💬 0 comments Opened Jun 22, 2026 by Ryosuke-Asano

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Desktop

Environment

  • OS: macOS (Darwin)
  • Claude Desktop: 1.14271.0
  • Claude Code SDK: 2.1.181
  • Deployment mode: 3P (gateway via LiteLLM proxy)
  • Platform: Anthropic API (via custom gateway)

What's Wrong?

When Claude Desktop runs in 3P mode with managedMcpServers defined in the configLibrary, custom MCP servers are completely blocked. The --managed-settings passed to the Claude Code process always contains:

{"allowedMcpServers": [], "allowManagedMcpServersOnly": true}

This means:

  • allowManagedMcpServersOnly: true → only servers in allowedMcpServers are permitted
  • allowedMcpServers: [] → empty allowlist → no custom MCP server can be used

Root Cause

In app.asar.vite/build/index.js, the function that constructs managed settings for 3P mode contains:

e.type === "3p" && A.managedMcpServers?.length && {
  allowedMcpServers: [],                          // ← hardcoded empty
  allowManagedMcpServersOnly: true
}

The configLibrary (configLibrary/*.json) correctly defines managed MCP servers:

{
  "managedMcpServers": [
    {"name": "sequential-thinking", "source": "user", "transport": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]},
    {"name": "Playwright", "source": "user", "transport": "stdio", "command": "npx", "args": ["@playwright/mcp@latest"]},
    {"name": "context7", "source": "user", "transport": "stdio", "command": "npx", "args": ["-y", "@upstash/context7-mcp@latest"]},
    {"name": "global-memory", "source": "user", "transport": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-memory"]},
    {"name": "ddg-search", "source": "user", "transport": "stdio", "command": "uvx", "args": ["duckduckgo-mcp-server"]}
  ]
}

But allowedMcpServers is set to [] instead of deriving the server names from managedMcpServers. The servers are defined but never allowed.

What Should Happen?

allowedMcpServers should be populated with the names from managedMcpServers:

// Suggested fix
e.type === "3p" && A.managedMcpServers?.length && {
  allowedMcpServers: A.managedMcpServers.map(s => s.name),
  allowManagedMcpServersOnly: true
}

Impact

All users running Claude Desktop in 3P mode with custom MCP servers configured via managedMcpServers are affected. No custom MCP server (stdio, HTTP, or SSE) can be used in 3P mode, regardless of configuration.

Evidence

The Claude Code process is spawned with:

--mcp-config {"mcpServers":{"playwright":{...},"ddg-search":{...}}}
--managed-settings {"allowedMcpServers":[],"allowManagedMcpServersOnly":true}

The --mcp-config defines servers, but --managed-settings blocks all of them. The process spawns zero child processes (confirmed via ps), meaning MCP servers are rejected before initialization.

Workarounds Attempted

| Approach | Result |
|---|---|
| Add allowedMcpServers to configLibrary JSON | Overridden by 3P code path |
| Add allowManagedMcpServersOnly: false to configLibrary | Overridden by 3P code path |
| Add MCP servers to ~/.claude/settings.json | mcpServers field not supported in settings schema |
| Add .mcp.json to project directory | Blocked by allowManagedMcpServersOnly: true |
| Patch app.asar binary | Crashes (code signature verification) |
| Wrap Claude Code binary with shell script | Auto-repaired on restart (integrity check) |

No user-side workaround exists.

View original on GitHub ↗