MCPトンネルのトラブルシューティング
トンネルスタックにおける接続性、TLS、IP検証、およびOAuthルーティングの問題を診断します。
トンネルを経由するリクエストは、3つのレイヤーのいずれかで失敗する可能性があります。順番に診断してください。まずトンネルエッジへのアウトバウンド接続、次にAnthropicからプロキシへの内部TLS、そしてアップストリームMCPサーバーへのルーティングとIP検証です。
クイックリファレンス
| 症状 | 原因 | 修正方法 |
|---|---|---|
| エージェントの + MCP Server ピッカーにトンネルが表示されない | ピッカーには、セッションのワークスペース内にあり、少なくとも1つのアクティブな証明書を持つトンネルのみが一覧表示されます。 | CA証明書を登録するか、トンネルが作成されたワークスペースでセッションを開いてください。 |
呼び出し元にHTTP 500が表示され、cloudflaredのログに No ingress rules were defined と記録される | cloudflaredにローカルターゲットがありません。 | cloudflaredサービスに --url http://localhost:8080 と network_mode: "service:mcp-proxy" を追加してください。 |
プロキシのログに no route for host と記録される | tunnel_domain が割り当てられたドメインと一致しないか、config.yaml を編集した後に再起動していません。 | tunnel_domain をトンネル詳細ページに表示されている正確なドメインに設定し、プロキシを再起動してください(docker compose restart mcp-proxy)。 |
プロキシのログに IP validation failed: <ip> is not a private address と記録される | アップストリームMCPサーバーがRFC1918の範囲外に解決されています。 | アップストリームIP検証を参照してください。 |
プロキシが cannot unmarshal !!seq into map[string]string で終了する | routes がYAMLリストになっています。 | routes: { name: http://host:port } を使用してください。 |
プロキシが open /data/tls.key: permission denied で終了する | キーが 0600 であり、プロキシコンテナは非rootで実行されています。 | chmod 644 data/tls.key を実行してください。 |
curl https://<proxy>:8080 が wrong version number で失敗する | 想定どおりの動作です。リスナーはプレーンテキストのWebSocketです。TLSはWSストリームの内部で行われます。 | 代わりにManaged AgentまたはMessages APIを通じて検証してください。 |
以下のセクションでは、1行の修正では解決できない障害について説明します。
送信元IP許可リストの背後でOAuthが失敗する
認可サーバーの送信元IP許可リストが、Anthropicのバックエンドから /token、/register、およびディスカバリーエンドポイントへのアクセスをブロックしている場合、OAuthフローは失敗します。Anthropicのエグレス範囲を許可リストに追加したくない場合は、ブラウザ向けの /authorize エンドポイントを既存のパブリックホスト名に残したまま、バックエンド間のOAuth呼び出しをトンネル経由でルーティングできます。
認可サーバー用のプロキシルートを追加する
routes: mcp: http://your-mcp-server:8080 auth: http://your-auth-server:8080routesを編集した後はプロキシを再起動してください(docker compose restart mcp-proxy、またはhelm upgrade)。エンドポイントを分割したディスカバリーメタデータを提供する
認可サーバーの
/.well-known/oauth-authorization-serverレスポンスでは、authorization_endpointを既存の許可リスト登録済みホスト名に向け、それ以外はすべてトンネルに向ける必要があります。{ "issuer": "https://auth.<tunnel-domain>", "authorization_endpoint": "https://<your-allowlisted-host>/authorize", "token_endpoint": "https://auth.<tunnel-domain>/token", "registration_endpoint": "https://auth.<tunnel-domain>/register", "code_challenge_methods_supported": ["S256"] }MCPサーバーをトンネルのissuerに向ける
MCPサーバーの
/.well-known/oauth-protected-resourceレスポンスでは、認可サーバーとしてトンネルのホスト名を参照する必要があります。{ "resource": "https://mcp.<tunnel-domain>", "authorization_servers": ["https://auth.<tunnel-domain>"] }
この構成では、ユーザーのブラウザは既存のホスト名の /authorize にアクセスし(これは許可リストですでに許可されています)、Anthropicのバックエンドは /token、/register、およびディスカバリードキュメントにトンネル経由でアクセスします。
セットアップコンポーネントの認証失敗
セットアップコンポーネント(Helm JobまたはComposeの setup サービス)は、フェデレーションルールを通じてOIDC JWTを交換することでTunnels APIに対して認証します。交換が失敗した場合は、Workload Identity Federationリファレンスの失敗した交換のトラブルシューティングを参照してください。失敗モード(subject、audience、issuer、JWKS、有効期間)は同じです。
トンネル固有の原因:
- チャートのデフォルトのaudienceは
api.anthropic.com(スキームなし)です。ルールのaudienceがhttps://api.anthropic.comの場合は、api.wif.audienceを一致するように設定してください。 - 交換が成功した後にTunnels APIから
403が返される場合、ルールのスコープにworkspace:manage_tunnelsが含まれていないか、ルールのサービスアカウントがトンネルのワークスペースのメンバーではありません。スコープを設定し、サービスアカウントをワークスペースに追加してください。
Helmでは、セットアップコンポーネントはpre-installフックのJobとして実行されます。失敗した場合、Jobは調査のために残されます(kubectl logs job/mcp-tunnel-setup -n mcp-tunnel)。Helmはフックリソースを管理しないため、再試行する前に削除してください。
helm uninstall mcp-tunnel -n mcp-tunnel
kubectl -n mcp-tunnel delete job mcp-tunnel-setupトンネルが接続しない
まずcloudflaredのログを確認してください。一般的な原因:
TUNNEL_TOKENが欠落している、期限切れである、または正しくコピーされていない。- ファイアウォールがトンネルエッジへのポート7844のアウトバウンドTCP/UDPをブロックしている。
cloudflaredはUDP受信バッファサイズに関する警告をログに記録することもあります。これはQUICのチューニングに関するヒントであり、エラーではありません。
証明書エラー
内部TLS中にAnthropicがプロキシの証明書を拒否すると、プロキシは tls handshake failed をログに記録します。以下を確認してください。
- サーバー証明書の有効期限が切れていないこと。
- 証明書のSubject Alternative Nameが
*.<tunnel-domain>と一致していること。 - 署名したCAがこのトンネル用にAnthropicに登録されていること。
完全な検証ルールについては、証明書の要件を参照してください。
アップストリームIP検証
SSRF保護のため、プロキシはデフォルトでRFC1918のプライベート範囲(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)内のアドレスにのみ接続します。プロキシからアップストリームへの接続ではIPv4のみがサポートされています。(ネットワーク要件に記載されているcloudflaredからエッジへのエグレス範囲は別のホップです。)
プロキシのログに IP validation failed: <ip> is not a private address と記録される場合、アップストリームのホスト名がその範囲外に解決されています。Kubernetesでは、一部のマネージドディストリビューションがService CIDRをRFC1918の範囲外に割り当てます。kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' がプライベート範囲外のアドレスを返す場合は、クラスターのService CIDRを調べて追加してください。
アドレスが正当なものである場合は、それをカバーする最も狭いCIDRを upstream.allowed_ips に追加してください。allowed_ips を設定すると、RFC1918のデフォルトを拡張するのではなく置き換えるため、他のアップストリームMCPサーバーが使用するプライベート範囲も含めてください。
upstream:
allowed_ips:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8 # loopback, for local testing onlyWas this page helpful?