claude-code - 💡(How to fix) Fix [FEATURE] Namespace plugin MCP server registrations to prevent cross-plugin collisions [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#60599Fetched 2026-05-20 03:54:22
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
labeled ×3

When two plugins both declare an MCP server with the same inner key in their mcpServers config, the loader appears to deduplicate by inner key alone (not by (plugin, server_key)), and one plugin's registration is silently dropped. /reload-plugins reports 1 error during load with no detail on which plugin failed.

Request: dedupe MCP server registrations by (plugin, server_key) so each plugin gets its own independent registration in its own mcp__plugin_<plugin>_<server>__* namespace, regardless of whether another plugin happens to declare the same inner key.

Error Message

When two plugins both declare an MCP server with the same inner key in their mcpServers config, the loader appears to deduplicate by inner key alone (not by (plugin, server_key)), and one plugin's registration is silently dropped. /reload-plugins reports 1 error during load with no detail on which plugin failed. 1 error during load. Run /doctor for details. No load error. The namespacing already implies per-plugin scoping; the loader should honor it for the dedup decision too. 4. Observe: 1 error during load. Only one of mcp__plugin_<plugin1>_foo__* / mcp__plugin_<plugin2>_foo__* appears in the deferred tool list. Not blocking — marketplace authors can work around it with per-plugin keys. But it's a real source of confusion, hurts SKILL portability, and the "1 error during load" message is opaque enough that it takes meaningful debugging to track down. The fix appears self-contained to the plugin loader's dedup logic.

Root Cause

Curated plugin marketplaces tend toward shared backends — Slack, Datadog, Jira, GitHub, etc. all get consumed by multiple plugins. Today, marketplace maintainers have to choose between:

  1. Per-plugin inner keys — works but creates verbose tool names and forces SKILLs to either accept reduced portability or maintain a lookup table of plugin-suffixed prefixes.
  2. Single-owner pattern — one plugin owns the registration; others depend on it being installed. Breaks any plugin if its dependency isn't installed; no way to declare the dependency, so the failure is silent.
  3. Live with the collision — accept that whichever plugin loads second silently loses its registration. Users hit confusing "missing tool" failures depending on install order.

None of these are good. Per-plugin namespace dedup is the structural fix.

Code Example

/reload-plugins
Reloaded: N plugins · ... · 6 plugin MCP servers · ...
1 error during load. Run /doctor for details.
RAW_BUFFERClick to expand / collapse

Summary

When two plugins both declare an MCP server with the same inner key in their mcpServers config, the loader appears to deduplicate by inner key alone (not by (plugin, server_key)), and one plugin's registration is silently dropped. /reload-plugins reports 1 error during load with no detail on which plugin failed.

Request: dedupe MCP server registrations by (plugin, server_key) so each plugin gets its own independent registration in its own mcp__plugin_<plugin>_<server>__* namespace, regardless of whether another plugin happens to declare the same inner key.

Current behavior

With two plugins installed, both declaring an MCP server { "slack": { "type": "http", "url": "https://mcp.slack.com/mcp" } }:

/reload-plugins
Reloaded: N plugins · ... · 6 plugin MCP servers · ...
1 error during load. Run /doctor for details.

The deferred tool list contains mcp__plugin_<first-loaded-plugin>_slack__* but not mcp__plugin_<second-loaded-plugin>_slack__*. The second registration is dropped with no indication to the user which plugin's tools they're missing. Whichever plugin "won" depends on load order.

This forces marketplace authors to mint plugin-specific inner keys (slack-engineering, slack-release) to avoid the collision — which then produces longer, less readable tool names (mcp__plugin_release_slack-release__slack_read_channel) and forces SKILL.md files to reference plugin-suffixed prefixes that break portability.

Expected behavior

Two plugins declaring mcpServers.slack should each register independently:

  • Plugin A's tools: mcp__plugin_A_slack__*
  • Plugin B's tools: mcp__plugin_B_slack__*

No load error. The namespacing already implies per-plugin scoping; the loader should honor it for the dedup decision too.

Why this matters

Curated plugin marketplaces tend toward shared backends — Slack, Datadog, Jira, GitHub, etc. all get consumed by multiple plugins. Today, marketplace maintainers have to choose between:

  1. Per-plugin inner keys — works but creates verbose tool names and forces SKILLs to either accept reduced portability or maintain a lookup table of plugin-suffixed prefixes.
  2. Single-owner pattern — one plugin owns the registration; others depend on it being installed. Breaks any plugin if its dependency isn't installed; no way to declare the dependency, so the failure is silent.
  3. Live with the collision — accept that whichever plugin loads second silently loses its registration. Users hit confusing "missing tool" failures depending on install order.

None of these are good. Per-plugin namespace dedup is the structural fix.

Repro

  1. Create two plugins in a marketplace, each with a plugin.json declaring mcpServers: ["./mcps/foo.json"].
  2. Have both ./mcps/foo.json files contain { "mcpServers": { "foo": { "type": "http", "url": "https://example.com/mcp" } } } — same inner key.
  3. Install both plugins, run /reload-plugins.
  4. Observe: 1 error during load. Only one of mcp__plugin_<plugin1>_foo__* / mcp__plugin_<plugin2>_foo__* appears in the deferred tool list.

Severity

Not blocking — marketplace authors can work around it with per-plugin keys. But it's a real source of confusion, hurts SKILL portability, and the "1 error during load" message is opaque enough that it takes meaningful debugging to track down. The fix appears self-contained to the plugin loader's dedup logic.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Two plugins declaring mcpServers.slack should each register independently:

  • Plugin A's tools: mcp__plugin_A_slack__*
  • Plugin B's tools: mcp__plugin_B_slack__*

No load error. The namespacing already implies per-plugin scoping; the loader should honor it for the dedup decision too.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [FEATURE] Namespace plugin MCP server registrations to prevent cross-plugin collisions [1 participants]