From de4126bf68c3d66fe4d429286170398584f25be2 Mon Sep 17 00:00:00 2001 From: lmiranda Date: Wed, 4 Feb 2026 13:46:43 -0500 Subject: [PATCH] fix: move mcp_servers to metadata.json to prevent silent plugin.json rejection Claude Code's strict schema validation silently rejects plugins with unknown root-level fields in plugin.json (anthropics/claude-code#20409). Moved mcp_servers to separate metadata.json files. Updated install/uninstall/list scripts to read from new location. Added cache clearing to switch-profile.sh. Co-Authored-By: Claude Opus 4.5 --- plugins/cmdb-assistant/.claude-plugin/metadata.json | 1 + .../contract-validator/.claude-plugin/metadata.json | 1 + plugins/data-platform/.claude-plugin/metadata.json | 1 + plugins/doc-guardian/.claude-plugin/metadata.json | 1 + plugins/git-flow/.claude-plugin/metadata.json | 1 + plugins/pr-review/.claude-plugin/metadata.json | 1 + plugins/projman/.claude-plugin/metadata.json | 1 + plugins/viz-platform/.claude-plugin/metadata.json | 1 + scripts/install-plugin.sh | 10 +++++----- scripts/list-installed.sh | 8 ++++---- scripts/switch-profile.sh | 4 ++++ scripts/uninstall-plugin.sh | 10 +++++----- 12 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 plugins/cmdb-assistant/.claude-plugin/metadata.json create mode 100644 plugins/contract-validator/.claude-plugin/metadata.json create mode 100644 plugins/data-platform/.claude-plugin/metadata.json create mode 100644 plugins/doc-guardian/.claude-plugin/metadata.json create mode 100644 plugins/git-flow/.claude-plugin/metadata.json create mode 100644 plugins/pr-review/.claude-plugin/metadata.json create mode 100644 plugins/projman/.claude-plugin/metadata.json create mode 100644 plugins/viz-platform/.claude-plugin/metadata.json diff --git a/plugins/cmdb-assistant/.claude-plugin/metadata.json b/plugins/cmdb-assistant/.claude-plugin/metadata.json new file mode 100644 index 0000000..3a90799 --- /dev/null +++ b/plugins/cmdb-assistant/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["netbox"]} diff --git a/plugins/contract-validator/.claude-plugin/metadata.json b/plugins/contract-validator/.claude-plugin/metadata.json new file mode 100644 index 0000000..11632cc --- /dev/null +++ b/plugins/contract-validator/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["contract-validator"]} diff --git a/plugins/data-platform/.claude-plugin/metadata.json b/plugins/data-platform/.claude-plugin/metadata.json new file mode 100644 index 0000000..59da561 --- /dev/null +++ b/plugins/data-platform/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["data-platform"]} diff --git a/plugins/doc-guardian/.claude-plugin/metadata.json b/plugins/doc-guardian/.claude-plugin/metadata.json new file mode 100644 index 0000000..a352e4a --- /dev/null +++ b/plugins/doc-guardian/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["gitea"]} diff --git a/plugins/git-flow/.claude-plugin/metadata.json b/plugins/git-flow/.claude-plugin/metadata.json new file mode 100644 index 0000000..a352e4a --- /dev/null +++ b/plugins/git-flow/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["gitea"]} diff --git a/plugins/pr-review/.claude-plugin/metadata.json b/plugins/pr-review/.claude-plugin/metadata.json new file mode 100644 index 0000000..a352e4a --- /dev/null +++ b/plugins/pr-review/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["gitea"]} diff --git a/plugins/projman/.claude-plugin/metadata.json b/plugins/projman/.claude-plugin/metadata.json new file mode 100644 index 0000000..a352e4a --- /dev/null +++ b/plugins/projman/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["gitea"]} diff --git a/plugins/viz-platform/.claude-plugin/metadata.json b/plugins/viz-platform/.claude-plugin/metadata.json new file mode 100644 index 0000000..3b6981d --- /dev/null +++ b/plugins/viz-platform/.claude-plugin/metadata.json @@ -0,0 +1 @@ +{"mcp_servers": ["viz-platform"]} diff --git a/scripts/install-plugin.sh b/scripts/install-plugin.sh index 0d19766..6762383 100755 --- a/scripts/install-plugin.sh +++ b/scripts/install-plugin.sh @@ -116,19 +116,19 @@ validate_target() { } # --- Get MCP Servers for Plugin --- -# Reads the mcp_servers array from plugin.json +# Reads the mcp_servers array from metadata.json (separate from plugin.json to avoid schema validation issues) # Returns newline-separated list of MCP server names, or empty if none get_mcp_servers() { local plugin_name="$1" - local plugin_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/plugin.json" + local metadata_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/metadata.json" - if [[ ! -f "$plugin_json" ]]; then + if [[ ! -f "$metadata_json" ]]; then return fi - # Read mcp_servers array from plugin.json + # Read mcp_servers array from metadata.json # Returns empty if field doesn't exist or is empty - jq -r '.mcp_servers // [] | .[]' "$plugin_json" 2>/dev/null || true + jq -r '.mcp_servers // [] | .[]' "$metadata_json" 2>/dev/null || true } # --- Check if plugin has any MCP servers --- diff --git a/scripts/list-installed.sh b/scripts/list-installed.sh index a19802b..bf501d5 100755 --- a/scripts/list-installed.sh +++ b/scripts/list-installed.sh @@ -68,16 +68,16 @@ get_available_plugins() { } # --- Get MCP Servers for Plugin --- -# Reads the mcp_servers array from plugin.json +# Reads the mcp_servers array from metadata.json (separate from plugin.json to avoid schema validation issues) get_mcp_servers() { local plugin_name="$1" - local plugin_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/plugin.json" + local metadata_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/metadata.json" - if [[ ! -f "$plugin_json" ]]; then + if [[ ! -f "$metadata_json" ]]; then return fi - jq -r '.mcp_servers // [] | .[]' "$plugin_json" 2>/dev/null || true + jq -r '.mcp_servers // [] | .[]' "$metadata_json" 2>/dev/null || true } # --- Check if plugin has any MCP servers defined --- diff --git a/scripts/switch-profile.sh b/scripts/switch-profile.sh index 12c5f70..1372d48 100755 --- a/scripts/switch-profile.sh +++ b/scripts/switch-profile.sh @@ -12,7 +12,9 @@ case "${1:-lean}" in lean) cp "$MARKETPLACE_DIR/marketplace-lean.json" "$MARKETPLACE_DIR/marketplace.json" cp "$ROOT_DIR/.mcp-lean.json" "$ROOT_DIR/.mcp.json" + rm -rf ~/.claude/plugins/cache/ echo "Switched to LEAN profile (6 plugins, 1 MCP server)" + echo "Plugin cache cleared." echo "" echo "Plugins: projman, git-flow, pr-review, clarity-assist, code-sentinel, doc-guardian" echo "MCP: gitea only" @@ -22,7 +24,9 @@ case "${1:-lean}" in full) cp "$MARKETPLACE_DIR/marketplace-full.json" "$MARKETPLACE_DIR/marketplace.json" cp "$ROOT_DIR/.mcp-full.json" "$ROOT_DIR/.mcp.json" + rm -rf ~/.claude/plugins/cache/ echo "Switched to FULL profile (12 plugins, 5 MCP servers)" + echo "Plugin cache cleared." echo "" echo "Plugins: all" echo "MCP: gitea, netbox, data-platform, viz-platform, contract-validator" diff --git a/scripts/uninstall-plugin.sh b/scripts/uninstall-plugin.sh index e0c62b4..8c32e53 100755 --- a/scripts/uninstall-plugin.sh +++ b/scripts/uninstall-plugin.sh @@ -77,19 +77,19 @@ validate_target() { } # --- Get MCP Servers for Plugin --- -# Reads the mcp_servers array from plugin.json +# Reads the mcp_servers array from metadata.json (separate from plugin.json to avoid schema validation issues) # Returns newline-separated list of MCP server names, or empty if none get_mcp_servers() { local plugin_name="$1" - local plugin_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/plugin.json" + local metadata_json="$REPO_ROOT/plugins/$plugin_name/.claude-plugin/metadata.json" - if [[ ! -f "$plugin_json" ]]; then + if [[ ! -f "$metadata_json" ]]; then return fi - # Read mcp_servers array from plugin.json + # Read mcp_servers array from metadata.json # Returns empty if field doesn't exist or is empty - jq -r '.mcp_servers // [] | .[]' "$plugin_json" 2>/dev/null || true + jq -r '.mcp_servers // [] | .[]' "$metadata_json" 2>/dev/null || true } # --- Remove from .mcp.json --- -- 2.49.1