[BUG] Plugin-bundled MCP server silently suppressed when a user/project .mcp.json has the same command+args (env ignored in dedup)
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 plugin ships its own .mcp.json and there is another regular .mcp.json
(user or project scope) that launches a server with the same command + args,
deduplication keys only on command + args and ignores the env block and the
server name.
As a result only one server is registered and the other is silently dropped -
even though the env values differ and point the server at a completely different
backend. The suppressed server does not appear as Failed or Disabled inclaude mcp list; it is simply absent.
In practice the plugin-bundled server is the one that disappears.
Note: this reproduces specifically between a plugin .mcp.json and a separate
(non-plugin) .mcp.json. It does not reproduce between two different plugins.
What Should Happen?
Two MCP servers should only be treated as duplicates when command + args +env all match. Servers with the same command+args but different env target
different systems and must all load.
Error Messages/Logs
Steps to Reproduce
- A plugin ships this bundled
.mcp.json:
{
"mcpServers": {
"internal-search": {
"command": "docker",
"args": ["run", "-i", "--rm", "acme/search-mcp:1.4"],
"env": {
"SEARCH_ENDPOINT": "https://search.internal.acme.dev",
"SEARCH_MODE": "readonly"
}
}
}
}
- The user also has a separate user/project
.mcp.jsonthat uses the SAME
command+args but a DIFFERENT env:
{
"mcpServers": {
"public-search": {
"command": "docker",
"args": ["run", "-i", "--rm", "acme/search-mcp:1.4"],
"env": {
"SEARCH_ENDPOINT": "https://search.public.acme.com",
"SEARCH_MODE": "readwrite"
}
}
}
}
- Start Claude Code and run
claude mcp listor /mcp.
Expected: both the plugin's internal-search and the user's public-search
load - they hit different endpoints in different modes.
Actual: only one registers. The plugin-bundled internal-search is silently
suppressed as a "duplicate" because command+args match, even thoughSEARCH_ENDPOINT and SEARCH_MODE differ.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.227
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
This is a common, legitimate pattern: many MCP servers launch through a generic
runner (docker/npx/uv), so command+args are identical and the only distinguishing
factor is env (endpoint, tenant, credentials, mode). It is worse for plugin
authors, because a plugin cannot control what other .mcp.json files exist on the
user's machine, so its bundled server can disappear through no fault of the plugin.
Prior art: #32393 (closed by a bot, not fixed; confirmed still present through
v2.1.210), and related #35573, #48857, #49372.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗