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のMCP設定ミスでWSL2が瀕死に — メモリ7.7GiB蒸発・ロードアベレージ57超の地獄から生還するまで

0
Posted at

image.png

目次

  1. はじめに
  2. 何が起きたか
  3. 根本原因
  4. 対策
  5. 対策の効果
  6. 再発防止チェックリスト
  7. 補足: なぜ他の PC では発生しなかったか
  8. まとめ

はじめに

Claude Code で MCP(Model Context Protocol)サーバーを複数利用していたところ、WSL2 環境でメモリ使用量が 7.7 GiB、ロードアベレージが 57超 に達し、システムがほぼ操作不能になるという事象に遭遇しました。

業務時間が半日溶けました(しかし、Claude Codeの利用で生産性が2倍以上になっているので、おつりは返ってきますが、、)orz

本記事では、原因調査から恒久対策までの全過程を共有します。
同じ構成で Claude Code を使っている方の参考になれば幸いです。

環境

  • OS: WSL2(Ubuntu 24.04)
  • RAM: 16 GB
  • CPU: 12コア
  • Claude Code: v2.1.x
  • MCP サーバー数: 9種(Atlassian, AWS系, GitHub, Playwright 等)

何が起きたか

ある日、Claude Code の応答が劇的に遅くなり、ターミナル操作すらままならない状態に。htop を見ると異常な値が並んでいました。
ちなみに、WSLの動作も激重になりました。

Memory: 7.7 GiB / 15 GiB (通常時の約4倍)
Load Average: 57.93 (12コアの約5倍、完全に過負荷)

Ctrl+C で Claude Code を終了しても状況は改善しません。ps aux で調べると、同一の MCP サーバープロセスが大量に起動 していました。

計測データ

項目
孤立 MCP プロセス数 43個
孤立プロセスのメモリ合計 約 4.2 GB(RSS 合計)
全 MCP プロセス数 54個
セッション1回あたりの起動プロセス数 約 30〜40個

本来9プロセスで済むはずの MCP サーバーが、54個も起動 していたのです。


根本原因

調査の結果、2つの設定ミスの複合 が原因でした。

原因1: .mcp.json の多階層重複

Claude Code は起動時に、カレントディレクトリから親方向へ .mcp.json を再帰的に探索・マージします。以下のように3階層に .mcp.json が配置されていました。

~/.claude/.mcp.json                          ← グローバル設定(6種)
└── ~/dev/.mcp.json                          ← プロジェクト設定(6種、グローバルと完全重複)
    └── ~/dev/my-project/.mcp.json           ← サブプロジェクト設定(11種)

サブプロジェクトのディレクトリで Claude Code を起動すると、3階層すべてが読み込まれ、同じ MCP サーバーが最大3インスタンスずつ起動されます。

MCP サーバー グローバル プロジェクト サブプロジェクト 起動数
aws-documentation-mcp-server 最大3つ
cdk-mcp-server 最大3つ
Context7 最大3つ
aws-cli-mcp-server 最大3つ
serena 最大3つ
mcp-atlassian 最大3つ

6種 × 3インスタンス = 18プロセスの無駄な多重起動

原因2: claude_code MCP サーバーによる再帰的プロセス生成

さらに深刻だったのが、.mcp.json に含まれていた以下の定義です。

"claude_code": {
    "command": "claude",
    "args": ["mcp", "serve"],
    "env": {}
}

これは Claude Code 自身を MCP サーバーとして子プロセス起動する 設定です。

claude mcp serve とは何か

claude mcp serveClaude Code 公式のサブコマンド で、Claude Code を他のツール(別の AI エージェント等)から MCP サーバーとして呼び出すための機能です。つまり、外部ツールが Claude Code の能力を利用するためのインターフェースとして設計されています。

しかし、Claude Code 自身の MCP 設定に定義するためのものではありません。

この定義が .mcp.json に含まれていた経緯として、claude mcp add コマンドや MCP セットアップ時に自動追加された可能性が高いと考えられます。公式機能として存在するコマンドが、自分自身の設定に入ると再帰ループを引き起こすという、いわば 「正規機能の誤配置」による罠 です。

何が起きるか

フォークボムに近い挙動 で、OS のリソース制限に到達するまでプロセスが増殖し続けます。

さらに、セッション終了後のプロセス孤立化の流れも図示します。

悪化要因: WSL2 のシグナル伝搬問題

Claude Code セッション終了時(Ctrl+C)に、子プロセスへ SIGTERM が正常に伝搬されません。

  • プロセスの親が WSL の Relay プロセスまたは init(PID=1)に引き取られる
  • 孤立プロセス(orphan process)は Claude Code のライフサイクルから切り離される
  • セッションを終了しても孤立プロセスは永続化 し、次回セッション起動で さらに蓄積

これが「Claude Code を終了してもメモリが減らない」原因でした。

発生メカニズムの全体像

Claude Code 起動(~/dev/my-project/ にて)
│
├─ Phase 1: 設定ファイルのマージ読み込み
│   ├─ ~/.claude/.mcp.json      → 6種
│   ├─ ~/dev/.mcp.json          → 6種(重複)
│   └─ ~/dev/my-project/.mcp.json → 11種(重複 + claude_code)
│
├─ Phase 2: MCP サーバープロセスの起動
│   ├─ 重複定義 → 約 24〜27 プロセス
│   └─ claude_code → 再帰的に +11〜27 プロセス
│
├─ Phase 3: 1セッションあたり合計 約 30〜40 プロセス
│
└─ Phase 4: セッション終了
    ├─ Claude Code 本体は終了
    └─ 子プロセスに SIGTERM 不達(WSL2 固有)
        └─ 孤立プロセスとして永続化
            └─ 数セッション後: 43個 / 4.2GB 消費

対策

対策1: MCP 設定の公式準拠な一元管理

Claude Code の公式ドキュメントによると、MCP 設定の保存場所は以下の通りです。

スコープ 保存場所
ユーザー/ローカル ~/.claude.jsonmcpServers フィールド)
プロジェクト プロジェクトルートの .mcp.json
管理 システムディレクトリの managed-mcp.json

全 MCP サーバーを ~/.claude.jsonmcpServers フィールドに一元管理 し、それ以外の .mcp.json はすべて削除しました。

変更前

~/.claude.json (mcpServers)  → 10種(claude_code 含む)
~/.claude/.mcp.json          → 6種(重複)
~/dev/.mcp.json              → 6種(重複)
~/dev/my-project/.mcp.json   → 11種(重複 + claude_code)

変更後

~/.claude.json (mcpServers)  → 9種(唯一の定義箇所、公式準拠)
その他すべて                   → 削除

集約した 9 種の MCP サーバー

# MCP サーバー名 コマンド 用途
1 atlassian-mcp-server npx (mcp-remote) Jira/Confluence 連携
2 awslabs.aws-documentation-mcp-server uvx AWS ドキュメント検索
3 awslabs.cdk-mcp-server uvx AWS CDK 操作支援
4 Context7 npx (@upstash/context7-mcp) ライブラリドキュメント取得
5 aws-cli.mcp-server uvx AWS CLI 操作
6 serena uv (serena-mcp-server) コードナビゲーション
7 github npx (@modelcontextprotocol/server-github) GitHub 操作
8 playwright npx (@playwright/mcp --vision) ブラウザ自動操作
9 Azure MCP Server npx (@azure/mcp) Azure 操作

対策2: claude_code MCP サーバーの完全排除

claude_codeclaude mcp serve)を MCP サーバーとして定義しないこと。これが再帰的プロセス生成の元凶です。

絶対にやってはいけない設定

"claude_code": {
    "command": "claude",
    "args": ["mcp", "serve"],
    "env": {}
}

この設定は Claude Code 自身を MCP サーバーとして再帰起動し、フォークボムに近い状態を引き起こします。

対策3: 孤立プロセスのクリーンアップ用シェル関数

WSL2 のシグナル伝搬問題に備えて、~/.bashrc または ~/.zshrc に以下を追加しておくと安心です。

claude-cleanup() {
  echo "孤立MCPプロセスをクリーンアップ中..."
  local pids=$(ps -eo pid,ppid,args | awk '
    ($2==1 || $2==2033) && $0 ~ /mcp|playwright|context7|uvx|serena|azure/ {print $1}
  ')
  local count=$(echo "$pids" | grep -c '[0-9]')

  if [ "$count" -gt 0 ]; then
    echo "$pids" | xargs kill -9 2>/dev/null
    echo "${count}個の孤立プロセスを終了しました"
  else
    echo "孤立プロセスはありません"
  fi
}

孤立プロセスの確認だけしたい場合:

ps -eo pid,ppid,tty,rss,args | awk '
  $2==1 || $2==2033 {
    if ($0 ~ /mcp|playwright|context7|uvx|serena|azure/) {
      sum+=$4; count++; print
    }
  }
  END {printf "\n孤立プロセス数: %d / 合計メモリ: %.0f MB\n", count, sum/1024}
'

対策の効果

Before / After

指標 対策前 対策後 改善率
メモリ使用量 7.7 GiB 1.8 GiB 77% 削減
孤立 MCP プロセス数 43個 0個 100% 解消
ロードアベレージ 57.93 正常値 大幅改善
1セッションの MCP プロセス数 30〜40個 9個 75% 削減

恒久対策後の定常値

指標
MCP サーバー起動数/セッション 9個(各1インスタンスのみ)
MCP サーバーの合計メモリ 約 1.2 GB
セッション終了後の孤立プロセス 0個
ロードアベレージ 0.75(12コアに対して極めて低負荷)

再発防止チェックリスト

Claude Code で MCP サーバーを利用する際、以下を守れば同じ問題は発生しません。

やってはいけないこと

NG 項目 理由
複数階層に .mcp.json を配置 マージにより同一サーバーが多重起動される
claude_codeclaude mcp serve)を MCP サーバーに定義 再帰的プロセス生成(フォークボム類似)
_amazon-q_disabled 等の非対応サーバーを定義 機能せずリソースだけ消費

やるべきこと

推奨事項 方法
MCP 設定は ~/.claude.json に一元管理 公式ドキュメント準拠のユーザースコープ
起動後に MCP プロセス数を確認 ps aux | grep -E 'mcp|playwright|context7|uvx|serena|azure' | grep -v grep
WSL2 ユーザーは claude-cleanup 関数を用意 シグナル伝搬問題への保険

検証コマンド

Claude Code 再起動後、以下で正常性を確認できます。

# MCP プロセスの確認(各サーバーが1プロセスのみであること)
ps aux | grep -E 'mcp|playwright|context7|uvx|serena|azure' | grep -v grep

# 孤立プロセスの確認(0個であること)
ps -eo pid,ppid,tty,rss,args | awk '
  ($2==1 || $2==2033) && $0 ~ /mcp|playwright|context7|uvx|serena|azure/ {count++}
  END {printf "孤立プロセス数: %d\n", count}
'

補足: なぜ他の PC では発生しなかったか

同じ WSL2 + 類似 MCP 構成の他 PC では再現しませんでした。差異は以下の通りです。

  1. .mcp.json が階層的に重複配置されていない(グローバル1箇所のみ)
  2. claude_code MCP サーバーが定義されていない
  3. 作業ディレクトリが ~/dev/ 直下で、サブディレクトリの .mcp.json がマージ対象にならない

つまり、MCP サーバーを多数使いつつ、複数プロジェクトをサブディレクトリで管理している環境 で発生しやすい問題です。


まとめ

問題 原因 対策
MCP サーバーの多重起動 .mcp.json の多階層重複 ~/.claude.json に一元管理
再帰的プロセス増殖 claude_code MCP サーバー定義 定義を完全排除
セッション終了後のプロセス残留 WSL2 のシグナル伝搬問題 claude-cleanup シェル関数

Claude Code + MCP は非常に強力な組み合わせですが、設定の重複と再帰的定義には要注意です。特に WSL2 環境ではプロセスの孤立化が起きやすいため、定期的なプロセス確認を推奨します。

この記事が同様の問題に直面した方のお役に立てれば幸いです。

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?