fix: write MCP config to ~/.claude.json instead of settings.json

Claude Code looks for global MCP servers in ~/.claude.json, not in
~/.claude/settings.json. Also migrates any existing entry from the
legacy location and cleans up duplicates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 18:45:59 +00:00
parent f9cefeecd8
commit 8a314a8a5b
+31 -31
View File
@@ -231,22 +231,22 @@ info "Checking existing MCP configuration..."
MCP_CONFIG_FILE="" MCP_CONFIG_FILE=""
EXISTING_ENTRY="" EXISTING_ENTRY=""
# Check global settings.json first (preferred location) # Check ~/.claude.json first (preferred location for global MCP servers)
if [ -f "$CLAUDE_SETTINGS" ]; then if [ -f "$CLAUDE_JSON" ]; then
EXISTING_ENTRY=$(jq -r --arg name "$MCP_NAME" '.mcpServers[$name] // empty' "$CLAUDE_SETTINGS" 2>/dev/null || true)
if [ -n "$EXISTING_ENTRY" ]; then
MCP_CONFIG_FILE="$CLAUDE_SETTINGS"
fi
fi
# Check ~/.claude.json
if [ -z "$EXISTING_ENTRY" ] && [ -f "$CLAUDE_JSON" ]; then
EXISTING_ENTRY=$(jq -r --arg name "$MCP_NAME" '.mcpServers[$name] // empty' "$CLAUDE_JSON" 2>/dev/null || true) EXISTING_ENTRY=$(jq -r --arg name "$MCP_NAME" '.mcpServers[$name] // empty' "$CLAUDE_JSON" 2>/dev/null || true)
if [ -n "$EXISTING_ENTRY" ]; then if [ -n "$EXISTING_ENTRY" ]; then
MCP_CONFIG_FILE="$CLAUDE_JSON" MCP_CONFIG_FILE="$CLAUDE_JSON"
fi fi
fi fi
# Check ~/.claude/settings.json (legacy location)
if [ -z "$EXISTING_ENTRY" ] && [ -f "$CLAUDE_SETTINGS" ]; then
EXISTING_ENTRY=$(jq -r --arg name "$MCP_NAME" '.mcpServers[$name] // empty' "$CLAUDE_SETTINGS" 2>/dev/null || true)
if [ -n "$EXISTING_ENTRY" ]; then
MCP_CONFIG_FILE="$CLAUDE_SETTINGS"
fi
fi
# Check for project-level .mcp.json files # Check for project-level .mcp.json files
FOUND_PROJECT_MCP=() FOUND_PROJECT_MCP=()
while IFS= read -r -d '' mcp_file; do while IFS= read -r -d '' mcp_file; do
@@ -268,9 +268,9 @@ if [ ${#FOUND_PROJECT_MCP[@]} -gt 0 ]; then
if [ -z "$EXISTING_ENTRY" ]; then if [ -z "$EXISTING_ENTRY" ]; then
# No global config yet - migrate from project file # No global config yet - migrate from project file
if ask_yes_no " Migrate to global config ($CLAUDE_SETTINGS)?"; then if ask_yes_no " Migrate to global config ($CLAUDE_JSON)?"; then
EXISTING_ENTRY=$(jq --arg name "$MCP_NAME" '.mcpServers[$name]' "$mcp_file") EXISTING_ENTRY=$(jq --arg name "$MCP_NAME" '.mcpServers[$name]' "$mcp_file")
MCP_CONFIG_FILE="$CLAUDE_SETTINGS" MCP_CONFIG_FILE="$CLAUDE_JSON"
fi fi
fi fi
@@ -396,22 +396,22 @@ else
}') }')
fi fi
# Write to settings.json (global/user level) # Write to ~/.claude.json (global MCP config location)
mkdir -p "$(dirname "$CLAUDE_SETTINGS")" if [ ! -f "$CLAUDE_JSON" ]; then
if [ ! -f "$CLAUDE_SETTINGS" ]; then echo '{}' > "$CLAUDE_JSON"
echo '{}' > "$CLAUDE_SETTINGS"
fi fi
tmp=$(jq --arg name "$MCP_NAME" --argjson entry "$MCP_ENTRY" \ tmp=$(jq --arg name "$MCP_NAME" --argjson entry "$MCP_ENTRY" \
'.mcpServers[$name] = $entry' "$CLAUDE_SETTINGS") '.mcpServers[$name] = $entry' "$CLAUDE_JSON")
echo "$tmp" > "$CLAUDE_SETTINGS" echo "$tmp" > "$CLAUDE_JSON"
ok "Written to $CLAUDE_SETTINGS" ok "Written to $CLAUDE_JSON"
# Also register via claude CLI if available (belt and suspenders) # Clean up from settings.json if it exists there (legacy location)
if command -v claude &>/dev/null; then if [ -f "$CLAUDE_SETTINGS" ]; then
# Check if claude mcp already has this entry to avoid duplicates if jq -e --arg name "$MCP_NAME" '.mcpServers[$name] != null' "$CLAUDE_SETTINGS" &>/dev/null; then
if claude mcp list 2>/dev/null | grep -q "$MCP_NAME"; then tmp=$(jq --arg name "$MCP_NAME" 'del(.mcpServers[$name])' "$CLAUDE_SETTINGS")
claude mcp remove "$MCP_NAME" --scope user 2>/dev/null || true echo "$tmp" > "$CLAUDE_SETTINGS"
ok "Removed legacy entry from $CLAUDE_SETTINGS"
fi fi
fi fi
@@ -436,13 +436,13 @@ done < <(find "$HOME" -maxdepth 3 -name ".mcp.json" \
-not -path "*/node_modules/*" \ -not -path "*/node_modules/*" \
-print0 2>/dev/null || true) -print0 2>/dev/null || true)
# Clean from ~/.claude.json if we wrote to settings.json # Clean from ~/.claude/settings.json if we wrote to ~/.claude.json
if [ -f "$CLAUDE_JSON" ]; then if [ -f "$CLAUDE_SETTINGS" ]; then
if jq -e --arg name "$MCP_NAME" '.mcpServers[$name] != null' "$CLAUDE_JSON" &>/dev/null; then if jq -e --arg name "$MCP_NAME" '.mcpServers[$name] != null' "$CLAUDE_SETTINGS" &>/dev/null; then
warn "Duplicate found in $CLAUDE_JSON" warn "Duplicate found in $CLAUDE_SETTINGS"
if ask_yes_no " Remove from $CLAUDE_JSON? (already in settings.json)"; then if ask_yes_no " Remove from $CLAUDE_SETTINGS? (already in $CLAUDE_JSON)"; then
tmp=$(jq --arg name "$MCP_NAME" 'del(.mcpServers[$name])' "$CLAUDE_JSON") tmp=$(jq --arg name "$MCP_NAME" 'del(.mcpServers[$name])' "$CLAUDE_SETTINGS")
echo "$tmp" > "$CLAUDE_JSON" echo "$tmp" > "$CLAUDE_SETTINGS"
ok "Removed" ok "Removed"
fi fi
fi fi