MCP tunnelsのアーキテクチャ — トンネルスタックの構成要素
MCP tunnelsを構成するProxy・cloudflared・Setup componentの役割と、資格情報の受け渡し方、接続の向きが逆転する仕組みを解説します。
MCP tunnelsとは何か
MCP tunnelsは、プライベートネットワーク内で動くMCPサーバーへ、インバウンドのポートを一切開けずにClaudeを接続する機能です。トラフィックはアウトバウンド専用の接続を通るため、ファイアウォールの受信ポート開放も、Anthropicのアクセス元IPレンジの許可リスト登録も不要になります。接続先の実行環境としてはManaged Agentsのセッションと、Messages APIのMCP接続の両方から使えます。
MCP tunnelsはResearch Previewの段階にあり、利用には申請が必要です。稼働率やサポートについての保証は無く、トランスポート部分をCloudflareという第三者プロバイダーに依存しており、Anthropicはいつでも仕様変更や提供終了ができる立て付けです。
稼働率の保証が無い以上、可用性が要求される経路に載せる構成は、保証条件が明示されてからの検討になります。ConsoleからClaude.aiのコネクタとして接続する経路は用意されておらず、利用先はManaged Agentsのセッションと、Messages APIのmcp_servers指定に限られます。
トンネルスタックを構成する5つの用語
構成要素には複数の呼び名が飛び交うため、正式名称と別名の対応を先に押さえておくと設定ファイルを読み違えません。実務で読み替えが必要な場面ごとの対応は次のとおりです。
| 用語 | 役割 | 設定ファイルやイメージでの別名 |
|---|---|---|
| Proxy | 役割Anthropicが実装するルーティング担当。内部TLSを終端し、宛先IPが許可レンジ内かを検証し、ホスト名でアップストリームへ振り分ける | 設定ファイルやイメージでの別名イメージ名mcp-proxy、設定パス/etc/mcp-gateway/config.yaml |
| cloudflared | 役割Cloudflareが提供するオープンソースのトンネルコネクタ。アウトバウンド接続の起点になる | 設定ファイルやイメージでの別名「outbound connector」「tunnel connector」とも呼ばれる |
| Setup component | 役割mcp-proxyイメージに同梱されるsetupバイナリ。プログラム的アクセス時にWIFで認証し、トンネルトークンの取得とCA証明書の発行・登録まで自動化する | 設定ファイルやイメージでの別名Helmのpre-installフックJob、Composeのsetupサービス |
| Tunnel edge | 役割cloudflaredが接続するCloudflareのエッジサーバー群(198.41.192.0/19、2606:4700:a0::/44、ポート7844) | 設定ファイルやイメージでの別名「the edge」 |
| Upstream MCPサーバー | 役割Proxyがルーティングする、プライベートネットワーク内の実際のMCPサーバー | 設定ファイルやイメージでの別名「upstream」「routed MCP server」 |
Proxyとcloudflaredの2コンテナが「トンネルスタック」の実体で、1スタックが1トンネルに対応します。可用性を上げたければ、同じスタックを複数ホストに複製できます。
資格情報の受け渡し方 — 2つのモード
トンネルスタックが起動時に必要とする資格情報は2つです。cloudflaredのアウトバウンド接続を認証するトンネルトークンと、Proxyが内部TLSのハンドシェイクで提示するサーバー証明書(トンネルに登録済みのCAで署名されたもの)。この2つの受け渡し方には2モードあります。
| モード | 資格情報の流れ | 向くケース |
|---|---|---|
| プログラム的アクセス(推奨) | 資格情報の流れSetup componentがWorkload Identity Federation(WIF)でTunnels APIへ認証し、トンネルトークンの取得とCA・サーバー証明書の生成・登録までを自動化する。workspace:manage_tunnelsスコープを持つ連合ルールが必要 | 向くケースKubernetesクラスタやクラウドの既存IdPを使い、本番環境で長期運用する構成 |
| 手動 | 資格情報の流れConsoleからトンネルトークンをコピーし、opensslなどでCAとサーバー証明書を自分で生成してConsoleに登録し、シークレットとしてスタックへ渡す。Setup componentは動かない | 向くケースローカルでの動作確認や、IdPを持たない小規模な検証 |
プログラム的アクセスを選ぶと、長期のシークレットを手でコピーする工程が丸ごと無くなります。WIFはAnthropicが提供する認証基盤としてはトークン交換の仕組みそのものが共通していますが、連合ルールに与えるスコープがMCP tunnels専用のworkspace:manage_tunnelsである点が他の用途と異なります。
接続の向きとリクエストの向きが逆転する仕組み
トンネルには2つの「向き」があり、互いに逆を向いています。接続の向きはcloudflaredからトンネルエッジへのアウトバウンドで、開いているのはこの1本だけです。リクエストの向きは、いったん接続が確立したあと、Anthropic側からプライベートネットワーク側へ向かうMCPリクエストです。「アウトバウンド専用」という表現は接続の向きを指しており、リクエストの向きまでアウトバウンドだという意味ではありません。
内部TLSはAnthropicのバックエンドとProxyの間だけで完結し、途中のcloudflaredとトンネルエッジは暗号化されたバイト列しか見えません。プライベートネットワークの中でMCPリクエストの中身が読める最初の地点は、Proxyです。
Proxyの経路制御とIP検証という設計
Proxyの設定ファイル(Composeなら/etc/mcp-gateway/config.yaml、Helmならレンダリング済みConfigMap)は、routesにサブドメインとアップストリームURLのマップを持ちます。ここは実装上の落とし穴が1つあり、routesはマップ型でなければならず、リスト形式で書くと起動時にcannot unmarshal !!seq into map[string]stringで落ちます。
# 正しい: マップ
routes:
echo: http://hello-mcp:9000
# 誤り: リスト形式は起動時にエラー
routes:
- echo: http://hello-mcp:9000もう1つの安全設計が、アップストリームIPの検証です。ProxyはSSRF対策として、既定ではRFC1918のプライベートアドレス空間(10.0.0.0/8・172.16.0.0/12・192.168.0.0/16)にしか接続しません。IPv4のみサポートで、社内システムがこの範囲外のアドレスを使っている場合はupstream.allowed_ipsを明示的に広げる必要があります。ここを0.0.0.0/0にするとSSRF対策そのものが無効になり、Proxyが到達できる範囲は社内ネットワーク全体に広がります。
ネットワーク要件と証明書のライフサイクル
構成要素ごとに、外向きの通信先が固定されています。Setup componentはapi.anthropic.comのポート443へ、cloudflaredはトンネルエッジ(198.41.192.0/19と2606:4700:a0::/44)のポート7844(TCPとUDP)へ、Proxyは設定した各アップストリームMCPサーバーへアウトバウンドで接続します。ファイアウォールのルールを事前に用意するなら、この3行がそのままチェックリストになります。
# Setup componentが必要とする経路の疎通確認(ポート443)
curl -sS -o /dev/null -w "%{http_code}\n" https://api.anthropic.com証明書には2種類あり、ライフサイクルが異なります。CA証明書はPEM形式で最大8kB、RSA 2048ビット以上かECDSA P-256以上、BasicConstraintsにCA:TRUEが必須で、1トンネルにつき最大2枚まで有効に保持できます。この上限が2枚である理由は、ダウンタイムなしでのローテーションを可能にするためです。サーバー証明書は登録済みのCAから直接署名され(中間CAを挟めない)、SANが*.<tunnel-domain>に一致する必要があります。Setup componentが自動生成する場合、CAは5年間有効なECDSA P-256、サーバー証明書は90日間有効なRSA 4096ビットが既定値です。自前のPKIで発行する運用にする場合は、90日ごとの更新をジョブとして組み込む前提で設計する必要があります。
Tunnels REST APIは/v1/tunnelsにあり、トンネルの作成・一覧・アーカイブ、CA証明書の登録、トンネルトークンの開示・ローテーションを担います。すべてのエンドポイントはworkspace:manage_tunnelsスコープを持つWIF発行のBearerトークンを要求し、Admin APIキーでは呼べません。以前のAdmin API面(/v1/organizations/tunnels、betaヘッダーmcp-tunnels-2026-05-19)は移行期間中は動きますが、非推奨扱いです。新規に組むなら最初から新しいbetaヘッダーmcp-tunnels-2026-06-22を使うほうが、あとで移行作業をやり直さずに済みます。認証ヘッダーの具体的な指定方法やconfig.yamlの各項目、setupコマンドのフラグはMCP tunnelsリファレンスにまとめています。
3層防御のセキュリティモデルと責任分界
MCP tunnelsは3層の独立した防御を積み重ねています。外側からトンネルエッジへの到達を検証する外部mTLSとIP検証、Cloudflareのネットワークを越えてもペイロードを読ませない内部TLS、そして認証済みのトンネル経由でも各MCPサーバー自身が要求するOAuthです。この3層目があるからこそ、トンネルを通れること自体はMCPツールの利用許可を意味しません。
責任分界も明確です。Anthropicはトンネルへのアクセス制御とCA証明書の検証、自社組織が所有するトンネルにしかリクエストを送らないことを保証します。一方でトンネルを通過するトラフィックの内容、Cloudflareの利用規約の遵守、トークンとTLS秘密鍵の保管、証明書の更新、各MCPサーバーのOAuth設定、Proxy・MCPサーバー自体のネットワーク制限は、利用組織側の責任です。トンネルトークンとTLS秘密鍵の両方を攻撃者に奪われると、Proxyになりすましてペイロードを読める状態になるため、この2つは高価値のシークレットとして扱う必要があります。侵害を疑ったときの具体的な確認手順とトンネル廃止の手順はMCP tunnelsのセキュリティにまとめています。
なぜCloudflareを挟んでも中身が読まれないのか
トランスポートに第三者(Cloudflare)を使いながら中身を読ませない設計は、責任の置き場所を意図的にずらした結果です。Cloudflareが担うのはあくまで暗号化された接続の運搬で、cloudflaredとトンネルエッジが見えるのは接続元IP・ホストのフィンガープリント・接続のタイミングとバイト量・割り当てられたサブドメインだけです。ペイロードの復号鍵はProxyが持つ秘密鍵の中にしか無く、Cloudflare側には渡りません。
これは「信頼できるトランスポート事業者を選ぶ」代わりに「トランスポート事業者を信頼しなくてよい設計にする」という選択です。Cloudflareの可用性保証が無い研究プレビュー段階であることを踏まえると、可用性ではなく機密性の設計に先に投資したと読めます。
従来型のリバースプロキシやVPNでインバウンドを開ける構成と比べると、攻撃対象領域の考え方が逆転している点も見逃せません。VPNは「境界の中に入れるかどうか」を1回の認証で決めるのに対し、MCP tunnelsは接続の確立(cloudflaredの認証)・内部TLSの検証(証明書の一致)・各MCPサーバーのOAuthという3つの独立した関門を、リクエストのたびに通過させます。関門を1つ増やすたびに運用の手間は増えますが、そのぶん1箇所の突破で全体が崩れる単一障害点を減らす設計になっています。
まとめ
MCP tunnelsは、社内ネットワークのMCPサーバーをClaudeのManaged AgentsやMessages APIから安全に呼びたいが、インバウンドのポート開放や自社IPの許可リスト登録は避けたい、という要件に応える構成です。ただしResearch Preview段階である以上、可用性が求められる本番経路にいきなり載せるのではなく、まずは検証環境で構成要素の役割分担を掴んでから拡張するのが現実的です。用語と力学を先に押さえておけば、実際に手を動かす段階でエラーメッセージの意味を推測しやすくなります。手を動かして最短経路で1本のトンネルを立てる手順はMCP tunnelsのクイックスタートにまとめています。