[BUG] Plugin-bundled MCP server silently suppressed when a user/project .mcp.json has the same command+args (env ignored in dedup)

Status Open
Reported on v2.1.227
Maintainer reply None cached
Activity 2 comments · opened Aug 11, 2026

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 in
claude 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

  1. 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"
         }
       }
     }
   }
  1. The user also has a separate user/project .mcp.json that 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"
         }
       }
     }
   }
  1. Start Claude Code and run claude mcp list or /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 though
SEARCH_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.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗