/context 1発で分かる問題
新しいClaude Codeセッションを開いて「hi」と入力したあと /context を実行してみてください。ガッツリ使い込んでる構成(MCPサーバー22個以上、スキル150個以上、プラグイン半ダース)だと、ライブウィンドウはこんな具合になります:
Context Usage — Opus 4.7 16.8k / 200k tokens (8%) Estimated usage by category - System prompt: 2.8k (1.4%) - System tools: 2k (1.0%) - Custom agents: 1.4k (0.7%) - Memory files: 2.2k (1.1%) - Skills: 8.3k (4.2%) ← 操作可能な最大の項目 - Messages: 13 tokens - Free space: 150.2k (75.1%) - Autocompact buffer: 33k (16.5%) ← 予約領域、ハードコード MCP tools · /mcp (loaded on-demand) ← 上記には含まれない
入力する前に常駐しているのは実質約16.8Kだけで、そのほとんどは動かしようがありません(システムプロンプト、組み込みの非遅延ツール、回収不能な33KのAutocompact予約)。22個以上のMCPサーバーと組み込みの遅延ツールは、このライブの数値にはまったく乗っていません。Tool Searchはツールの名前だけをリストアップして、スキーマは必要な時にだけフェッチします。だから別途「loaded on-demand」のバケツに収まっていて、ウィンドウの中には居ないわけです。
実際に削れる中で一番大きいのはSkillsです。
Resident vs. Deferred — 実際にロードされるもの
起動時のペイロードは、固定のシステムプロンプトに加えて動的に発見される複数のリソースの合計です。旧版の説明が落としていたポイント: Tool Searchはそのペイロードを2つのバケツに分けます。公式MCPドキュメントもこうはっきり書いています — "Tool search is enabled by default. MCP tools are deferred rather than loaded into context upfront."
- Resident(常駐) — セッションが開いた瞬間からライブウィンドウに計上される。
- Deferred(遅延) — 発見されて名前はリストされるが、完全な定義はオンデマンドでフェッチ。ライブウィンドウには計上されない。
flowchart TB
Start([Claude Codeセッション開始]) --> R[Resident<br/>ライブウィンドウ内]
Start --> D[Deferred<br/>Tool Searchがオンデマンドでフェッチ]
R --> SP[システムプロンプト 約3K · 固定]
R --> BT[組み込みの非遅延ツール 約2K · 固定<br/>Read/Edit/Bash/Glob/Grep/Skill/ToolSearch]
R --> SKL[Skillsリスト<br/>SKILL.mdごとのname + description]
R --> MEM[メモリ · CLAUDE.md + MEMORY.md]
R --> AGT[カスタムエージェント · ~/.claude/agents/]
R --> MCPI[MCPサーバーinstructions<br/>遅延されない — issue #48680]
R --> AC[Autocompact予約 33K · ハードコード]
D --> MCPT[MCPツール定義<br/>全サーバー + claude.aiコネクタ]
D --> BTD[組み込み遅延ツール<br/>WebFetch/WebSearch/Cron*/Notebook*]
classDef control fill:#ffe0e0,stroke:#cc3333,stroke-width:2px,color:#000
classDef free fill:#d4f8d4,stroke:#2e7d32,color:#000
class SKL,MCPI control
class MCPT,BTD free
赤いノードが手をつける価値のある常駐コストです: Skillsリスト と MCPサーバーinstructions。緑のノード — MCPツール定義(巨大なclaude.aiコネクタカタログも含む)と組み込みの遅延ツール — はTool Searchのおかげで帳簿から落ちています。それ以外は固定(システムプロンプト、組み込みツール、autocompactバッファ)か影響が小さい(メモリ、エージェント)ものです。
公式ドキュメントによる各ローダーの説明場所
| ローダー | 挙動 | ソース |
|---|---|---|
| Tool Search | ツール定義(MCP + 組み込み)を遅延させ、オンデマンドでフェッチ。結果ライブウィンドウから消える — 常駐の合計値が小さい理由 | Claude Code MCPドキュメント, Tool Search SDK, APIリファレンス |
| MCPツール定義 | 他のツールと同じくTool Searchで遅延: 名前はリスト、スキーマはオンデマンドでフェッチ | Claude Code MCPドキュメント |
| MCPサーバーinstructions | 接続された各サーバーはinstructions文字列を寄与する — 遅延されず常駐、サーバーあたり2KB上限。次セクションでメカニズムと計測方法を解きほぐす。 | Claude Code MCPドキュメント, Issue #48680 |
| claude.aiコネクタ | Pro/Maxサインインでアカウントコネクタ(Gmail、Linear、Notion…)が使えるようになる。ツール定義は他と同じく遅延されるので、常駐するのは2KB以下のinstructionsだけ — CLIでは ENABLE_CLAUDEAI_MCP_SERVERS=false で無効化 |
Claude Code MCPドキュメント, Issue #50062 |
| Skills | 各 SKILL.md のフロントマター(name + description)が連結されてリストになり、システムプロンプトに常駐で含まれる — 操作可能な最大の1行 |
Claude Code Skills, agentskills.io spec |
| Skill発見パス | 4箇所をスキャン: ~/.<client>/skills/、~/.agents/skills/、およびプロジェクトレベル相当 |
Agent Skills client implementation |
| プラグイン | マーケットプレースプラグインはhooks/agents/skills/commandsを plugins/cache/ に配置する。プラグインのスキルは skillOverrides で制御不可 |
Pluginドキュメント, Skills overrideノート |
| Autocompactバッファ | ウィンドウの先頭に33K予約。環境変数オーバーライドはトリガー閾値をずらすだけで、予約サイズ自体は変わらない | Issue #12053, Issue #31806 |
初期の地ならしをしてくれた2つのコミュニティ記事: Scott Spence氏のOptimising MCP Server Context Usage と atcyrus氏のMCP Tool Search Context Pollution Guide。ただし時代背景に注意してください。彼らの派手なbefore/after数字は、まだTool Searchが遅延してくれない頃のものです。彼らが解説したメカニズムは今でも重要 — ただし今は60Kのツールスキーマの壁ではなく、残りのinstructionsコストに対して効いてきます。そしてその残りのコストは見た目以上に捉えどころがない — /context 自体にその行がないのです。
なぜMCP instructionsは /context に出てこないのか
MCPサーバーを20個以上繋いだセッションで /context を実行してinstructionsコストを探しても、行は見つかりません。目の錯覚ではなく — /context 自体にそのカテゴリがないのです。固定の8バケツのタクソノミ(System prompt、System tools、MCP tools、MCP tools (deferred)、Custom agents、Memory files、Skills、Messages)から表示を組み立てて、それぞれを名前付きの行として出力する作りになっています。「MCP instructions」行は無いし、これまでもありませんでした。
ではどこにあるのかというと、セッション開始時にClaude Codeは、接続された各サーバーのinstructions文字列を1つの # MCP Server Instructions ブロックにまとめて発行します — トランスクリプトでは <system-reminder> としてインラインに見えるやつで、内部の mcp_instructions_delta チャネル経由で流れてきます(チャネル名はv2.1.153のバンドル内部で確認済み)。このブロックは静的なシステムプロンプトの一部ではなくメッセージ添付として届けられ、isMeta: true フラグが立てられています。これを拾うべき2つのカウンタがどちらもスキップします:
- 「System prompt」バケツは静的なシステムプロンプトのセクションだけをカウント — メッセージストリーム添付は素通り。
- 「Messages」カウンタは
isMetaブロックを明示的にスキップ。
これが計測上の死角です。最初の実ターンが走る前は、/context の合計値は可視バケツの合計です。どちらのバケツもMCP instructionsをカウントしないので、合計はライブコンテキストをちょうどその分過小評価します。最初の実ターン後はヘッドラインがAPIの実トークン使用量(input + cache reads)に切り替わり、その分を黙って取り込みます — それでも明細行はやっぱり無し。
なので自分で測ることになります:
| 知りたいもの | やり方 |
|---|---|
| 生のinstructionsテキスト | セッションJSONLを ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl で開き、本文が # MCP Server Instructions で始まる添付を探す |
| 実際の常駐コスト(差分) | サーバーを繋いだ状態で実ターンを1回流して /context、次にサーバーを切って(コネクタなら ENABLE_CLAUDEAI_MCP_SERVERS=false、それ以外は .mcp.json から削除)もう1回 /context。ヘッドラインの差分がコスト |
| 1ペイロードのコスト | JSONLからテキストをコピーして /v1/messages/count_tokens に system ブロックとして貼り付ける — Claude Codeが内部で /context の明細行を出すのと同じエンドポイント |
| 上限 | 各サーバーのinstructions文字列は2048 UTF-16文字で切り詰められる。常駐合計は ≤ N × 2KB |
両方とも — 8バケツのタクソノミと isMeta スキップ — v2.1.153のバンドルで検証できます: strings ~/.local/share/claude/versions/2.1.153 | grep -E 'mcp_instructions_delta|getMcpInstructionsDeltaAttachment' を叩けば、チャネル名と注入を行うgetterが返ってきます。
3つのレバー
flowchart LR
A[常駐コンテキスト] --> L1[Lever 1<br/>Skills]
A --> L2[Lever 2<br/>プラグイン → ローカルスキル]
A --> L3[Lever 3<br/>MCP instructions]
L1 --> R1[skillOverrides name-only<br/>+ maxSkillDescriptionChars 0]
L2 --> R2[使う資産を ~/.claude/ に昇格<br/>プラグインを無効化]
L3 --> R3[ENABLE_CLAUDEAI_MCP_SERVERS false<br/>+ 冗長で使わないサーバーを無効化]
R1 --> S1[最大の効果<br/>スキル数に応じてスケール]
R2 --> S2[プラグインごとに1〜3K<br/>+ skillOverridesの届く範囲を回復]
R3 --> S3[常駐instructionsを削る<br/>コネクタの定義は既に遅延済み]
各レバーは常駐の発見パスを狙います — 最初のプロンプトが処理される前にローダーがライブウィンドウに抱え込んでいるもの。効果が大きい順に並んでいます: Skills が現状一番動かせる行なので1番目、MCP は Tool Search が既にほとんど仕事をやってくれているので最後。
Lever 1 · Skills — skillOverrides を正しく使う
Skillsバケットに何が入っているか
起動時に発見される各 SKILL.md は、name(数トークン)と description(maxSkillDescriptionChars まで、デフォルト1536)をシステムプロンプトのスキルリストに寄与します。これは常駐 — 遅延しません。150個のスキル全部フルdescriptionだと15Kトークンを軽く超え、上の /context の8.3Kはすでに最適化後の数字です。ここから手をつけます。
4つの状態 (2026年5月修正)
skillOverrides はスキル単位のオブジェクトで、ディレクトリ名がキーになります。以前自分のリサーチノートで公開していた推奨設定で文字列形式 ("skillOverrides": "user-invocable-only") を使っていましたが、これはJSONスキーマ検証で弾かれます。オブジェクト形式しかサポートされていません。
以下のstate図は、4つの正当な値と、コストを段階的に下げていく遷移をまとめたものです: デフォルトの on 状態、2つのコスト削減状態(name-only は自動呼び出しを維持、user-invocable-only は明示的スラッシュ呼び出しを要求)、そして完全に隠す off 状態。
stateDiagram-v2
[*] --> on
on: on (default), 名前と説明をロード、自動・スラッシュ呼び出し可能
state "Cost reduced" as Reduced {
nameonly: name-only, 名前のみ、名前から自動呼び出し可、スラッシュ呼び出し可
userinv: user-invocable-only, 名前のみ、自動呼び出し不可、スラッシュ呼び出し可
}
state "Hidden" as Hid {
off: off, どこにもロードされない、呼び出し不可
}
on --> nameonly: descriptionロードを削減
on --> userinv: スラッシュ名のみに固定
on --> off: 完全に隠す
nameonly --> userinv: 自動呼び出しを停止
userinv --> off: 完全に隠す
2つのコスト削減値の決定的な違いは自動呼び出しです。user-invocable-only は名前通りのことしかやりません — スキルは /skill-name 経由でしか辿りつけません。自動呼び出しはオフなので、タスクが自然にそのスキルを呼ぶような場合でもモデルは自発的に手を伸ばしません。name-only はリストに名前を残しつつ、自動呼び出しも生かしておきます。だから、タスクが必要とすればモデルが自分でロードして実行できます。
その差が、自分が全部 name-only を選んだ理由です。自分のフローの多くは /goal "do X" 形式の自然言語指示で、モデル(あるいは産み出されたサブエージェント)が「あ、これは qa-team スキルの出番だな」と気づいて、スラッシュコマンドを打たなくてもロードしてくれる必要があります。user-invocable-only だとそれを殺してしまうので、スキル名を全部覚えて打つはめになります。user-invocable-only は明示呼び出しでゲートしたい稀なスキル用に取っておくつもりですが、実際のところ今はそのバケツは空です。
セットアップ
# ローカルで発見できる全スキルにname-onlyを適用
SKILLS=$(find ~/.claude/skills ~/.agents/skills -maxdepth 2 -name "SKILL.md" 2>/dev/null \
| sed 's|.*/skills/||; s|/SKILL.md$||' | sort -u)
OVERRIDES=$(echo "$SKILLS" | jq -R . | jq -s 'map({(.): "name-only"}) | add')
jq --argjson o "$OVERRIDES" '
.skillOverrides = $o |
.maxSkillDescriptionChars = 0 |
.skillListingBudgetFraction = 0.005
' ~/.claude/settings.json > /tmp/s.json && mv /tmp/s.json ~/.claude/settings.json
3つの設定、3つの目的:
| 設定 | デフォルト | 自分の値 | 理由 |
|---|---|---|---|
skillOverrides |
{} |
{ <every-skill>: "name-only" } |
descriptionを落とし、自動/サブエージェント呼び出しは残す |
maxSkillDescriptionChars |
1536 |
0 |
descriptionを完全にドロップ — 名前だけ残る。オーバーライドし忘れたスキル用のハードな安全網 |
skillListingBudgetFraction |
0.01 |
0.005 |
スキルリストがウィンドウのどれだけを消費できるかの上限 |
編集後はClaude Codeを完全に再起動してください — スキルリストは現在のセッションでキャッシュされます。/context で Skills 行を確認しましょう。
注意点
- プラグインのスキルは
skillOverridesの影響を受けない。 これがLever 2の存在理由です。 - ビルドバージョンが大事。
skillOverridesはv2.1.129まで壊れていました — 旧ビルドでは常にonを返すスタブでした (Issue #50631)。claude --versionで確認を。(skillOverridesが組み込みスキルにも届くかは未確定です。これらを無効化したい機能リクエスト Issue #26838 はduplicateでクローズされました)。 - フロントマター側の
disable-model-invocation: trueとuser-invocable: falseも同じことをやってくれますが、一括適用ならskillOverridesの方が早いです。
Lever 2 · プラグイン → ローカルスキル
マーケットプレースプラグインは便利ですが、hooks/agents/skills/commandsをまとめてバンドルで配信します。プラグインに含まれるスキルは ~/.claude/plugins/cache/.../skills/ に置かれ — 公式ドキュメント通り — skillOverrides で黙らせることができません。なので、自動呼び出ししないお喋りなスキル5個をプラグインが含んでいる場合、何をしようがその5個のdescriptionが毎セッション常駐で読み込まれます。
回避策は、実際に使うパーツをユーザー空間に昇格させてから、プラグインを無効化することです。
flowchart LR
PC[plugins/cache/foo/]:::plug --> S1[skills/*]
PC --> A1[agents/*]
PC --> H1[hooks/*]
PC --> C1[commands/*]
S1 -- cp -r --> US[~/.claude/skills/foo-*]:::user
A1 -- cp -r --> UA[~/.claude/agents/foo-*]:::user
H1 -.使わなければskip.-> X((✕))
C1 -.使わなければskip.-> X
PD[settings.json<br/>enabledPlugins.foo = false]:::cfg --> Disable[プラグイン無効化<br/>キャッシュロード停止]
classDef plug fill:#fff3cd,stroke:#c79100,color:#000
classDef user fill:#d4f8d4,stroke:#2e7d32,color:#000
classDef cfg fill:#e3f2fd,stroke:#1565c0,color:#000
手順
- プラグインが何を含んでいるか確かめる。 各プラグインのキャッシュディレクトリは、ソースの
skills/、agents/、hooks/、commands/をそのままミラーしたものです。
ls ~/.claude/plugins/cache/<plugin>@<marketplace>/
- 使うものだけユーザー空間にコピーする。
cp -r ~/.claude/plugins/cache/codex@openai-codex/skills/codex-cli-runtime \
~/.claude/skills/
cp -r ~/.claude/plugins/cache/coderabbit@claude-plugins-official/agents/code-reviewer \
~/.claude/agents/
プラグインを無効化する。
~/.claude/settings.jsonのenabledPluginsからそのキーを削除するか、claude plugin uninstall <plugin>@<marketplace>を実行します。ローカル化したスキルを
skillOverridesに追加。 もうユーザースキルなので、Lever 1が効きます。状況に応じてname-onlyまたはuser-invocable-onlyを。プラグインが更新されたら、再コピーが必要です。 トレードオフは承知の上です: 自動更新を捨てて、
skillOverridesの制御権と低いsteady-stateコンテキストコストを取る、ということ。たまにしか使わないプラグインなら、このトレードは引き合います。
最近ローカル化したもの
| プラグイン | 残したもの | 無効化 | 回収トークン |
|---|---|---|---|
codex@openai-codex |
codex-rescue エージェント、codex-cli-runtime / codex-result-handling / gpt-5-4-prompting スキル |
yes | 約1.4K (加えて skillOverrides のリーチ回復) |
coderabbit@claude-plugins-official |
code-reviewer エージェント、autofix / code-review スキル |
yes | 約1K |
figma@claude-plugins-official |
グローバルでは何も — zumen-fe プロジェクト内でのみ .claude/settings.local.json で有効化 |
yes (ユーザーレベル) | 約1.4K |
claude-md-management@claude-plugins-official |
何も — 使わなかった | yes | 小 |
figmaのケースには触れておきたい4つ目のパターンがあります: プラグインを1プロジェクトにスコープする。ユーザーレベルで無効化し、単一プロジェクトの .claude/settings.local.json で再有効化:
{ "enabledPlugins": { "figma@claude-plugins-official": true } }
そのプロジェクトに cd した時だけプロジェクトがロードされます。
Lever 3 · MCP — Tool Searchが遅延できないものを削る
ここは旧版が真逆のことを書いていたレバーです。現行のClaude Codeでは、MCPツール定義はTool Searchが遅延してくれます — ライブウィンドウには乗りません。公式ドキュメントもはっきり書いています: "Tool search is enabled by default. MCP tools are deferred rather than loaded into context upfront." 旧版の「claude.aiコネクタをブロックして約100K節約」というアドバイスは、本物の遅延が入る前の時代の話でした (Issue #50062、completedでクローズ済み)。今はコネクタのツール定義も他と同じく遅延します。本当に常駐するコストとして残るのは2つ:
- MCPサーバーinstructions。 接続された各サーバーは、いつ自分に手を伸ばすべきかをモデルに伝えるinstructions文字列を載せられる — 計測の死角セクションで定量化した残余コスト。遅延されず (Issue #48680)、サーバーあたり2KBの上限 (Claude Code MCPドキュメント)。冗長なサーバー(Serenaの操作ガイド、DeepWikiのツールカタログ)は毎セッションその予算を使い切ります。
- そもそも遅延しない設定。 Tool SearchはVertex AIではデフォルトでオフ、
ANTHROPIC_BASE_URLがファーストパーティ以外のプロキシを指す時もオフ。ENABLE_TOOL_SEARCH=falseだと全ての定義がウィンドウに戻ります。(HTTP/Streamableツールが全く遅延しないという以前のレポート Issue #40314 はnot-plannedでクローズされ、現行ドキュメントはHTTPツールも他と同じく遅延すると確認しています。)
なのでこのレバーの守備範囲は今や狭い: instructionsが要らないサーバーを無効にして、そして — サブスクで認証するなら — claude.aiコネクタをCLIから外す。
claude.aiコネクタを無効化する (メインのレバー)
コネクタはサブスクリプション経由で届くもので、claude mcp add 経由ではありません。Web上の claude.ai/customize/connectors で追加して(Gmail、Linear、Notion、Google Drive、Google Calendar、Exa、Figma…; TeamとEnterpriseプランでは admin だけが追加可能)、同じClaude.aiアカウントでClaude Codeにサインインすれば自動的に使えるようになります — マシンごとに claude mcp add する必要はありません。 MCP config precedence では最後に位置し(local、project、user、plugin servers の後)、自分のサーバーとはエンドポイントでマッチされ、/mcp ではClaude.ai由来としてフラグが立ちます。アクティブな認証がClaude.aiサブスクリプションの時だけフェッチされます — ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN、Bedrock、Vertexの下では絶対にフェッチされません。
Tool Searchがあればコネクタのツール定義は遅延しますが、instructionsと名前リストは常駐で同乗してきます。v2.1.63 からは、ドキュメント化された純正のスイッチがあり、CLIから完全に外せます — false にセット:
ENABLE_CLAUDEAI_MCP_SERVERS=false claude
恒久化するには settings.json の env ブロックに入れましょう(下記参照)。これが正規のopt-outリクエスト #50062 が追っていたスイッチで、env varがshipした時点でcompletedとしてクローズされました。並行する別のトグルリクエスト #44112、#47881、#56773 はすべてnot-plannedでクローズ。#20412 は「自動注入が非力なマシンをOOMさせる」という広めの懸念でまだOPENです。コネクタはclaude.aiとClaude Desktopでは引き続き使えます — 無視するのはClaude Codeだけです。
1枚の図で対比 — デフォルト挙動はコネクタinstructionsを常駐させ、ENABLE_CLAUDEAI_MCP_SERVERS=false はコネクタを完全にスキップ:
%%{init: {'themeVariables': {'signalColor': '#1a1a1a', 'signalTextColor': '#1a1a1a', 'noteTextColor': '#1a1a1a', 'noteBkgColor': '#f8f8f8', 'noteBorderColor': '#666'}}}%%
sequenceDiagram
autonumber
participant CLI as claude (起動)
participant Auth as Claude.ai認証
participant Local as ~/.claude.json
participant CTX as ライブコンテキスト
rect rgb(255, 230, 230)
Note over CLI,CTX: デフォルト + Tool Search
CLI->>Auth: サブスクトークン
Auth-->>CLI: アカウントコネクタ一覧
CLI->>Local: mcpServersを読み込み
CLI->>CTX: ツール定義は遅延 · instructionsは保持
Note over CTX: スキーマはオンデマンド、<br/>コネクタinstructionsは常駐
end
rect rgb(230, 255, 230)
Note over CLI,CTX: ENABLE_CLAUDEAI_MCP_SERVERS=false (v2.1.63)
CLI->>Local: 自分のサーバーのみ読み込み
CLI->>CTX: コネクタは完全にスキップ
Note over CTX: コネクタツール無し、<br/>コネクタinstructions無し
end
なぜinstructionsレベルのトグルが無いのか
上のコネクタスイッチがinstructionsを落とせるのは、サーバーの接続自体を切る副作用としてです — Claude Codeが接続を開かないので initialize レスポンスが来ず、何も注入されない。サーバーのツールは保ちつつinstructionsだけを落とす、という純正のスイッチは存在しません。バンドル (v2.1.153) でもそのギャップが確認できます: 常駐ブロックを組み立てる関数は無条件です。接続されたサーバーのMCP initialize 結果に空でない instructions フィールドがあれば、その文字列はそのまま追加されます。env var、setting、flagはどれも参照されません。
この欠落は、姉妹機能にはトグルが付いているので目立ちます。Skillsにはリストを省略するためのターン単位 suppressNextSkillListing フラグがあり、git関連ガイダンスにはブロック全体をスキップする CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS env varがあります。MCPサーバーinstructionsには同等品が来たことが無く、#48680 は結果のコストに対してオープンですが、フレーミングは抑制トグルではなく遅延を中心にしたものです。
冗長なサーバーのinstructionsには耐えられないがツールは使いたい、という場合、唯一の手段はサーバー側です: サーバーの initialize レスポンスを編集して instructions を省略する。自分の所有でないサーバーなら、レスポンスを途中で書き換える小さなMCPプロキシが唯一の機械的な選択肢です — 文書化も非サポートもされていないので、両端を自分で制御している時にだけ載せる前提で扱いましょう。
何がinstructionsコストをカットしないか
| 設定 / 挙動 | なぜ効かないか |
|---|---|
ENABLE_TOOL_SEARCH=true (デフォルト) |
ツールスキーマだけを遅延 — instructionsチャネルは切り離されていて影響なし |
| サーバーあたり2KB上限 | ダメージは上限内に収まる; ゼロにはならない。N サーバーで最大 N × 2KB 常駐 |
サーバーのツールに permissions.deny |
ツール呼び出しをブロック; instructionsは接続時に既に注入済み |
--mcp-config <file> 単体 |
加算的 — デフォルトソースが既にロードしたものに追加されるだけ。スコープするには --strict-mcp-config とペア |
Transport / alwaysLoad / プラグイン同梱サーバー |
これらのどれも initialize instructionsが注入されるかどうかには関係しない |
Tool Searchはオンのままで
このレバー全体は、Tool Searchが遅延をやってくれている前提です — そしてデフォルトでオン。ただ、ENABLE_TOOL_SEARCH が false にされたり、auto モードが閾値を超えても起動に失敗したり (Issue #18370) すると、全てのMCPツール定義がライブウィンドウに戻ってきて、旧来の60Kの壁を眺めることになります。true を明示的にセットして(下記の設定ブロック参照)、/context でMCPサーバーが「loaded on-demand」の下に表示されていて、トークン行ではないことを確認しましょう。
現在の settings.json (削減後)
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "env": { "ENABLE_TOOL_SEARCH": "true", "ENABLE_CLAUDEAI_MCP_SERVERS": "false", "CLAUDE_CODE_ENABLE_TELEMETRY": "0", "MAX_MCP_OUTPUT_TOKENS": "200000", "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1", "CLAUDE_CODE_DISABLE_1M_CONTEXT": "1", "CLAUDE_CODE_EFFORT_LEVEL": "max" }, "skillOverrides": { "<every-skill-name>": "name-only" }, "maxSkillDescriptionChars": 0, "skillListingBudgetFraction": 0.005, "enabledPlugins": { "figma@claude-plugins-official": false, "codex@openai-codex": false, "coderabbit@claude-plugins-official": false, "claude-md-management@claude-plugins-official": false } }
このセットアップを支えるのは2つのenv varです。ENABLE_TOOL_SEARCH: "true" が肝心 — MCPと組み込みツール定義をライブウィンドウから遅延させてくれます。ENABLE_CLAUDEAI_MCP_SERVERS: "false" はサブスクコネクタをCLIから外します。CLIを1つの明示的なサーバーファイルにピンしたい時だけ、--strict-mcp-config フラグを追加してください。
検証
flowchart TD
Start([settings.json を編集]) --> Restart[Claude Codeを<br/>完全に再起動]
Restart --> Ctx{/context}
Ctx -->|Skills 行 減った?| Y1[Lever 1 効いてる]
Ctx -->|Plugins 行 減った?| Y2[Lever 2 効いてる]
Ctx -->|MCP は loaded on-demand 表示?| Y3[Lever 3 効いてる]
Y1 --> Done([完了])
Y2 --> Done
Y3 --> Done
Ctx -->|Skills 変わらず| Debug1[claude --version 確認<br/>≥ v2.1.129、再起動]
Ctx -->|MCP がトークン行| Debug2[Tool Search オフ —<br/>ENABLE_TOOL_SEARCH=true をセット]
Debug1 --> Done
Debug2 --> Done
具体的には:
# 1. コンテキストの内訳を確認 — MCPは「loaded on-demand」であってトークン行ではないはず /context # 2. Skills行がまだ大きい場合 claude --version # v2.1.129以上である必要あり jq '.skillOverrides | length' ~/.claude/settings.json # スキル数と一致するはず # 3. claude.aiコネクタが消え、自分のサーバーだけが残っているか確認 /mcp # 4. プラグインが無効か確認 jq '.enabledPlugins' ~/.claude/settings.json
注視すべき既知バグ
| Issue | ステータス | なぜ重要か |
|---|---|---|
| #48680 | OPEN | MCP サーバーinstructions はTool Searchで遅延されない — 計測の死角セクションで定量化し、Lever 3がターゲットにする残余コスト。純正の抑制トグルなし。Lever 3のなぜinstructionsレベルのトグルが無いのかを参照 |
| #40314 | CLOSED · not-planned | HTTP/Streamable MCPツールが遅延しなかった(120K前掲)と報告; not-plannedでクローズされ、現行ドキュメントはHTTPツールもTool Searchで遅延と確認 — 自分のトランスポートで /mcp と /context を見て確認 |
| #54716 | OPEN | 組み込み遅延ツールにはまだopt-outなし — 遅延されている間は無害だが追っておく価値はあり |
| #41809 | CLOSED · not-planned | 無効化したMCPサーバーが以前は遅延リストに残っていた — 無効化後に確認 |
| #12053, #31806 | CLOSED · not-planned / duplicate | Autocompactバッファ (約33K) はハードコード; CLAUDE_AUTOCOMPACT_PCT_OVERRIDE はトリガー閾値をずらすが予約は解放できず、閾値をデフォルト以上には上げられない |
| #50631 | v2.1.129で修正 | skillOverrides は旧ビルドではno-op(常に on を返すスタブ)だった — 計測前にアップグレードしたか確認を |
| #50062 COMPLETED · #44112 / #47881 / #56773 not-planned · #20412 OPEN | 混在 | クライアント単位のコネクタトグルが ENABLE_CLAUDEAI_MCP_SERVERS=false (v2.1.63) としてship: 正規リクエスト #50062 はcompletedでクローズ、重複トグルリクエストはnot-plannedでクローズ、#20412 は非力マシンOOM観点でOPENのまま |
| #18370 | OPEN | Tool Search auto モードが閾値を超えても起動失敗することがある — ENABLE_TOOL_SEARCH=true を明示的にセットしないと遅延が黙って止まる |
より深いところを言えば: 遅延は土台になっているアーキテクチャで、ちゃんと動いています。残っているのはほとんど周りのリークパス — 遅延しないinstructions、たまに起動に失敗するモード。修正は「遅延を切る」ことではなく、「遅延がリークする余地を残さない」こと、そして遅延が設計上カバーしようとしなかった少数のものを削っていくことです。それが3つのレバーが達成することそのものです。
採用しなかったもの
検討して却下したオプションをいくつか:
ANTHROPIC_API_KEY認証に切り替える。 APIキー(およびBedrock/Vertex)セッションは、claude.aiコネクタをそもそも取りに行きません。とはいえそのためだけに認証を変える必要はありません:ENABLE_CLAUDEAI_MCP_SERVERS=falseならMaxプランの請求はそのままにコネクタだけ外せます。~/.claude.jsonのcachedGrowthBookFeatures.tengu_claudeai_mcp_connectorsを編集する。 サーバーが次のハンドシェイクで上書きします — #44112 参照。ドキュメント化されたenv varを使いましょう。- 全スキルを
offにする。 クリーンな/context出力には魅力的ですが、自動発見を全部失います。スキル名を全部覚えて打つ羽目になります。name-onlyの方が無難なデフォルトです。 - Autocompactを無効化する。 構造的にハードコードされています。
CLAUDE_AUTOCOMPACT_PCT_OVERRIDEがトリガーを遅らせるだけで、予約は解放しません。
参考文献
公式ドキュメント
- Claude Code Settings
- Claude Code MCP
- Claude Code Skills
- Claude Code Plugins
- Claude Code Changelog
- Agent SDK · Tool Search
- Tool Search API リファレンス
- Agent Skills spec — discovery paths
- Anthropic Engineering — Advanced tool use
この記事の元ネタになったコミュニティ記事
- Scott Spence — Optimising MCP Server Context Usage in Claude Code
- atcyrus — MCP Tool Search Context Pollution Guide
- Paddo — MCP Context Isolation via Slash Commands
- candede — Solving MCP Context Bloat
- Joe Njenga — Cutting MCP context bloat with Tool Search
言及したツール
- agent skills CLI — クロスクライアントスキルインストール用
npx skills
この演習をやって違うコスト分布になった人がいたら、ぜひ聞いてみたいです — リークパスはClaude Codeのリリースごとにシフトするし、次の6ヶ月のchangelogエントリでどのレバーが一番効くかは変わっていくはずです。
原文: Cutting Claude Code's Initial Context Bloat — Skills, Plugins, and MCP Tactics (Ryota Murakami, 2026-05-21)