MCP tools not exposed when two servers share identical self-reported name+version
Description
When two MCP servers configured in project-level .mcp.json are backed by the same underlying package/binary, they report an identical serverVersion.name + version in their initialize response. In this situation, neither server's tools become available to the harness or ToolSearch — even though the harness's own spawn log shows a fully successful handshake for both instances (hasTools:true).
This happens regardless of the .mcp.json config key name. Renaming the config keys to be completely unique (no shared substrings) does not fix it, which rules out a config-key string collision and points specifically at the self-declared serverVersion (name+version) as the internal dedup/registration key.
Reproduction
Observed independently in 3 separate pairs within the same project/session, all sharing this exact signature:
google-ads+google-ads-manaka— both backed by@channel47/google-ads-mcp@latest, both self-report{"name":"google-ads-mcp","version":"1.1.1"}meta-ads+meta-ads-interpark— both backed by the same localmeta-ads-mcpbinary, both self-report{"name":"meta-ads","version":"1.23.0"}gtm+gtm-works— both backed by@ainative/gtm-mcp, both self-report{"name":"ainative-gtm-mcp","version":"0.2.0"}
In every case, the spawn logs at ~/Library/Caches/claude-cli-nodejs/<project>/mcp-logs-<config-key>/*.jsonl show, for both entries in the pair:
Starting connection with timeout of 30000ms
Successfully connected (transport: stdio) in ~1-4s
Connection established with capabilities: {"hasTools":true,"hasPrompts":true/false,"hasResources":true/false,"hasResourceSubscribe":false,"serverVersion":{"name":"<identical-name>","version":"<identical-version>"}}
No errors, no timeouts — the handshake completes cleanly. But neither config entry's tools (mcp__<config-key>__*) ever appear in the tool list or via the ToolSearch deferred-tools index.
We also specifically tested renaming the .mcp.json keys for pair #1 to unique, unrelated names not sharing any substring with the original (kw-libera-diag / kw-manaka-diag instead of google-ads / google-ads-manaka). This did not resolve the issue — the new spawn logs still show hasTools:true for both, and tools still never appeared under the new key names either. This isolates the cause to the self-declared serverVersion rather than the .mcp.json key.
Expected behavior
Each configured MCP server entry, keyed by its unique .mcp.json key, should expose its own tools independently, regardless of what name/version the underlying server process self-reports in its initialize response. Two independent config entries should never silently cancel each other's tool registration.
Environment
- Claude Code (desktop app), MCP servers configured via project-level
.mcp.json(stdio transport,npx/local binary launchers) - macOS
Workaround
Only run one server instance of a given duplicate-name/version package at a time (comment out or remove the other .mcp.json entry, restart the session).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗