0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code の設定ファイルにコメントを1行書いたら MCP サーバーが全部消えた——`.claude.json` の沈黙の全消去 (#69354) と予防

0
Posted at

Claude Code の設定ファイルにコメントを1行書いただけで、登録した MCP サーバーが全部消えました。引き金は rm でも git reset でもありません。~/.claude.json に、自分のためのメモを /* … */ で書き足して保存し、再起動しただけです。エラーは何も出ません。

この記事は、起票 #69354 で報告されたこの事故の、起きる仕組みと、消えたあとの取り戻し方、そして二度と失わないための2つの習慣をまとめます。

何が起きるのか(結論を一行で)

~/.claude.json は JSON です。JSON はコメントを許しません。///* */ を書き足すとファイル全体が不正な JSON になり、Claude Code はそれをパースできなかったときに、エラーを出さないまま設定を実質的に空へ上書きします。結果として、登録していた MCP サーバーの定義が一つ残らず消えます。

報告者は「動いていた ~/.claude.json にブロックコメントを一つ足して保存し、Claude Code を再起動したら、設定が黙って消え、MCP サーバーを全部失った」と書いています(macOS・2.1.142)。

なぜ「コメントを足す」が「全消失」になるのか

2つの事実が重なって事故になります。

1. .claude.json の中身は厳密な JSON で、コメントを書けない

JSON の仕様にはコメントの構文がありません。設定ファイルの編集に慣れていると、つい「この鍵は何のためか」「ここは一時的に外した」を /* */ でメモしたくなりますが、JSON ではそれが不正な文字になります。手元で確かめられます。

cat > /tmp/sample.json <<'EOF'
{
  "mcpServers": {
    "github": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"]}
  } /* 自分用のメモ */
}
EOF

python3 -c "import json; json.load(open('/tmp/sample.json'))"
# json.decoder.JSONDecodeError で失敗する(コメントの位置で構文エラー)

コメントを消せば、同じ中身でも問題なく読めます。壊しているのは中身ではなく、コメントという一行だけです。

2. 読む側が「パースに失敗したら、書く前に止まる」作りになっていない

起票へのコメントで、別の利用者がこの点を的確にまとめています。核心は「検証せずに書く(write-without-validation)」というパターンだ、と。たとえコメントが JSON でサポートされていなくても、パースに失敗したファイルを、パーサーが黙って上書きしていいわけがない、という指摘です。

安全な作りなら、読み込みに失敗した時点で「設定ファイルが壊れています」と知らせ、もとのファイルには指一本触れずに止まるはずです。ところが現状は、パースに失敗した後も書き込みの側が進み、壊れた入力の代わりに(実質的に空の)設定で上書きしてしまう。こうして、再起動という何気ない操作のあとに設定が消えます。

なぜ、よくある防御がすり抜けられるのか

Claude Code の安全策の多くは、Claude のツールの呼び出しBashWriteEdit)を PreToolUse の hook で走査して止める形です。ですがこの事故は、Claude が何かのツールを呼んだ結果ではありません。Claude Code というアプリ自身が、起動のときに自分の設定ファイルを読み書きする過程で起きています。ツールの呼び出しを見張る hook の網には、原理的にかかりません。

git の安全網も効きません。~/.claude.json は利用者のホームにある設定で、ふつうリポジトリの管理下に置きません。だから「git のおかげで戻せる」も、ここでは前提から外れます。

まず復旧する——記憶に頼らず MCP を取り戻す

消えても、多くの場合、設定そのものを思い出さずに取り戻せます。

1. シェルの履歴から、登録のコマンドを拾う。 MCP サーバーを CLI で足していたなら、そのときのコマンドが履歴に残っています。

history | grep -E "claude mcp (add|add-json)"

出たコマンドをそのまま走らせ直せば、同じサーバーが再び登録されます。

2. 古いコピーを探す。 エディタの自動保存や、クラウド同期の履歴、~/.claude.json.bak のような退避が残っていることがあります。

ls -la ~/.claude.json* ~/.config/**/claude*.json 2>/dev/null

3. プロジェクト側の設定を確認する。 MCP の定義は、ホームの ~/.claude.json だけでなく、プロジェクトの .mcp.json にも書けます。プロジェクト側に残っていれば、そこから写せます。

二度と失わないための2つの習慣

予防1:JSON にコメントを書かない。 いちばん効きます。鍵の意味を残したいなら、コメントではなく、説明を兼ねた鍵の名前にするか、別の README に書きます。どうしてもコメントつきの設定を扱いたいなら、それは JSONC や YAML を許す別のファイルの仕事で、~/.claude.json には持ち込みません。

予防2:.claude.json を、起動のたびに自動で退避する。 万一の上書きに備えて、世代を持ったバックアップを取ります。要点は、コピーする前に必ず「正しい JSON か」を検証することです。壊れた中身をバックアップに上書きしてしまっては元も子もありません。

#!/usr/bin/env bash
# ~/.claude/hooks/backup-claude-json.sh
# SessionStart で発火。今の ~/.claude.json が「正しい JSON のとき」だけ世代退避する。
set -euo pipefail
src="$HOME/.claude.json"
dir="$HOME/.claude/backups"
mkdir -p "$dir"
if [ -f "$src" ] && python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$src" 2>/dev/null; then
  cp "$src" "$dir/claude.json.$(date +%Y%m%d-%H%M%S)"
  # 直近30世代だけ残す
  ls -1t "$dir"/claude.json.* 2>/dev/null | tail -n +31 | xargs -r rm -f
fi
exit 0

settings.jsonhooks.SessionStart にこのスクリプトを登録しておけば、セッションを開くたびに、壊れていないときだけ世代が増えます。万一消えても、直近の正しい設定へ戻せます。

正直な検証の範囲

手元の Linux で確認できたのは、コメントを含む JSON が不正であること(上の json.load がその場で失敗します)と、復旧と予防の手順が成立することです。再起動で実際に空へ上書きされる瞬間は、自分の生きた設定を壊す危険があるため再現していません。報告された挙動として扱っています。なお「壊れた入力で黙って上書きする」挙動そのものは、本来は Anthropic 側が直すべきアプリのバグです(検証してから書く、壊れていたら止める、という作りにすべきです)。利用者の側でできるのは、上の2つの習慣で被害をゼロにすることです。


この事故は、Write の全置換で状態ファイルが消える型や、git stash の退避を捨ててしまう型と同じく、「日常のいちばん無害に見える操作」がデータ消失の引き金になる系統の一つです。こうした「設定で先回りすれば防げる事故」を、実機で検証した検出と復旧と予防の形で1つずつ集めた手引きを公開しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?