◉GEMINI LABEN
●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止しました。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止しました。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/開発ツール
⟐ 開発ツール/2026-10-24中級

MCP を足すほど 400 エラーに近づく — Gemini CLI のツール数を、タスクごとの持ち物に絞る

MCP サーバーを足していったら Gemini CLI が 400 で止まる、という報告が出ています。上限の数字は確定していませんが、includeTools でタスクごとに持ち物を決めておけば、原因の切り分けも予防もできます。

Gemini CLI11MCP8includeTools400 エラートラブルシューティング37settings.json3

Issue #24246 を開いたのは、MCP サーバーを 5 つ目まで足した夜でした。タイトルには「128 を超えると 400」とあり、本文には「400 を超える」とあります。同じページの中で数字が食い違っているのです。

最初にお伝えしたいのは、この上限の正体は、私が確認できた範囲では公式ドキュメントに書かれていないということです。Issue は 2026 年 3 月に立ち、私が読んだ時点でも open のまま、エラー本文や再現手順も添えられていませんでした。

それでも、手を打つ価値はあります。数字が確定していなくても、「ツールが増えるほど失敗に近づく」という方向だけは、原因の切り分けに使えるからです。

まず、いま何本載っているかを知る

/mcp を実行すると、サーバーごとの CONNECTED の状態と、読み込まれたツールの一覧が出ます。ここで全部を数えるのは骨が折れます。しかも、includeTools を書いていないサーバーは、そのサーバーが持つツールがすべて載ります。

ドキュメントには、ツール名が mcp_{serverName}_{toolName} の形になり、63 文字を超えると途中が ... で省略されること、同名になった場合は後から登録されたほうが前のものを上書きすることも書かれています。本数が増えるほど、名前の衝突も起きやすくなります。

私は最初、このあたりを読まずに「サーバーを足せば便利になる」とだけ考えて、コード検索、ドキュメント検索、Issue 管理と、思いつくままに登録していました。結果は芳しくありませんでした。何が原因で止まったのか、どのサーバーを外せば直るのかが、分からなくなったのです。いま思えば、足す前に数えておくべきでした。

includeTools で「このタスクの持ち物」を決める

公式ドキュメントでは、includeTools を書くと「そのサーバーから載るのはここに挙げたツールだけ」になり、excludeTools は includeTools より優先される、とされています。両方に同じ名前があれば、除外が勝ちます。

.gemini/settings.json は、たとえば次のようになります。

{
  "mcpServers": {
    "repo": {
      "command": "npx",
      "args": ["-y", "YOUR_REPO_MCP_SERVER"],
      "includeTools": ["search_code", "read_file", "list_commits"],
      "excludeTools": ["delete_branch"]
    },
    "tracker": {
      "httpUrl": "https://example.com/mcp",
      "includeTools": ["get_issue", "add_comment"]
    }
  }
}

このブロックは「何を解決するか」を一言で言えば、読むだけの作業に、書き込みのツールを持ち込まないことです。書き込み系を最初から外しておくと、本数が減るだけでなく、確認ダイアログを押し間違える余地も減ります。

サーバー名にアンダースコアは使わないようにしてください。ドキュメントによると、ポリシーの解析が mcp_ の後の最初のアンダースコアで分割されるためです。my-repo のようにハイフンにしておけば迷いません。

本数を予算にして、設定ファイルのまま数える

/mcp の画面を目で数える代わりに、設定ファイルから数えます。次のスクリプトは、includeTools に書いた本数から excludeTools を引いて合計し、予算を超えたら、あるいは includeTools を書いていないサーバーがあれば、終了コード 1 で知らせます。

#!/usr/bin/env python3
"""settings.json の mcpServers を読み、includeTools の本数を予算と突き合わせる。"""
import json, sys
 
BUDGET = 40  # 手元で決めた上限。公式の上限値ではありません
 
def count(path: str) -> int:
    with open(path, encoding="utf-8") as f:
        servers = json.load(f).get("mcpServers", {})
    total, unknown = 0, []
    for name, cfg in servers.items():
        inc = cfg.get("includeTools")
        if inc is None:
            unknown.append(name)  # includeTools なし = 全ツールが載る
            continue
        n = len([t for t in inc if t not in cfg.get("excludeTools", [])])
        print(f"{name:<20} {n:>3} 本")
        total += n
    for name in unknown:
        print(f"{name:<20} 全部入り(本数不明)")
    print(f"確定分の合計 {total} 本 / 予算 {BUDGET} 本")
    return 1 if (unknown or total > BUDGET) else 0
 
if __name__ == "__main__":
    sys.exit(count(sys.argv[1] if len(sys.argv) > 1 else ".gemini/settings.json"))

このスクリプトは、手元で小さなサンプル設定を渡し、本数の集計と終了コードが想定どおりになることを確かめています。予算の 40 は、公式の数字ではなく、私が自分の作業のために置いた線です。 上限が確定したら、この一行だけ書き換えれば足ります。

「本数不明」を失敗扱いにしているのは、意図的です。includeTools を書いていないサーバーこそ、本数を勝手に増やす張本人になりやすいからです。

タスクごとに設定を差し替える

もう一歩進めて、作業の種類ごとに設定ファイルを分けておきます。たとえば profiles/review.json と profiles/triage.json を用意して、作業を始める前に、プロジェクトの設定へコピーします。

#!/usr/bin/env bash
# 使い方: ./use-profile.sh review
set -euo pipefail
name="${1:?profile 名を指定してください}"
src="profiles/${name}.json"
[ -f "$src" ] || { echo "見つかりません: $src" >&2; exit 2; }
mkdir -p .gemini
cp "$src" .gemini/settings.json
python3 mcp_budget.py .gemini/settings.json

コピーの直後にスクリプトを走らせるので、予算を超える設定は、起動する前に気づけます。「止まってから原因を探す」のではなく、「止まる前に数える」順番に変えるわけです。

なお、セッションの途中で設定を差し替えたあとは、CLI を起動し直してからお試しください。MCP の読み込みが走るのは起動時だからです。起動時のエラーは、既定では表に出ません。MCP issues detected. Run /mcp list for status. という案内が出たら、/mcp list を開くのが先です。

それでも 400 が出たときの順番

予算の中に収まっていて、それでも 400 が返るなら、本数以外を疑います。

  1. /mcp list で、DISCONNECTED のサーバーがないか見ます
  2. 直前に足したサーバーを 1 つずつ mcp.excluded に入れて、再現するか確かめます
  3. 同じ作業を、サーバー 1 つだけの設定で行います
  4. それでも再現するなら、Issue にエラー本文と本数を添えて報告します

同じ「止まる」でも、モデル名の間違いが原因のことがあります。その切り分けは Gemini API で 404 と 429 が同時に出たとき、最初にモデル名を確かめる にまとめました。失敗の種類を型で分けて受け止めたいときは、例外にならない失敗を型で閉じる も参考になります。

Issue #24246 には、まさにエラー本文と再現手順が足りていません。もしお手元で再現した方がいらっしゃれば、本数とモデル名を添えていただければ、次に読む誰かの助けになるはずです。

持ち物は、サーバー単位ではなく作業単位で決めます。 便利そうだから足すのをやめて、今日の作業に要るものだけを持つ——この線引きだけは、これからも守っていくつもりです。

次の一歩として、まず /mcp を開き、includeTools を書いていないサーバーを 1 つだけ選んで、使っているツール名を絞ってみてください。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ 開発ツール2026-10-19
MCP のタイムアウトを 10 分にしたのに 1 分で切れる — 値を決めている層を順に辿る
Gemini CLI で MCP サーバーの timeout を長くしたのに、想定より早く切れる。設定ファイルの層ごとに値を並べ、単位の取り違えや拡張側の上書きを見つける小さなスクリプトと、切り分けの順番を書き残します。
⟐ 開発ツール2026-09-21
つないだ MCP を初めて外した日 — 常時有効にするツールを選ぶ基準
MCP サーバーを足し続けると、API の上限である 512 個の関数宣言に当たる手前で応答の質が落ちます。Gemini CLI の includeTools と excludeTools を使い、常時有効にするツールを選ぶ基準と外し方をまとめます。
⟐ 開発ツール2026-10-20
@config と打ったのに別のファイルが渡っていた? Gemini CLI の @ 参照が曖昧一致を黙って拾う件の確かめ方
Gemini CLI の @ 参照で、名前が曖昧なときに最初の一致だけが使われるという報告を読み、同名ファイルが複数ある場所で事故を防ぐために行った点検の手順を、小さな Python スクリプトと一緒に整理しました。