From 0c61710c432bcc4d52e0cfc27bc5f16264440a0d Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Thu, 30 Apr 2026 01:05:20 -0400 Subject: [PATCH] fix: disable claude plugin bundled mcps --- .claude-plugin/PLUGIN_SCHEMA_NOTES.md | 24 +++++++++++++++++++++++- .claude-plugin/plugin.json | 1 + README.md | 2 ++ schemas/plugin.schema.json | 18 +++++++++++++++++- tests/plugin-manifest.test.js | 18 ++++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/.claude-plugin/PLUGIN_SCHEMA_NOTES.md b/.claude-plugin/PLUGIN_SCHEMA_NOTES.md index 3ce4b76f..7ee8f3bd 100644 --- a/.claude-plugin/PLUGIN_SCHEMA_NOTES.md +++ b/.claude-plugin/PLUGIN_SCHEMA_NOTES.md @@ -132,6 +132,26 @@ The test `plugin.json does NOT have explicit hooks declaration` in `tests/hooks/ --- +## The `mcpServers` Field: Keep the Empty Opt-Out + +ECC keeps `.mcp.json` at the repository root for Codex plugin installs and manual MCP setup. +Claude Code also auto-discovers plugin-root `.mcp.json` files by convention, which would bundle the same MCP servers into Claude plugin installs. + +Keep this field in `.claude-plugin/plugin.json`: + +```json +{ + "mcpServers": {} +} +``` + +This explicit empty object prevents Claude plugin installs from auto-loading ECC's root MCP definitions. +Without the opt-out, strict OpenAI-compatible gateways can reject plugin MCP tool names such as `mcp__plugin_everything-claude-code_github__create_pull_request_review` because they exceed 64 characters. + +Users who want the bundled MCP servers should configure them manually from `.mcp.json` or `mcp-configs/mcp-servers.json`. + +--- + ## Known Anti-Patterns These look correct but are rejected: @@ -142,6 +162,7 @@ These look correct but are rejected: * Relying on inferred paths * Assuming marketplace behavior matches local validation * **Adding `"hooks": "./hooks/hooks.json"`** - auto-loaded by convention, causes duplicate error +* Removing `"mcpServers": {}` - re-enables root `.mcp.json` auto-discovery for Claude plugin installs and can produce overlong MCP tool names Avoid cleverness. Be explicit. @@ -170,7 +191,8 @@ Before submitting changes that touch `plugin.json`: 1. Ensure all component fields are arrays 2. Include a `version` 3. Do NOT add `agents` or `hooks` fields (both are auto-loaded by convention) -4. Run: +4. Preserve `"mcpServers": {}` unless you are intentionally changing Claude plugin MCP bundling behavior +5. Run: ```bash claude plugin validate .claude-plugin/plugin.json diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 5dcb32b9..12666847 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -22,6 +22,7 @@ "automation", "best-practices" ], + "mcpServers": {}, "skills": ["./skills/"], "commands": ["./commands/"] } diff --git a/README.md b/README.md index ed936532..d1d3b778 100644 --- a/README.md +++ b/README.md @@ -829,6 +829,8 @@ Windows note: the Claude config directory is `%USERPROFILE%\\.claude`, not `~/cl #### Configure MCPs +Claude plugin installs intentionally do not auto-enable ECC's bundled MCP server definitions. This avoids overlong plugin MCP tool names on strict third-party gateways while keeping manual MCP setup available. + Copy desired MCP server definitions from `mcp-configs/mcp-servers.json` into your official Claude Code config in `~/.claude/settings.json`, or into a project-scoped `.mcp.json` if you want repo-local MCP access. If you already run your own copies of ECC-bundled MCPs, set: diff --git a/schemas/plugin.schema.json b/schemas/plugin.schema.json index f9a3d90f..e5bda89e 100644 --- a/schemas/plugin.schema.json +++ b/schemas/plugin.schema.json @@ -5,7 +5,7 @@ "required": ["name"], "properties": { "name": { "type": "string" }, - "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" }, + "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?$" }, "description": { "type": "string" }, "author": { "oneOf": [ @@ -31,6 +31,22 @@ "type": "array", "items": { "type": "string" } }, + "commands": { + "type": "array", + "items": { "type": "string" } + }, + "mcpServers": { + "oneOf": [ + { "type": "string" }, + { + "type": "array", + "items": { "type": "string" } + }, + { + "type": "object" + } + ] + }, "features": { "type": "object", "properties": { diff --git a/tests/plugin-manifest.test.js b/tests/plugin-manifest.test.js index f067921e..4a3111e9 100644 --- a/tests/plugin-manifest.test.js +++ b/tests/plugin-manifest.test.js @@ -217,6 +217,24 @@ test('claude plugin.json commands is an array', () => { assert.ok(Array.isArray(claudePlugin.commands), 'Expected commands to be an array'); }); +test('claude plugin.json disables bundled MCP servers for provider tool-name compatibility', () => { + const reportedOverlongToolName = `mcp__plugin_${claudePlugin.name}_github__create_pull_request_review`; + + assert.ok( + reportedOverlongToolName.length > 64, + 'Expected the reported GitHub MCP tool name to exceed strict provider limits without the MCP opt-out', + ); + assert.ok( + Object.prototype.hasOwnProperty.call(claudePlugin, 'mcpServers'), + 'Expected mcpServers to be explicitly declared so Claude Code does not auto-load root .mcp.json', + ); + assert.deepStrictEqual( + claudePlugin.mcpServers, + {}, + 'Claude plugin installs must not auto-bundle root MCP servers; document/manual MCP install remains supported', + ); +}); + test('claude plugin.json does NOT have explicit hooks declaration', () => { assert.ok( !('hooks' in claudePlugin),