MCPサーバーの肥大化を防ぎトークン消費と誤爆を抑える実務運用レシピ

MCPサーバーの肥大化を防ぎトークン消費と誤爆を抑える実務運用レシピ

2026/10/23
目次
開閉

VS Code(Cline等のエージェント拡張機能)やAntigravity CLIなどのAIコーディング環境で、Anthropicが策定したオープン標準「Model Context Protocol (MCP)」への対応が急速に進んでいます。

ローカルのファイルシステムやGitHub、社内のPostgreSQLデータベースなどをMCPサーバーとして接続すれば、AIが自律的にコンテキストを取得し、コードの修正や調査を行えるようになります。

しかし、便利だからと手当たり次第にMCPサーバーを登録していくと、現場ではすぐに別の壁に直面します。

「何も質問していないのに、最初の1ターンだけで大量のトークンが消費される」
「単なるコードの相談なのに、AIが関係のない外部ツールを呼び出してエラーになる」

私自身、手元の開発環境(会社支給のMacBook Proと自宅のWindowsノートPC)で複数のMCPサーバーを常用する中で、この「ツールの肥大化による弊害」に悩まされました。

本記事では、MCPが裏側でツールを展開する仕組みとトークン消費の実測データ、現場でハマった通信の落とし穴、そしてトークン浪費と誤爆を抑えるための実践的な運用レシピをまとめます。


ツール肥大化が引き起こす「見えないコスト」の正体

MCPの利便性を享受する一方で、登録サーバーを増やしすぎると日常の開発効率を損なう原因になります。その背景には、MCPクライアントとLLMの間で行われるツール定義のやり取りがあります。

MCPサーバーの構成と思案するエンジニア

1. 毎ターン消費される大量のJSON Schema定義

MCPクライアント(VS Codeの拡張機能やAntigravity CLI、Claude Desktopなど)は、起動時に接続先のMCPサーバーへ tools/list リクエストを送信します。

サーバーから返ってきたツールの名前、説明文、引数の型情報(JSON Schema)は、ユーザーが入力したプロンプトと一緒に、毎ターンのシステムプロンプトとしてLLMへ送信されます。

手元環境で代表的なMCPサーバーのスキーマサイズとトークン消費量を計測した結果が以下です。

MCPサーバー主な提供ツールツール数推定トークン消費量
Filesystemファイル読み書き、一覧取得、移動など約7個約1,100 tokens
PostgreSQLテーブルスキーマ取得、クエリ実行など約4個約800 tokens
GitHubPR作成、コミット取得、Issue検索など約26個約3,800 tokens
Puppeteer / FetchWebページ取得、スクリーンショットなど約5個約950 tokens
Slack / Linearメッセージ送受信、チケット更新など約10個約1,600 tokens

これらをすべてグローバル設定(claude_desktop_config.json 等)に登録していると、合計で約8,200〜10,000トークンものスキーマ情報が、最初の挨拶を交わす前から毎往復のコンテキストに付加されます。

1回の往復で8,000トークン以上の入力が常に課金対象となるだけでなく、モデルが保持できる会話履歴(コンテキストウィンドウ)の上限を大きく圧迫してしまいます。

2. ツールの選択ミス(誤爆)と応答精度の低下

トークン消費以上に実務で厄介なのが、ツールの選択ミス(ハルシネーション)の増加です。

LLMに30個以上のツールを同時に提示すると、プロンプトの意図を解釈する際にツールの役割が競合しやすくなります。

たとえば「この関数のTypeScriptの型定義を修正して」と頼んだだけなのに、AIが余計なWeb検索ツールやGitHubのIssue検索ツールを呼び出そうとして処理が中断する現象が起きます。

AIに持たせるツールは多ければ良いわけではなく、「今取り組んでいるタスクに必要な道具だけを渡す」という絞り込みが欠かせません。


現場でハマった2大落とし穴と検証ログ

MCPサーバーの導入や自作を進める中で、実務上特に遭遇しやすい2つのトラブルがあります。

落とし穴1: stdio通信での console.log 混入によるJSON-RPC破壊

MCPの代表的な通信方式である stdio(標準入出力)では、クライアントとサーバーが改行区切りのJSON-RPC形式で通信します。

自作のMCPサーバーや一部のスクリプトで、接続確認やデバッグのために何気なく標準出力へログを出力してしまうと、通信が即座にクラッシュします。

実際にNode.jsで起動時に console.log を1行差し込んだミニサーバーを作成し、クライアントから初期化リクエスト(initialize)を送った際の検証ログが以下です。

[CLIENT CRITICAL ERROR] JSON-RPC parse failed! Raw message was: "[DEBUG] MCP server starting up and initializing connection pool..."
[CLIENT ERROR DETAILS]: Unexpected token 'D', "[DEBUG] MCP"... is not valid JSON

クライアントは標準出力から流れてくる文字列をすべてJSONとして解釈しようとするため、デバッグ用のテキストが混ざるとパースに失敗し、サーバーとの接続を切断してしまいます。

MCPサーバー内でデバッグログを出力する場合は、必ず**標準エラー出力(STDERR)**へ流す必要があります。Node.jsであれば console.error、Pythonであれば sys.stderr.write や logging モジュールを用います。

落とし穴2: ホームディレクトリ指定による過剰な権限付与

ファイルシステムを操作する @modelcontextprotocol/server-filesystem では、引数としてアクセスを許可するディレクトリパスを渡します。

ここで設定が面倒だからと、ホームディレクトリ全体(~ や C:\Users\username)を渡してしまうケースを見かけます。

この設定を行うと、AIが .ssh/ 配下の秘密鍵や、別プロジェクトの .env ファイル、OSの個人設定ファイルまで自由に探索できる状態になります。プロンプトインジェクションやツールの誤作動が発生した際のリスクが非常に高くなります。

アクセス許可パスは、必ず「作業対象のリポジトリ配下」や「共有ドキュメントフォルダ」に限定して指定します。


トークン浪費と誤爆を防ぐ3つの効率化レシピ

こうした課題を踏まえ、日々の開発環境を快適に保つために実践している3つの運用レシピを紹介します。

レシピ1: グローバル設定をやめ、プロジェクトやプラグイン別にスコープを分離する

すべてのMCPサーバーを単一のグローバル設定ファイルに集約せず、プロジェクトやタスク単位で設定を分離します。

たとえばAntigravity CLIであれば、マシン全体に適用される ~/.gemini/config/mcp_config.json にすべてのサーバーを書くのではなく、プロジェクト固有のプラグイン設定(plugins/<プラグイン名>/mcp_config.json)を活用することで、その機能が必要な時だけMCPツールをロードできます。

VS CodeのClineやRoo Code等の拡張機能でも、ワークスペース固有の設定やプロファイル機能を使い、プロジェクトごとに有効化するサーバーを切り替える運用が効果的です。

{
  "mcpServers": {
    "project-filesystem": {
      "command": "node",
      "args": [
        "./scripts/mcp-filesystem.js",
        "./src",
        "./docs"
      ]
    }
  }
}

Webフロントエンドの開発中にはデータベースやクラウド連携のツールを読み込ませず、DBマイグレーションや管理作業を行うときだけ専用のプロファイルへ切り替える運用にすることで、コンテキストの消費を最小限に抑えられます。

レシピ2: npx -y の都度実行をやめ、ローカル固定または uvx で起動を速くする

MCPの設定例では npx -y @modelcontextprotocol/server-... という記述がよく使われます。

しかし、npx -y はエディタやクライアントが起動するたびにリモートリポジトリへの問い合わせやパッケージ解決を試みるため、起動に数秒のレイテンシが生じる場合があります。また、ネットワーク環境によっては起動エラーを引き起こします。

頻繁に利用するNode.js製サーバーは、ローカルに固定バージョンをインストールして直接起動するか、Python製サーバーであれば uvx を活用するのがおすすめです。

Astral社の高速パッケージマネージャー「uv」が提供する uvx コマンドは、強力なローカルキャッシュと仮想環境の高速生成により、コールドスタート時でも数百ミリ秒でサーバーを立ち上げられます。

{
  "mcpServers": {
    "git": {
      "command": "uvx",
      "args": ["mcp-server-git", "--repository", "."]
    }
  }
}

レシピ3: 最小権限の原則に基づくパスのホワイトリスト化

ファイル操作ツールには、編集対象となる具体的なディレクトリのみを配列で渡します。

Windows環境とmacOS環境の併用では、パスの区切り文字やエスケープの違いに注意が必要です。JSONファイル内では、Windowsのバックスラッシュを \\ と二重にエスケープするか、スラッシュ / 表記に統一して記述します。

{
  "mcpServers": {
    "workspace-fs": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:/Users/username/projects/my-app/src",
        "C:/Users/username/projects/my-app/public"
      ]
    }
  }
}
Lowom 編集長 編集長
TIPS 現場のワンポイント
「AIに多くの道具を持たせるほど賢くなると思いがちですが、実際は逆です。作業机の上に今使う道具だけを並べるように、ツールを3〜5個に絞ったほうが、AIの判断速度も回答の精度も格段に安定します」

設定ファイルの保存場所と管理のポイント

主要なMCPクライアントにおける設定ファイルの配置場所は以下のとおりです。

  • Antigravity CLI / IDE:
    • グローバル設定: ~/.gemini/config/mcp_config.json(Windows: %USERPROFILE%\.gemini\config\mcp_config.json)
    • プラグイン別スコープ: plugins/<プラグイン名>/mcp_config.json
  • VS Code (Cline / Roo Code):
    • 拡張機能の設定画面、またはストレージ設定(cline_mcp_settings.json)
  • Claude Desktop:
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json

設定ファイル内にAPIキーなどのシークレット情報を記述する場合は、平文で直書きせず環境変数(env フィールド)を経由して注入します。

以前紹介したシークレット管理手法と組み合わせることで、リポジトリに設定ファイルをコミットしても機密情報が漏洩しない状態を維持できます。

シークレット管理の具体的なツール選定や使い分けについては、以下の記事で詳しく解説しています。


道具箱は、小さく保つくらいがちょうどいい

新しいプロトコルや便利な連携ツールが登場すると、つい「あれもこれも」と設定ファイルに詰め込みたくなります。私自身、最初は手持ちのMCPツールをすべて有効化しようとして、結果的に無駄なトークンを払い、AIの的外れなツール呼び出しに頭を抱えることになりました。

現実の開発現場でも、作業机の上にすべての工具を山積みにしていると、かえって目当てのレンチを探すのに手間取ります。AIへのツール提供も同じで、今から書くコードに必要なファイルやスキーマだけをそっと手渡すくらいの距離感が、一番テンポよく開発を進められます。

まずは作業対象のリポジトリに合わせて必要なMCPサーバーだけを最小限で立ち上げ、普段触るディレクトリだけをホワイトリストに指定してみる。そうした小さな環境づくりから、ノイズのない身軽なAIとの協業を試してみてください。

Lowom 編集長
この記事を書いた人:Lowom 編集長 現役Webエンジニア

都内IT企業に勤める業界20年のWebエンジニア。業務効率化・自動化スクリプトや快適な開発環境の構築、厳選したツール・ガジェットの活用法など、手元で実際に検証したリアルな一次情報をお届けします。

運営者プロフィール詳細を見る