MCP 本番デプロイの地雷マップ:86% の MCP Server がまだ Localhost に閉じ込められている理由
ローカルで stdio を使って MCP server を動かすと、Claude は完璧にツールを呼び出し、結果を返す。すべてがスムーズに動くので「デプロイは環境を変えるだけ」だと思ってしまう。そしてクラウドに push すると、Docker コンテナは起動 3 秒で exit、Kubernetes デプロイはランダムに失敗、エージェントはタスクを忘れて「暴走」し始める——これが MCP 本番デプロイの現実だ。
私たちはエージェントフリートのデプロイテストでこれらの落とし穴を踏んできた。この記事は私たちが整理した「本番デプロイの地雷マップ」——トランスポート層、認証、トークン消費からセッション分離まで、localhost から production までのすべての断裂点を解析する。
TL;DR
- stdio トランスポートは本番に不適:20 同時接続で 91% のリクエストが失敗(20/22、Apigene 業界分析)。本番環境の唯一の正解は Streamable HTTP(SSE は 2025-11-25 仕様で廃止済み)
- 公開 MCP server の 38.7% がゼロ認証(Bloomberry 1,412 server 調査)。仕様で auth は OPTIONAL と明記——これはバグではなく仕様
- エージェントの「暴走」=トークン税の問題:GitHub MCP の 93 個のツール定義は約 55,000 トークンを消費。5 つの server で最初のユーザーメッセージ前にコンテキストウィンドウの最大 50% を消費
- Kubernetes デプロイのランダム失敗はプロトコル設計の問題:MCP 公式 2026 ロードマップで「stateful sessions fight with load balancers」をスケーリングの課題として直接認知
- AAIF は政治的シグナルであり、セキュリティ保証ではない:AWS/Google/Microsoft の参加は MCP が廃止されないことを意味するが、auth 標準化、コンプライアンス認証、セキュリティベースラインは提供しない
- 3 大実際の事故:Asana テナントデータ漏洩(約 1,000 顧客)、Postmark 悪意ある npm パッケージ(BCC 攻撃)、Supabase RLS バイパス——すべて 2025 年に発生
ローカルで完璧に動く MCP——なぜデプロイすると死ぬのか?
まず症状から。ローカルで stdio を使った MCP server は完璧に動作する。Docker デプロイ後、コンテナは起動 3 秒で exit。あるいは HTTP+SSE でクラウドにデプロイして単独テストは正常だが、2 人目のユーザーが接続した瞬間にすべてが壊れる。
これはコードのバグではない——トランスポート方式の選択ミスだ。
3 つのトランスポートの現実
| トランスポート | 適用シーン | 本番利用 | ステータス |
|---|---|---|---|
| stdio | ローカル開発、単独テスト | 不適切 | 仕様でサポートされているが 1:1 parent-child process 限定 |
| HTTP+SSE | Google で見つかるチュートリアルのほぼすべて | 新規デプロイは非推奨 | 2025-11-25 仕様で正式廃止 |
| Streamable HTTP | 本番環境の唯一の選択肢 | 適切 | 現行仕様の標準 |
Apigene のデプロイテスト(業界分析)は残酷な数字を出した:stdio は 20 同時接続で 20/22 リクエストが失敗——失敗率 91%。ローカルテストで問題がないのは、クライアントが自分 1 人だけだからだ。
重要:使用中の MCP チュートリアルが SSE トランスポートを使っている場合、SSE は 2025-11-25 仕様で正式に廃止されたことに注意。新規デプロイはすべて Streamable HTTP を直接使用すべきだ。
Docker デプロイで必ず確認すべき 4 項目
コンテナ化デプロイで繰り返し踏んだ 4 つの落とし穴:
1. stdio server には -i フラグが必要
# 間違い:stdin が閉じてコンテナが即座に exit
docker run my-mcp-server
# 正しい:stdin を開いたまま維持
docker run -i my-mcp-server
2. Server は 0.0.0.0 で listen する必要がある
// 間違い:ローカルホストのループバック、コンテナ外から接続不可
server.listen(3000, '127.0.0.1');
// 正しい:すべてのインターフェース
server.listen(3000, '0.0.0.0');
3. ポートマッピングの正しい設定
# docker-compose.yml
services:
mcp-server:
ports:
- "3000:3000" # host:container を一致させる
environment:
- MCP_TRANSPORT=streamable-http
4. Volume パーミッション:非 root ユーザーで実行する場合、マウントされたボリュームの書き込み権限で頻繁に問題が発生する。Dockerfile で正しい user/group を先に設定しておくこと。
MCP の Auth は「OPTIONAL」——仕様にそう書いてあり、38.7% の Server がそう実装している
MCP には認証が必須だと思っているかもしれないが、MCP Authorization Specification を開くと、auth は明確に OPTIONAL と記されている。
Bloomberry が 1,412 個の公開(publicly-listed)MCP server を分析した結果は不安を覚えるものだ(注:このデータは公開サーバーを対象としたもので、企業内部のプライベートデプロイのセキュリティ設定は通常まったく異なる):
| Auth 方式 | 割合 | 意味 |
|---|---|---|
| ゼロ認証 | 38.7% | 誰でも接続でき、すべてのツールを列挙可能 |
| Static API Key / PAT | 53% | ないよりはましだが、キーが漏洩すれば終わり |
| OAuth 2.1 | 8.5% | 公式推奨だが、実装はごくわずか |
さらに皮肉なことに、OAuth 2.1 を「正しく」実装しようとするエンタープライズ開発者は、もう 1 つの問題にすぐ直面する——元の仕様では MCP server 自体を authorization server として扱う設計になっている。企業が Okta や Azure AD をアイデンティティプロバイダーとして使っている場合、この前提はまったく機能しない。
OAuth の専門家 Aaron Parecki がこの設計上の問題を記録している——彼が指摘した根本原因は、元の仕様が RFC 8414(OAuth Server Metadata)の使用を要求しており、MCP server が認可サーバーを兼ねることを強制していた点だ。仕様はその後、外部 IdP への認可委任を許可するよう更新されたが、SDK の実装はまだ追いついていない。
現時点の Auth 決定マトリクス
| シナリオ | 推奨方式 | 理由 |
|---|---|---|
| 個人開発者 / 社内ツール | Static bearer token + サーバーサイド検証 | 素早くリリース可能、リスクは管理可能 |
| SaaS / マルチテナント | OAuth 2.1 + 外部 IdP | 長期的に正しい選択だが、独自統合が必要 |
| エンタープライズ(Okta/Azure AD) | OAuth 2.1 + RFC 8414 metadata delegation | SDK の成熟を待つか、自前でラッパーを実装 |
重要:どの方式を選んでも、MCP 仕様には 2 つのハード要件がある——トークンを URI query string に置くことは禁止、サーバーが受け取ったトークンをパススルーすることは禁止(confused deputy 攻撃の防止)。
エージェントの暴走はプロンプトのせいではない——トークン請求書の問題だ
Claude エージェントが MCP ツールを使用中に、突然ツールを誤用したり、タスク目標を忘れたり、質問とまったく関係のない回答を始める。プロンプトの書き方が悪いと思い、3 日かけて system prompt を調整する——しかし問題はそこにはない。
真相:Context Window がツール定義税で食い尽くされている
すべての MCP ツールの JSON Schema 定義がコンテキストウィンドウに注入される。呼び出すかどうかに関係なくだ。これは固定コストになる:
| 指標 | 数字 | 出典 |
|---|---|---|
| GitHub MCP ツール数 | 93 個 | GitHub MCP Server |
| GitHub MCP トークン消費量 | 約 55,000 トークン | Lunar.dev 分析 |
| ツール定義 1 つあたりのコスト | 550~1,400 トークン | 業界測定 |
| 5 つの MCP server + 150 ツール | 30,000~100,000 トークン | 業界推計 |
| 200k コンテキストウィンドウ占有率 | 最大 50% | 計算値 |
つまり、最初のユーザーメッセージを送信する前に、コンテキストウィンドウの半分がツール定義で消費されている可能性がある。
MCP vs REST API 直接利用のコスト比較
Scalekit の 75 組の対照ベンチマークによると:MCP は直接 CLI/REST API 操作と比較して 4~32 倍コストが高い(4 倍は単純な単一ステップの read 操作、32 倍はマルチツールチェーンの複雑な write 操作で発生)。
ユースケースが 1~3 個のツールのみの場合、REST API や function calling を直接使う(MCP を介さない)方がトークン効率は大幅に良い。MCP の強みは複数サーバーの統一インターフェースと動的なツール組み合わせにある——ただし、その強みがどれだけのトークンオーバーヘッドに値するかは自分で評価する必要がある。
3 つの緩和策
- MCP server 数を制限:すべてのサーバーを同時にロードする必要はない。30 ツール以下が妥当な参考上限
- MCP Tool Search:Anthropic は 2025 年 11 月からオンデマンド読み込みをサポート。開発者がツール定義に
defer_loading: trueを設定して有効化する。ツール定義が 10K トークンを超える場合に推奨。コンテキストウィンドウの 95% を保持(トークンオーバーヘッドを約 85% 削減) - Claude Code Mode:コーディングタスクのトークン消費を大幅に削減するが、ワークフローに適合するか要評価
Kubernetes + MCP——公式が認めた設計上の制限であり、YAML の問題ではない
MCP server を Kubernetes にデプロイすると、成功したり失敗したり、規則性がまったく見えない。YAML の記述ミス、リソースリミット不足、ネットワークポリシーの問題を疑うかもしれない——しかし真の問題は MCP プロトコル自体の設計にある。
プロトコル設計 vs 負荷分散
MCP は コネクションごとのサーバーサイドセッション状態 を維持する。クライアントが SSE/Streamable HTTP で Pod A にセッションを確立した後、後続の POST リクエストは同じ Pod A に到達する必要がある。
しかし Kubernetes のデフォルト動作は ラウンドロビン負荷分散——後続リクエストは Pod B に送られ、Pod B にはセッション状態がなく、プロトコルが即座に破綻する。
GitHub Discussions #102 には PHP 開発者のリアルな体験が記録されている:「Kubernetes with multiple pods, POST requests get round-robined to different pod from SSE connection = breaks protocol」。
公式 2026 ロードマップで 「stateful sessions fight with load balancers」がスケーリングの課題として直接認知されている。
現時点での唯一の解決策:Sticky Session + 外部セッションストア
# Nginx sticky session 設定
upstream mcp_backend {
ip_hash; # クライアント IP ベースの sticky session
server mcp-pod-1:3000;
server mcp-pod-2:3000;
server mcp-pod-3:3000;
}
server {
location /mcp {
proxy_pass http://mcp_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Redis を外部セッションストアとして組み合わせ、リクエストが異なる Pod に到達してもセッション状態を取得可能にする:
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
// セッション状態を Redis に保存(in-memory ではなく)
async function saveSessionState(sessionId: string, state: object) {
await redis.set(`mcp:session:${sessionId}`, JSON.stringify(state), 'EX', 3600);
}
async function getSessionState(sessionId: string) {
const data = await redis.get(`mcp:session:${sessionId}`);
return data ? JSON.parse(data) : null;
}
Cold Start vs Always-On のコスト判断
| デプロイ方式 | Cold Start | 月額概算(25 RPD) |
|---|---|---|
| Azure Container Apps(scale-to-zero) | 10~30 秒 | 約 $0 + リクエスト単位 |
| AWS Lambda | 500ms~2 秒 | 約 $0 + 呼び出し単位 |
| Cloud Run min-instances=1 | 10ms 未満 | 約 $15/月 |
| AWS ECS always-on(t3.medium) | 10ms 未満 | 約 $30/月 |
| 従来型 VM | 10ms 未満 | 約 $20~50/月 |
💡 ヒント:ユーザー体験が重要なら、Cloud Run の
min-instances=1(約 $15/月)が cold start を解消する最も安価な方法だ。10~30 秒の cold start は WebSocket/SSE 長時間接続シナリオでは、ユーザーが接続切断を直接体感してしまう。
タイムライン:MCP 公式 2026 ロードマップでは、stateful session と load balancer の衝突がスケーリングの既知課題として記載されているが、stateless transport の具体的なリリース時期は未発表。ロードマップの更新を継続的に追跡されたい。
AAIF の真実——AWS/Google/Microsoft の参加は政治的シグナルであり、セキュリティ保証ではない
2025 年 12 月 9 日、Linux Foundation は Agentic AI Foundation(AAIF)の設立を発表した。Anthropic が MCP を寄贈、Block が Goose を寄贈、OpenAI が AGENTS.md を寄贈。Platinum メンバーには AWS、Google、Microsoft、OpenAI が名を連ねる——華やかな顔ぶれだ。
しかし AAIF が解決する問題は期待とは違うかもしれない:
| AAIF が対応すること | AAIF が対応しないこと |
|---|---|
| プロトコル中立的なガバナンス(Anthropic の一方的な支配を防止) | Auth 標準化 |
| SDK 互換性 Working Group | SSO 統合仕様(Okta/Azure AD) |
| 単一企業によるプロトコル廃止の防止 | コンプライアンス認証(SOC 2/ISO 27001) |
| オープンソースコミュニティガバナンスプロセス | 本番セキュリティベースライン |
| MCP server の公開制限(参入障壁なし) |
AWS、Google、Microsoft が Platinum メンバーになったことは重要な 政治的シグナル だ——MCP は Anthropic に一方的に廃止されることはなく、長期的に存続するプロトコルである。しかし AAIF メンバーシップが特定の MCP server を「エンタープライズ対応」と保証するわけではない。
MCP エンタープライズ対応の自己評価フレームワーク
AAIF が正式な認証を提供するまで(現時点でタイムラインなし)、以下の 5 つの質問に自分で答える必要がある:
- Auth は設定済みか?(ゼロ認証でないだけではなく、完全なトークンライフサイクル管理があるか)
- セッションは分離されているか?(グローバルな可変状態なし、session ID keyed)
- 依存関係はロックされているか?(package-lock.json / yarn.lock が存在し、定期的に監査)
- Tier 1 公式サーバーのみを使用しているか?(Anthropic / GitHub / Cloudflare が自ら保守)
- ツール記述は定期的にスキャンしているか?(tool poisoning 攻撃の防止)
環境変数地獄——MCP エコシステムに統一規格がない代償
3 つの MCP server を同時に使用?おめでとう、env var の命名地獄が待っている:
# ClickUp MCP
MCP_API_KEY=xxx
# PostgreSQL MCP
DATABASE_URL=postgres://user:pass@host:5432/db
# GitHub MCP
GITHUB_TOKEN=ghp_xxxxx
統一された命名規則はない。各サーバーが独自に定義する。${env:VAR} 構文は一部のサーバーのみがサポート。
Docker MCP Gateway のサイレント上書き
Docker MCP Gateway の issue #317 には特に悪質な動作が記録されている:gateway が config.yaml + Docker secret からクレデンシャルを読み取り、見つからない場合に設定済みのクレデンシャルを空値でサイレントに上書きする——エラーなし、警告なし、サイレントに失敗する。
env var は明確に設定しているのに、サーバーが受け取るのは空文字列。デバッグ時はまず、クレデンシャルが実際にサーバープロセスに到達しているか確認すること。
v1.27.1 で修正されたデバッグに 3 日かかるサイレントバグ
MCP server が切断後にサイレントに失敗し、エラーログがゼロの場合——v1.27.1 より前の TypeScript SDK では、トランスポートエラーが サイレントに飲み込まれ、onerror コールバックがまったく発火しなかった。
これは接続切断、セッション無効化、トランスポートエラーが発生しても、エージェントオーケストレーション層がまったく把握できないことを意味する。v1.27.1 でこのバグが修正され、onerror コールバックが正しく発火するようになった。
重要:業界記事での「MCP v1.27」は 2 つのものを混同している——プロトコル仕様 は日付ベースのバージョン(最新:2025-11-25)を使用し、TypeScript SDK は semver(v1.27.1)を使用する。関連資料を読む際は、どちらを指しているか確認すること。
環境変数管理の実践的アプローチ
# .env.mcp — すべての MCP server クレデンシャルの一元管理
# ClickUp
CLICKUP_MCP_API_KEY=xxx
# PostgreSQL
POSTGRES_MCP_DATABASE_URL=postgres://...
# GitHub
GITHUB_MCP_TOKEN=ghp_xxx
# プレフィックス命名規則:{SERVICE}_MCP_{KEY_TYPE}
CI/CD パイプラインに起動前の検証を追加:
#!/bin/bash
# mcp-env-check.sh — サーバー起動前にクレデンシャルを検証
REQUIRED_VARS=("GITHUB_MCP_TOKEN" "POSTGRES_MCP_DATABASE_URL")
for var in "${REQUIRED_VARS[@]}"; do
if [ -z "${!var}" ]; then
echo "ERROR: $var is not set. Aborting."
exit 1
fi
done
echo "All MCP credentials verified. Starting server..."
3 大実際の事故の解析——使用中のサードパーティ MCP Server は本当に安全か?
2025 年に 3 件の MCP 関連セキュリティ事故が発生した。その共通の根本原因は、MCP エコシステムの現時点での構造的リスクを明らかにしている。
事故 1:Asana テナントデータ漏洩(2025 年 6 月)
- タイムライン:2025 年 5 月 1 日に MCP server 公開 → 6 月 4 日にテナント分離の脆弱性を発見 → 約 1,000 顧客が影響 → 2 週間サーバー停止して修復
- 根本原因:キャッシュされたレスポンスがテナントコンテキストを再検証しなかった。User B のリクエストが User A のプロジェクト名、タスク説明、メタデータを読み取る可能性
- パターン:Confused Deputy——サーバーが信頼すべきでないキャッシュされたセッション状態を信頼
事故 2:Postmark 悪意ある npm パッケージ(2025 年 9 月)
- 手法:攻撃者が非公式の
postmark-mcpnpm パッケージを作成し、15 バージョンにわたって信頼を構築した後、v1.0.16 で隠し BCC を追加 - 影響:週約 1,500 ダウンロード(削除前の累計 1,643 回)。このサーバーを通じて送信されたすべてのメールが攻撃者のメールボックスにサイレントコピー
- パターン:サプライチェーン攻撃——npm エコシステムの信頼メカニズムを悪用
事故 3:Supabase/Cursor RLS バイパス
- 手法:MCP server が
service_roleキーで Row-Level Security をバイパスし、prompt injection と組み合わせてデータ漏洩 - パターン:権限昇格——MCP server が過剰な権限のクレデンシャルを保持
共通の根本原因
arXiv の MCP 脅威分類研究は 7 つの脅威カテゴリと 23 の攻撃ベクトルを特定——単一の防御措置で特定された脅威の 34% 以上をカバーするものはない。
サードパーティ MCP Server 使用前の 4 つの質問
サードパーティ MCP server を使用する前に自問すべきこと:
- 誰が保守している? 公式(Anthropic/GitHub/Cloudflare)かコミュニティか?
- セキュリティ連絡先はあるか? npm ページにバグ報告チャネルはあるか?
- 依存関係の最終更新はいつ? 90 日以上更新がないのは警告サイン
- npm レジストリ名は公式と一致しているか?
postmark-mcpは Postmark 公式ではない
マルチテナントセッション分離——MCP プロトコルは対応しない、自分で実装する必要がある
MCP server が複数のテナントにサービスを提供する場合、理解すべき重要な事実がある:MCP プロトコル自体はセッション分離を保証しない——これは完全にサーバー開発者の設計責任だ。
MCP GitHub Issue #1087 にリスクが記録されている:サーバーがグローバル変数にセッション状態を保存する場合(例:self.last_email)、User B のリクエストが User A のデータを読み取る可能性がある。これはまさに Asana 事故の根本原因だ。
3 つの分離失敗パターン
- グローバル可変状態:
let currentUser = ...がモジュールレベルで宣言され、すべてのセッションで共有 - 共有 in-memory キャッシュ:キャッシュキーに session/tenant ID が含まれず、テナント間の汚染が発生
- 未検証のセッション状態再割り当て:キャッシュされたレスポンスがテナントコンテキストを再検証せずに返される
正しいマルチテナント MCP Server 設計
// 間違い:グローバル可変状態
let lastQuery: string; // すべてのセッションで共有!
// 正しい:session ID keyed 状態
const sessionState = new Map<string, SessionData>();
function handleRequest(sessionId: string, request: McpRequest) {
const state = sessionState.get(sessionId);
if (!state || state.tenantId !== request.tenantId) {
throw new Error('Session/tenant mismatch');
}
// ... リクエスト処理
}
データベースの row-level security と定期的な session ID 衝突テストを組み合わせて、分離の完全性を確保する。
MCP エコシステムの現状——「95% はゴミ」にデータの裏付けがある理由
「95% の MCP server はゴミ」というフレーズは Reddit で広く引用されている——極端に聞こえるが、Bloomberry のデータはこの印象にかなり近い。
エコシステム健全性指標
| 指標 | 数字 | 出典 |
|---|---|---|
| リモートエンドポイント停止率 | 52% | Bloomberry、2,181 エンドポイント調査 |
| 完全に正常なエンドポイント | 9% | 同上 |
| レートリミット実装率 | 2.4% | Bloomberry、1,412 server 分析 |
| CORS 完全開放 | 22.9% | 同上 |
| ゼロ認証 | 38.7% | 同上 |
Server 分類の推奨
| Tier | 定義 | 例 | 本番利用の推奨 |
|---|---|---|---|
| Tier 1 | 当事者が自ら保守 | Anthropic / GitHub / Cloudflare | 利用可能だが auth 設定は必要 |
| Tier 2 | 大企業が公式に公開 | Asana / Stripe / Notion 公式 MCP | セキュリティ実績の評価が必要 |
| Tier 3 | 活発なコミュニティが保守 | セキュリティ連絡先あり、定期更新 | 完全なセキュリティ監査が必要 |
| Tier X | 保守されていない | 最終コミットが 90 日以上前 | 本番利用は非推奨 |
エコシステムがこの状態にある理由
- ツールの未成熟:MCP server 認証プロセスがなく、誰でも公開可能
- OAuth 採用率が極めて低い(8.5%):仕様が OPTIONAL と記載、SDK にデフォルトで auth が含まれない
- 強制的なセキュリティベースラインがない:AAIF は現時点でコンプライアンス認証を提供していない
長期的に楽観できる理由
- AAIF ガバナンス:Anthropic がロードマップを一方的に支配することを防ぎ、中立的な進化を確保
- Stateless transport の目標:ロードマップでスケーリング課題として記載。プロトコル層での session vs load balancer 衝突の解決を目指す
- MCP Tool Search:context drift のトークン消費を自動的に緩和
- MCP Tool Search GA:Anthropic が 2026 年 2 月に Tool Search と Programmatic Tool Calling を正式版としてリリース。大規模ツールセットのトークン消費問題がエコシステムレベルで緩和されつつある
MCP 本番デプロイチェックリスト——今日実行できる 15 の検査項目
トランスポート層
- Streamable HTTP 確認:本番環境では必ず Streamable HTTP を使用。stdio や廃止された SSE は不可(→「なぜデプロイすると死ぬのか」セクション参照)
-
0.0.0.0バインディング:サーバーの listen アドレスが127.0.0.1ではないこと(→ Docker デプロイチェックリスト参照) - SSE 無効化:新規デプロイで HTTP+SSE を使用しない。既存のものは早急に移行
Auth 層
- Bearer token 設定済み:最低でも static bearer token を使用。ゼロ認証は不可(→ Auth 決定マトリクス参照)
- トークンが URI query string にない:MCP 仕様のハード要件
- トークンライフサイクル設定:access token ≤1 時間、refresh token と併用
セッション層
- Sticky session 設定:Nginx
ip_hashまたは ALB cookie affinity(→ Kubernetes セクション参照) - 外部セッションストア:Redis または PostgreSQL。in-memory のみは不可
コンテキスト管理
- ツール数監査:サーバーあたり 30 ツール以下が妥当な参考上限(→ トークン請求書セクション参照)
- MCP Tool Search 有効確認:ツール定義に
defer_loading: trueを設定してオンデマンド読み込みを有効化(2025 年 11 月からサポート)
環境変数管理
- クレデンシャル起動時検証:CI/CD パイプラインに env var チェックスクリプトを追加(→ 環境変数地獄セクション参照)
-
.env.mcp一元管理:統一プレフィックス命名でサーバー間の上書きを防止
テナント分離
- Session ID keyed 状態:グローバル可変状態なし。各セッションが独立(→ マルチテナント分離セクション参照)
サプライチェーン
- Tier 1 公式サーバーのみ:本番環境で未検証のサードパーティサーバーを避ける(→ 3 大事故セクション参照)
- 依存関係ロック + 定期監査:
package-lock.jsonが存在し、ツール記述を定期的にスキャン
リスク開示
本記事は MCP server の本番デプロイにおけるセキュリティ上の意思決定に関わる内容を含む。いくつかの重要なリスクを提示する:
- MCP プロトコルはまだ急速に進化中:2025-11-25 仕様は SSE を廃止し、ロードマップでは stateless transport を目標として記載。今日のベストプラクティスは半年後に変わる可能性がある。
- 本記事で引用したサードパーティデータ(Bloomberry の 1,412 server 分析、Apigene のデプロイテスト)は業界の独立調査であり、公式 MCP チームの発表ではない。数字はエコシステムの成熟とともに改善される可能性がある。
- Cold start のコストは概算値:実際のコストはリクエスト量、リージョン、プロバイダーの価格変動に依存する。
- サードパーティ MCP server の使用にはセキュリティリスクの自己評価が必要:AAIF は認証を提供していない。「Tier 1 / Tier 2」分類は本記事の提案フレームワークであり、公式基準ではない。
- Auth 方式の選択はセキュリティ要件に関わる:static bearer token は過渡的な解決策であり、長期的なセキュリティアーキテクチャではない。
結論:MCP のポテンシャルは本物だが、本番デプロイの落とし穴も本物だ
MCP は本物の問題を解決している——AI エージェントがツールやデータに統一プロトコルで接続できるようにすること。そのビジョンは正しく、AAIF の設立は長期的な存続を保証している。
しかし今日、86% の MCP server がまだ localhost に閉じ込められているのには理由がある。stdio から Streamable HTTP へのトランスポートの断層、仕様が auth を OPTIONAL と記載する設計選択、session-per-connection と load balancer の根本的な衝突——これらはあなたの技術力の問題ではない。プロトコルとエコシステムがまだ成熟していないという現実だ。
今日 MCP を本番環境に投入するなら、上記の 15 項目チェックリストが最低基準だ。一つずつ確認し、すべてにチェックを入れ、MCP 2026 ロードマップの進捗を追い続けてほしい。
MCP は成熟する——問題は、成熟する前にこの地雷マップを持って進む覚悟があるかどうかだ。
FAQ
MCP エコシステムは実際に成熟しているのか?「95% の MCP server はゴミ」という主張にはデータの裏付けがあるのか?
データで裏付けられています。Bloomberry が 1,412 個の公開 MCP server を分析した結果:リモートエンドポイントの 52% が停止、完全に正常なのは 9% のみ、レートリミットを実装しているのはわずか 2.4%。本番環境では Tier 1 公式サーバー(Anthropic、GitHub、Cloudflare が自ら保守しているもの)のみを使用し、サードパーティサーバーはセキュリティと保守状態を個別に評価することを推奨します。
MCP server を Kubernetes にデプロイした後、成功したり失敗したりするのは設定の問題か?
設定の問題ではありません。MCP の session-per-connection 設計は、単一のサーバーインスタンスがセッション全体を処理することを前提としています。Kubernetes のラウンドロビン負荷分散は、後続の POST リクエストを異なる Pod に送信し、セッションの連続性を破壊します。公式 2026 ロードマップでこの問題が直接認められています。現時点の解決策は sticky session + 外部セッションストア(Redis)です。
Claude エージェントが MCP ツール使用中に突然タスクを忘れるのはなぜか?
プロンプトの問題ではありません。コンテキストウィンドウがツール定義で埋め尽くされているのが原因です。GitHub MCP の 93 個のツール定義は約 55,000 トークンを消費します。5 つの MCP server を合わせると、最初のユーザーメッセージの前に 200k コンテキストウィンドウの 50% を消費する可能性があります。対策:MCP server 数の制限、MCP Tool Search の有効化(オンデマンド読み込み)、Claude Code Mode の利用を検討してください。


