MCP collision check suppresses claude.ai connectors that point to a different workspace than the same-named plugin — no scriptable workaround

Open 💬 0 comments Opened Jun 29, 2026 by kwiegand-intuit

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 a built-in plugin MCP (e.g. plugin:slack:slack, plugin:atlassian:atlassian) and the corresponding claude.ai connector (e.g. claude.ai Slack, claude.ai Atlassian) are intentionally pointed at different upstream workspaces, the /mcp UI suppresses the claude.ai connector as a false duplicate:

claude.ai Slack · ◌ hidden — same URL as your server 'plugin:slack:slack' To use this connector instead, disable the plugin server in /plugins

The two connectors are not duplicates: they authenticate to different workspaces, hold different OAuth tokens, and expose different data. The collision detector matches on a normalized URL signature that strips the very identity (workspace / OAuth) that distinguishes them.

Impact: anyone running a plugin MCP and the same-named claude.ai connector at different workspaces (e.g. a corporate workspace and a team workspace) loses the claude.ai connector on every cold start, with no scriptable workaround. The failure is silent — the connector is suppressed rather than erroring — so a user may not notice their second workspace's data is simply missing.

This re-files #58375, which the stale bot auto-closed on 2026-06-12 (not_planned, "inactive for too long") with no maintainer response. It still reproduces on 2.1.195 (capture below); the deminified root-cause analysis was done against 2.1.139.

Root cause. The URL-normalization function collapses gateway-routed URLs to just the ?mcp_url=... param; the signature builder keys collision on that string. Both the plugin-side and the claude.ai-side connector for the same product carry the same mcp_url, so the workspace/OAuth identity that distinguishes them is not in the key. (Minified names rotate per release; grep the stable log string Suppressing claude.ai connector "X": duplicates manually-configured "Y". Functions below are from 2.1.139.)

VG7 = ["/v2/session_ingress/shttp/mcp/", "/v2/session_ingress/mcp/ws/", "/v2/ccr-sessions/"];
function vG7(H) {
  if (!VG7.some((_) => H.includes(_))) return H;
  try { return new URL(H).searchParams.get("mcp_url") || H; } catch { return H; }
}
function $wH(H) {            // collision-key builder
  let _ = E16(H); if (_) return `stdio:${hH(_)}`;
  let q = S16(H); if (q) return `url:${vG7(q)}`;   // <-- identity not in this string
  return null;
}

Why there is no scriptable workaround. The /mcp Disable button writes to ~/.claude.jsonprojects[<cwd>].disabledMcpServers[], so a script editing that array seems equivalent — but from observed behavior the button also disconnects/loads the plugin in-memory in the running session, and we could not find an exposed path to that in-memory half. A file edit alone produces a split-brain session that needs another restart, which puts the file back into the suppressing state. So the only fix is a manual disable→restart→re-enable dance on every cold start.

What Should Happen?

The collision check should treat a plugin MCP and a claude.ai connector that point at different workspaces / OAuth identities as distinct, and leave both connected after a cold start — no manual dance required.

Concretely, one of:

  1. (Preferred) Include the per-connector stable id in the collision signature built by $wH, so connectors differing only by workspace/identity stop colliding.
  2. Skip URL-based collision detection for the managed claude.ai-side connectors (discriminate on whatever field reliably separates the two sides), since the user explicitly opted into them.
  3. Match only when the OAuth account / workspace identifiers are also equal.

Secondary ask if the above are out of scope: expose claude mcp reload <plugin> (or any IPC) that performs the in-memory disconnect/load the UI buttons do, so the workaround is at least scriptable instead of a five-step manual dance per cold start.

Error Messages/Logs

Captured on Claude Code 2.1.195 (2026-06-29), bottom of the `/mcp` "Manage MCP servers" list (47 servers; the list scrolls — this is the lower portion):


claude.ai Slack · ◌ hidden — same URL as your server 'plugin:slack:slack'
    To use this connector instead, disable the plugin server in /plugins

Built-in MCPs (always available)
plugin:atlassian:atlassian · ✔ connected · 40 tools
plugin:slack:slack · ✔ connected · 18 tools


The `claude.ai Slack` suppression is the line directly above the "Built-in MCPs" section (where both plugins show connected). The `claude.ai Atlassian` connector is above the visible portion of this list; it exhibits the identical suppression, but only the Slack line is shown here to keep this a faithful, un-stitched excerpt.

Suppression log line to grep: `Suppressing claude.ai connector "X": duplicates manually-configured "Y"`

Steps to Reproduce

  1. Install the built-in Slack (and/or Atlassian) plugin and OAuth it to Workspace A.
  2. Separately enable the corresponding claude.ai connector (via claude.ai connector settings) and OAuth it to a different Workspace B — a distinct workspace with a distinct OAuth identity.
  3. Cold-start Claude Code (fully quit and relaunch) and open /mcp.

Result: the claude.ai connector shows as hidden — same URL as your server 'plugin:...'; its tools never register in the session. The plugin connectors work.

Manual workaround (must repeat every cold start): /mcp → Disable both plugins → quit and restart → re-enable both plugins. After that, all four connectors function simultaneously, until the next cold restart.

Related but different: #39511 (closed not_planned) covered a cosmetic warning on disconnected claude.ai connectors where the plugins still worked. This issue is about valid, simultaneously-active dual-workspace connectors made unusable.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.195

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗