MCP: claude.ai connectors NOT suppressed when same-named manual entry exists (inverse of #58375)
Summary
Claude Code's startup logic suppresses some — but not all — claude.ai <connector> MCP entries when an exact-name match exists in a manually-configured .mcp.json / ~/.claude.json. The suppression appears non-deterministic: of 11 manually-configured JC-MCP-* servers with same-named claude.ai connectors registered against the same claude.ai account, only ONE (JC-MCP-DashBots) gets correctly suppressed. The other 10 fail their OAuth handshake every session, producing [ERROR] log lines and (for users who haven't authenticated those claude.ai connectors) cluttering the MCP server list with broken entries.
Issue #58375 reports the inverse case (suppression that shouldn't fire). This issue is the opposite: suppression that should fire but doesn't.
Repro
/datadrive/vscode/.mcp.json (workspace-level config):
{
"mcpServers": {
"JC-MCP-DashBots": { "type": "http", "url": "https://mcp.cloudingenium.com/dash-bots/mcp", "oauth": { "clientId": "77cdce60-..." } },
"JC-MCP-Workforce": { "type": "http", "url": "https://mcp.cloudingenium.com/workforce/mcp", "oauth": { "clientId": "249e442e-..." }, "default_config": { "defer_loading": true } },
"JC-MCP-Intel": { "type": "http", "url": "https://mcp.cloudingenium.com/intel/mcp", "oauth": { "clientId": "..." } },
"JC-MCP-HubFiscal": { "type": "http", "url": "https://mcp.cloudingenium.com/hubfiscal/mcp","oauth": { "clientId": "..." } }
// ... ~20 more JC-MCP-* entries
}
}
Same user account also has these registered as claude.ai-side connectors (via web UI → Settings → Connectors): JC-MCP-DashBots, JC-MCP-Workforce, JC-MCP-Intel, JC-MCP-HubFiscal, etc.
Observed (extension v2.1.142, VS Code Insiders host)
[DEBUG] Suppressing claude.ai connector "claude.ai JC-MCP-DashBots": duplicates manually-configured "JC-MCP-DashBots"
[ERROR] MCP server "claude.ai JC-MCP-Workforce" Error: Streamable HTTP error: ... mcp_unauthorized_no_token
[ERROR] MCP server "claude.ai JC-MCP-Intel" Error: Streamable HTTP error: ... mcp_unauthorized_no_token
[ERROR] MCP server "claude.ai JC-MCP-HubFiscal" Error: Streamable HTTP error: ... mcp_unauthorized_no_token
... (8 more, all same shape)
Only DashBots gets the Suppressing debug line. All others fail OAuth instead.
Expected
All claude.ai <X> connectors should be suppressed when X is also the name of a manually-configured MCP server (mcpServers["X"] in any of the resolved config sources). The current behavior is one of:
- Suppression runs but with a stale view of
mcpServers(race against deferred-loading entries), OR - Suppression matches on identity beyond name (e.g. URL/clientId), and DashBots happens to match where others don't, OR
- Suppression iterates only a subset of configured servers.
Hypothesis: race with default_config.defer_loading
Initial hypothesis was default_config.defer_loading: true delayed manual server registration past the suppression check, leaving the claude.ai duplicate live. But data doesn't bear it out cleanly:
| Server | defer_loading | Suppressed? |
|---|---|---|
| JC-MCP-DashBots | false | ✅ yes |
| JC-MCP-Intel | false | ❌ no |
| JC-MCP-HubFiscal | false | ❌ no |
| JC-MCP-Workforce | true | ❌ no |
| JC-MCP-Analitica | true | ❌ no |
So defer_loading is at most a contributor, not the sole cause. Intel and HubFiscal are non-deferred yet still don't get their claude.ai counterparts suppressed.
Impact
- ~10×
[ERROR]lines per session per unsuppressed duplicate. - Connectors panel shows broken entries that users can't easily remove (deleting them on claude.ai web UI is the only fix).
- Users who DO authenticate the claude.ai-side connectors end up running every MCP call through the claude.ai proxy hop, even when their workspace already has direct same-name configuration.
Suggested fix
Make the suppression check name-based and order-independent: walk the union of all manually-configured MCP server names across ~/.claude.json, project .mcp.json, and plugin-provided MCP configs, and suppress every claude.ai <name> where <name> is in that union — regardless of registration timing or default_config state.
Bonus: log the suppression decision for every claude.ai connector, including the non-suppressed ones with a reason (no manual match by name, manual match exists but URL differs, etc.) — currently the silent path makes this kind of bug invisible until users notice their session-startup log noise.
Environment
- Extension:
anthropic.claude-code-2.1.142-linux-x64 - Host: Ubuntu 24.04 / Azure VM / VS Code Insiders SSH
cc_version=2.1.142.5bcand2.1.142.ba0both observed- Workspace:
/datadrive/vscode/.mcp.json(project-level) - User-level:
~/.claude.json(only 4 stdio-banned entries, unrelated)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗