[BUG] 3P mode: custom MCP servers blocked — `allowedMcpServers` hardcoded to empty array despite `managedMcpServers` being defined
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 inallowedMcpServersare permittedallowedMcpServers: []→ 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.