You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A repository that is both a Cursor plugin and a Claude Code plugin often ships two MCP config filenames:
mcp.json — Cursor’s documented plugin default (Plugins reference: auto-discover mcp.json; mcpServers in .cursor-plugin/plugin.json only for a custom path or inline config)
.mcp.json — Claude Code’s documented plugin default
The Marketplace scan already looks for both names (see #43: “.mcp.json or mcp.json”). The runtime on a Marketplace clone is not documented when both files exist and contain different servers. In our case the clone started the Claude Code file (local stdio / uvx) instead of the Cursor file (hosted HTTP + OAuth).
That is a different failure from #43 (scanner ignoring manifest paths / inline mcpServers). This issue is precedence when both files are present.
Why we ship both (adoption, not a quirk)
We publish one git repository as two first-class plugins:
a Cursor Marketplace plugin (.cursor-plugin/), and
a Claude Code plugin (.claude-plugin/).
That is deliberate distribution: the same skills + hosted MCP for whoever the user already lives in, without a second repo or a second source of truth. Cursor’s public contract puts MCP in mcp.json. Claude Code’s public contract puts MCP in .mcp.json. Following both docs in one repo is how dual-client vendors will keep packaging this — Figma’s mcp-server-guide is the same shape (Cursor + Claude in one git tree).
Anyone else aiming for adoption on both IDEs will hit the same filename pair. If those two files ever diverge (hosted vs local stdio, different env, a leftover uvx on the Claude side), the Cursor Marketplace clone can start the wrong server while the listing still describes the hosted one. This is not unique to us; it is the default layout two public plugin specs produce when they share a repo.
Expected
Per the plugins reference:
Default discovery for a Cursor plugin is mcp.json at the plugin root.
.mcp.json is not the Cursor plugin contract (it is Claude Code’s).
If both files exist, Cursor should either:
load mcp.json only, or
document a deterministic precedence (and warn when the two payloads differ).
The submit scanner and the authoring docs should name the same files and the same precedence.
Actual
Installing from the Marketplace cloned the entire GitHub repo into the plugin cache. Both files sat at the plugin root. With nomcpServers pin (we followed the docs: omit the field so mcp.json is auto-discovered), Cursor connected to the server in .mcp.json, not mcp.json.
A local plugin copy that only included mcp.json behaved as documented (hosted URL). The Marketplace clone did not.
Reproduction
Minimal dual-client plugin root (the layout two marketplaces independently document):
.cursor-plugin/plugin.json — no mcpServers (rely on default discovery):
In the authoring / submit docs, warn dual Cursor + Claude Code authors: shipping both filenames is the natural adoption layout; different payloads can make the Marketplace clone start the wrong server. Pin mcpServers or keep a single shared file.
Summary
A repository that is both a Cursor plugin and a Claude Code plugin often ships two MCP config filenames:
mcp.json— Cursor’s documented plugin default (Plugins reference: auto-discovermcp.json;mcpServersin.cursor-plugin/plugin.jsononly for a custom path or inline config).mcp.json— Claude Code’s documented plugin defaultThe Marketplace scan already looks for both names (see #43: “
.mcp.jsonormcp.json”). The runtime on a Marketplace clone is not documented when both files exist and contain different servers. In our case the clone started the Claude Code file (local stdio /uvx) instead of the Cursor file (hosted HTTP + OAuth).That is a different failure from #43 (scanner ignoring manifest paths / inline
mcpServers). This issue is precedence when both files are present.Why we ship both (adoption, not a quirk)
We publish one git repository as two first-class plugins:
.cursor-plugin/), and.claude-plugin/).That is deliberate distribution: the same skills + hosted MCP for whoever the user already lives in, without a second repo or a second source of truth. Cursor’s public contract puts MCP in
mcp.json. Claude Code’s public contract puts MCP in.mcp.json. Following both docs in one repo is how dual-client vendors will keep packaging this — Figma’s mcp-server-guide is the same shape (Cursor + Claude in one git tree).Anyone else aiming for adoption on both IDEs will hit the same filename pair. If those two files ever diverge (hosted vs local stdio, different env, a leftover
uvxon the Claude side), the Cursor Marketplace clone can start the wrong server while the listing still describes the hosted one. This is not unique to us; it is the default layout two public plugin specs produce when they share a repo.Expected
Per the plugins reference:
mcp.jsonat the plugin root..mcp.jsonis not the Cursor plugin contract (it is Claude Code’s).mcp.jsononly, orThe submit scanner and the authoring docs should name the same files and the same precedence.
Actual
Installing from the Marketplace cloned the entire GitHub repo into the plugin cache. Both files sat at the plugin root. With no
mcpServerspin (we followed the docs: omit the field somcp.jsonis auto-discovered), Cursor connected to the server in.mcp.json, notmcp.json.A local plugin copy that only included
mcp.jsonbehaved as documented (hosted URL). The Marketplace clone did not.Reproduction
Minimal dual-client plugin root (the layout two marketplaces independently document):
.cursor-plugin/plugin.json— nomcpServers(rely on default discovery):{ "name": "example", "displayName": "Example", "version": "0.1.0" }.claude-plugin/plugin.json— Claude Code plugin in the same repo (MCP is not inlined; it auto-discovers.mcp.json).mcp.json(Cursor / hosted — what the listing should run):{ "mcpServers": { "example": { "url": "https://mcp.example.com/mcp", "auth": { "CLIENT_ID": "example-mcp" } } } }.mcp.json(Claude Code / local stdio — different payload on purpose):{ "mcpServers": { "example": { "command": "uvx", "args": ["example-mcp-server"] } } }Steps:
Result: the clone started
uvx example-mcp-serverfrom.mcp.json.Expected: hosted
https://mcp.example.com/mcpfrommcp.json.Workaround that unblocked us
.mcp.jsononly (same file Claude Code auto-discovers)."mcpServers": "./.mcp.json"in.cursor-plugin/plugin.json.mcp.jsonwith a different server.This matches the documented custom-path override, and is what figma/mcp-server-guide does (single
.mcp.json+ pin; no rootmcp.json).Request
mcp.jsonand.mcp.jsonboth exist at the plugin root.mcp.json).mcpServersor keep a single shared file.Related
.mcp.jsonormcp.jsonand does not use the manifest for custom paths / inline MCP