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=""
EXISTING_ENTRY=""
# Check global settings.json first (preferred location)
if [ -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 ~/.claude.json
if [ -z "$EXISTING_ENTRY" ] && [ -f "$CLAUDE_JSON" ]; then
# Check ~/.claude.json first (preferred location for global MCP servers)
if [ -f "$CLAUDE_JSON" ]; then
EXISTING_ENTRY=$(jq -r --arg name "$MCP_NAME" '.mcpServers[$name] // empty' "$CLAUDE_JSON" 2>/dev/null || true)
if [ -n "$EXISTING_ENTRY" ]; then
MCP_CONFIG_FILE="$CLAUDE_JSON"
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
FOUND_PROJECT_MCP=()
while IFS= read -r -d '' mcp_file; do
@@ -268,9 +268,9 @@ if [ ${#FOUND_PROJECT_MCP[@]} -gt 0 ]; then
if [ -z "$EXISTING_ENTRY" ]; then
# 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")
MCP_CONFIG_FILE="$CLAUDE_SETTINGS"
MCP_CONFIG_FILE="$CLAUDE_JSON"
fi
fi
@@ -396,22 +396,22 @@ else
}')
fi
# Write to settings.json (global/user level)
mkdir -p "$(dirname "$CLAUDE_SETTINGS")"
if [ ! -f "$CLAUDE_SETTINGS" ]; then
echo '{}' > "$CLAUDE_SETTINGS"
# Write to ~/.claude.json (global MCP config location)
if [ ! -f "$CLAUDE_JSON" ]; then
echo '{}' > "$CLAUDE_JSON"
fi
tmp=$(jq --arg name "$MCP_NAME" --argjson entry "$MCP_ENTRY" \
'.mcpServers[$name] = $entry' "$CLAUDE_SETTINGS")
echo "$tmp" > "$CLAUDE_SETTINGS"
ok "Written to $CLAUDE_SETTINGS"
'.mcpServers[$name] = $entry' "$CLAUDE_JSON")
echo "$tmp" > "$CLAUDE_JSON"
ok "Written to $CLAUDE_JSON"
# Also register via claude CLI if available (belt and suspenders)
if command -v claude &>/dev/null; then
# Check if claude mcp already has this entry to avoid duplicates
if claude mcp list 2>/dev/null | grep -q "$MCP_NAME"; then
claude mcp remove "$MCP_NAME" --scope user 2>/dev/null || true
# Clean up from settings.json if it exists there (legacy location)
if [ -f "$CLAUDE_SETTINGS" ]; then
if jq -e --arg name "$MCP_NAME" '.mcpServers[$name] != null' "$CLAUDE_SETTINGS" &>/dev/null; then
tmp=$(jq --arg name "$MCP_NAME" 'del(.mcpServers[$name])' "$CLAUDE_SETTINGS")
echo "$tmp" > "$CLAUDE_SETTINGS"
ok "Removed legacy entry from $CLAUDE_SETTINGS"
fi
fi
@@ -436,13 +436,13 @@ done < <(find "$HOME" -maxdepth 3 -name ".mcp.json" \
-not -path "*/node_modules/*" \
-print0 2>/dev/null || true)
# Clean from ~/.claude.json if we wrote to settings.json
if [ -f "$CLAUDE_JSON" ]; then
if jq -e --arg name "$MCP_NAME" '.mcpServers[$name] != null' "$CLAUDE_JSON" &>/dev/null; then
warn "Duplicate found in $CLAUDE_JSON"
if ask_yes_no " Remove from $CLAUDE_JSON? (already in settings.json)"; then
tmp=$(jq --arg name "$MCP_NAME" 'del(.mcpServers[$name])' "$CLAUDE_JSON")
echo "$tmp" > "$CLAUDE_JSON"
# Clean from ~/.claude/settings.json if we wrote to ~/.claude.json
if [ -f "$CLAUDE_SETTINGS" ]; then
if jq -e --arg name "$MCP_NAME" '.mcpServers[$name] != null' "$CLAUDE_SETTINGS" &>/dev/null; then
warn "Duplicate found in $CLAUDE_SETTINGS"
if ask_yes_no " Remove from $CLAUDE_SETTINGS? (already in $CLAUDE_JSON)"; then
tmp=$(jq --arg name "$MCP_NAME" 'del(.mcpServers[$name])' "$CLAUDE_SETTINGS")
echo "$tmp" > "$CLAUDE_SETTINGS"
ok "Removed"
fi
fi