
コンテキストが枯渇するのは、ウィンドウが小さいせいだという説明は半分正しくて半分誤解を招きます。
実際に何がウィンドウを圧迫しているかを見ると、もっと具体的な原因が見えてきます。
メモリ永続化ツール(claude-mem など)を試した方もいると思います。
あれは「前のセッションの記憶を次に引き継ぐ」問題を解くアプローチです。
今日の話は別で、 今動いているセッションの中 で溢れるという、もっと即物的な問題です。
OSS の context-mode は、その問題を MCP サーバー + フック + サンドボックスの三層構造で解くツールです。
GitHub で 23,000 超のスターを集めていて、Claude Code・Codex CLI・ChatGPT など 17 のプラットフォームに対応しています。
仕組みを理解して手元で動かせる状態になることをゴールに進めます。
コンテキスト枯渇の本当の原因はツール出力の肥大化にある
Claude Code や Codex CLI で長い作業を続けていると、途中から応答がぼんやりしてくることがあります。
最初に伝えた設計方針を忘れる、同じ確認を繰り返す、そういった症状です。
直感的には「コンテキストウィンドウが小さい」せいだと思いがちですが、何がウィンドウを埋めているかを追うと話が変わってきます。
エージェントが作業中にやることを想像してみてください。
ファイルを読む。ディレクトリを検索する。Web を取得する。MCP サーバーに問い合わせる。
これらのツール呼び出しの生出力が、 そのままコンテキストに積み上がっていく 構造になっています。
たとえば 300KB のソースファイルを一度読むだけで数万トークン近くが消費されます。
grep の検索結果が何百行も返ってくれば、それもそのまま窓に入ります。
MCP サーバーが返す JSON レスポンスも同様です。
複数のファイルを横断しながら作業する長いセッションでは、作業の本筋と関係ない「生の出力」がじわじわと窓を圧迫していきます。
厄介なのは、これが 指示の希釈 として現れることです。
ウィンドウの前半が大量のツール出力で埋まっていると、後半に書いた指示やルールへの注意が分散します。
コンパクションが走ったとき、最初のほうに書いた設計方針が圧縮・切り捨てられる可能性もあります。
メモリ永続化は「次のセッションに引き継ぐ」問題を解くツールです。
今回の問題はそこではなく、 今のセッション内でツール出力をそもそも積ませない 構造をどう作るか、という話です。
context-mode の三層構造:MCP・フック・サンドボックスはどう連携するか
context-mode は三つの構成要素が連携して動きます。
それぞれの役割を一言で言うと、MCPサーバーが「出力の受け口」、PreToolUse フックが「割り込みとルーティング」、サンドボックスが「生データの保管庫」です。
エージェントが read_file を呼んだとき、フックがその呼び出しを横取りして MCP サーバーにルーティングします。
MCP サーバーはファイルを読んで生データをサンドボックス(ローカルストレージ)に保存し、エージェントには要約と参照キーだけを返します。
エージェントが詳細を見たいときは、参照キーを使って必要な範囲だけを引き出します。
生データ全体をコンテキストに展開せずに済む、というのがこの仕組みの肝です。
データの流れを擬似的に整理するとこうなります。
# context-mode なし(生出力がそのままコンテキストへ)
agent
→ read_file("src/main.ts")
← [ファイル内容 315KB = 数万トークンがそのままコンテキストへ積まれる]
# context-mode あり(サンドボックス経由)
agent
→ read_file("src/main.ts") ← PreToolUse フックが割り込む
→ ctx_execute_file("src/main.ts") ← MCP サーバーへルーティング
← { ref: "ctx_abc123", summary: "315行のTypeScript。エクスポートはFooとBar" }
# コンテキストには要約と参照キーだけ(5.4KB 相当)
# 生データはサンドボックスに保管
agent が詳細を見たいとき
→ ctx_batch_execute({ ref: "ctx_abc123", lines: "1-50" })
← [指定した50行だけ取得]
SkillsLLM に掲載されている事例では、315KB が 5.4KB になる約 98% 削減という数字が示されています。
ただしこれは大きなファイルの読み込みが多いセッションの結果です。前提条件は後の節で整理します。
サブエージェントへの対応も面白いポイントです。
Claude Code プラグインとしてインストールすると、Task ツール(サブエージェント)の起動時にも自動でルーティング指示が注入されます。
親エージェントだけでなく子エージェントも同じサンドボックスを使うため、マルチエージェント構成でもコンテキストの肥大化が抑えられます。
17 プラットフォーム対応は、後述するフック設定の command 引数にプラットフォーム名を渡す仕組みで実現されています。
Claude Code・Codex CLI・ChatGPT・Qwen Code・Copilot CLI などが含まれていて、設定ファイルの引数を変えるだけで同じ仕組みが使えます。
インストールと設定:つまずきやすいポイントを先に潰す
Claude Code プラグインとして入れる場合は2行で完結します。
/plugin marketplace add mksglu/claude-context-mode
/plugin install context-mode@claude-context-mode
Claude Code を再起動すると、MCPサーバーとフックが自動で有効になります。
インストール後の設定ファイルには、フックの定義が自動で追加されます。
中身を読めるようにしておくと、問題が起きたときの対処が早くなります。
{
"hooks": {
"PreToolUse": [
{
"matcher": "run_shell_command|read_file|read_many_files|grep_search|web_fetch|agent|mcp__plugin_context-mode_context-mode__ctx_execute|mcp__(?!.*context-mode)",
"hooks": [
{ "type": "command", "command": "context-mode hook claude-code pretooluse" }
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "context-mode hook claude-code posttooluse" }
]
}
],
"SessionStart": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "context-mode hook claude-code sessionstart" }
]
}
],
"PreCompact": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "context-mode hook claude-code precompact" }
]
}
]
}
}
各フィールドの意味をかみ砕きます。
matcher は対象ツールを正規表現で絞り込む設定です。
PreToolUse の matcher が長いのは、read_file・grep_search・web_fetch など出力が大きくなりやすいツールと MCP 呼び出し全般を捕捉しているためです。
context-mode 自身のツール(ctx_execute など)は除外する記述も含まれています。
type と command はフックが呼ぶシェルコマンドです。
context-mode のバイナリにプラットフォーム名とイベント種別を渡す形になっています。
SessionStart や PreCompact はツール呼び出しとは別のライフサイクルイベントで、セッション開始時のサンドボックス初期化やコンパクション前の状態保存に使われます。
ここで 一番ハマりやすい落とし穴 を先に伝えておきます。
フックの command はグローバルインストールの context-mode バイナリを直接呼びます。
グローバルのバージョンが古いと、フックが inert (静かに無効化)されます。
エラーも出ずに「入れたのに効いていない」状態になるため、バージョン確認だけは最初にやっておいてください。
# バージョン確認
context-mode --version
# グローバルを最新に更新
npm install -g context-mode@latest
Claude Code 以外で使う場合は、command のプラットフォーム名引数を変えるだけです。
Qwen Code なら "context-mode hook qwen-code pretooluse"、Copilot CLI なら "context-mode hook copilot-cli pretooluse" になります。
この引数部分だけが変わると理解しておけば、他のプラットフォームへの展開もすぐできます。
トークン削減効果を自分で確認する方法と、効果が出ないケース
インストール後に状況を確認するには、Claude Code のチャットでスラッシュコマンドを実行します。
/context-mode status
現在のセッションでどれだけのデータがサンドボックスに逃がされたか、コンテキストに実際に入ったデータ量との差分が表示されます。
これが ビフォーアフターを比較する最短ルート です。
SkillsLLM に掲載されている事例では、9.6MB の生ツール出力が発生するセッションで 99% がサンドボックスに保持され、約 245 万トークンのコンテキスト消費を回避できた、という数字が示されています。
前提として「9.6MB の生ツール出力が出るほどファイル読み込みが多いセッション」という条件がついています。
正直なところ、これだけの出力が出るセッションはかなり限定的です。
小さなファイルを数個操作するだけの短いセッション、シェルコマンド中心で大きなファイル読み込みがほとんどないセッションでは、サンドボックスに逃がせるデータ量も少なく、劇的な改善は期待しないほうがいいです。
自分の開発スタイルを振り返って「複数の大きなファイルをまたいで長く作業するか」を確認するのが判断の近道です。
当てはまると思ったらインストールして、まずステータスコマンドの数値を見てみる、という順番がおすすめです。
削減率が一桁台であれば、そのプロジェクトでは効果より設定の複雑さのほうが上回る可能性があります。
実運用で気をつけたいトレードオフと「入れるかどうか」の判断
サンドボックスにデータを逃がすということは、エージェントが「見えていない情報」が増えるということでもあります。
この点はきちんと理解しておいたほうがいいです。
たとえば、あるツール呼び出しの結果を後から参照しようとするとき、参照キーが何らかの理由で失われていると、エージェントは情報を取り出せません。
エラーログをそのままコンテキストに残して後で参照したいケースでも、サンドボックス経由だと意識的に引き出しに行く手順が必要です。
「全部見えている状態」に慣れていると、最初は少し違和感があるかもしれません。
デバッグが難しくなる側面も念頭に置いておく必要があります。
生出力がコンテキストに入っていないため、「なぜエージェントがこの判断をしたか」を後から追いにくくなります。
想定と違う挙動が出たとき、サンドボックスのログを直接確認する手順を把握しておくと対処が速くなります。
セキュリティ面については、SkillsLLM の自動スキャン(依存関係の脆弱性チェックとプロンプトインジェクションのヒューリスティクス)で高 severity の問題はなしという結果が出ています。
生データはすべてローカルのサンドボックスに保持され、外部サービスには送信されない設計です。
「入れるかどうか」の判断は、こう整理するとわかりやすいと思います。
- 入れる価値が高い 構成:大きなコードベースを横断する作業が多い、1セッションを長く回す、MCP サーバーを複数同時に使っている、マルチエージェントで動かしている
- 過剰になりやすい 構成:1タスク1セッションで完結させるスタイル、操作するファイルが少ない、シェルコマンドや小さな出力が中心
ツールを積みすぎると、設定の複雑さ自体がデバッグのコストになります。
計測してから判断する、という順番を守るだけで、後悔のない導入ができると思います。
株式会社ホコサキは山口県宇部を拠点に、AI 活用支援や業務システム開発に取り組んでいます。
Claude Code をはじめとした AI コーディングエージェントの実務導入も扱っており、「どのツールをどう組み合わせるか」という判断から一緒に考えられます。
ご相談は お問い合わせページ からどうぞ。

