MCP: claude.ai connectors NOT suppressed when same-named manual entry exists (inverse of #58375)

Resolved 💬 1 comment Opened May 15, 2026 by cloudingenium-automation[bot] Closed Jun 14, 2026

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.5bc and 2.1.142.ba0 both observed
  • Workspace: /datadrive/vscode/.mcp.json (project-level)
  • User-level: ~/.claude.json (only 4 stdio-banned entries, unrelated)

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗