MCP-Tunnel befinden sich in der Research Preview. Zugang anfordern, um sie auszuprobieren.
Eine Anfrage durch den Tunnel kann auf einer von drei Ebenen fehlschlagen; diagnostiziere sie der Reihe nach: die ausgehende Verbindung zum Tunnel-Edge, das innere TLS von Anthropic zu deinem Proxy, dann Routing und IP-Validierung zum Upstream-MCP-Server.
| Symptom | Ursache | Lösung |
|---|---|---|
| Tunnel erscheint nicht im + MCP Server-Picker des Agenten | Der Picker listet nur Tunnel im Workspace der Session auf, die mindestens ein aktives Zertifikat haben. | Registriere ein CA-Zertifikat oder öffne die Session in dem Workspace, in dem der Tunnel erstellt wurde. |
Aufrufer sieht HTTP 500; cloudflared loggt No ingress rules were defined | cloudflared hat kein lokales Ziel. | Füge --url http://localhost:8080 und network_mode: "service:mcp-proxy" zum cloudflared-Service hinzu. |
Proxy loggt no route for host | tunnel_domain stimmt nicht mit der zugewiesenen Domain überein, oder config.yaml wurde ohne Neustart bearbeitet. | Setze tunnel_domain auf die exakte Domain, die auf der Tunnel-Detailseite angezeigt wird, und starte dann den Proxy neu (docker compose restart mcp-proxy). |
Proxy loggt IP validation failed: <ip> is not a private address | Upstream-MCP-Server wird außerhalb von RFC1918 aufgelöst. | Siehe Upstream-IP-Validierung. |
Proxy beendet sich mit cannot unmarshal !!seq into map[string]string | routes ist eine YAML-Liste. | Verwende routes: { name: http://host:port }. |
Proxy beendet sich mit open /data/tls.key: permission denied | Der Key hat 0600; der Proxy-Container läuft nicht als root. | chmod 644 data/tls.key. |
curl https://<proxy>:8080 schlägt fehl mit wrong version number | Erwartet; der Listener ist Plaintext-WebSocket. TLS findet innerhalb des WS-Streams statt. | Verifiziere stattdessen über einen Managed Agent oder die Messages API. |
Die folgenden Abschnitte behandeln Fehler, die mehr als eine einzeilige Lösung erfordern.
OAuth-Flows schlagen fehl, wenn die Source-IP-Allowlist deines Authorization-Servers das Backend von Anthropic daran hindert, /token, /register und die Discovery-Endpunkte zu erreichen. Wenn du die Egress-Bereiche von Anthropic lieber nicht auf die Allowlist setzen möchtest, kannst du die Backend-zu-Backend-OAuth-Aufrufe durch den Tunnel routen, während der browserseitige /authorize-Endpunkt auf deinem bestehenden öffentlichen Hostnamen bleibt.
Füge eine Proxy-Route für den Authorization-Server hinzu
routes:
mcp: http://your-mcp-server:8080
auth: http://your-auth-server:8080Starte den Proxy nach dem Bearbeiten von routes neu (docker compose restart mcp-proxy oder helm upgrade).
Stelle Discovery-Metadaten mit aufgeteilten Endpunkten bereit
Die /.well-known/oauth-authorization-server-Antwort deines Authorization-Servers sollte authorization_endpoint auf deinen bestehenden Hostnamen in der Allowlist verweisen lassen und alles andere auf den Tunnel:
{
"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"]
}Verweise den MCP-Server auf den Tunnel-Issuer
Die /.well-known/oauth-protected-resource-Antwort deines MCP-Servers sollte den Tunnel-Hostnamen als ihren Authorization-Server referenzieren:
{
"resource": "https://mcp.<tunnel-domain>",
"authorization_servers": ["https://auth.<tunnel-domain>"]
}Mit dieser Konfiguration erreicht der Browser des Nutzers /authorize auf deinem bestehenden Hostnamen (den deine Allowlist bereits zulässt), während das Backend von Anthropic /token, /register und die Discovery-Dokumente durch den Tunnel erreicht.
Die Setup-Komponente (Helm-Job oder Compose-setup-Service) authentifiziert sich bei der Tunnels-API, indem sie ein OIDC-JWT über deine Federation-Regel austauscht. Wenn der Austausch fehlschlägt, siehe Fehlerbehebung bei einem fehlgeschlagenen Austausch in der Workload-Identity-Federation-Referenz; die Fehlermodi (Subject, Audience, Issuer, JWKS, Lifetime) sind dieselben.
Tunnel-spezifische Ursachen:
api.anthropic.com (ohne Schema). Wenn die Audience deiner Regel https://api.anthropic.com ist, setze api.wif.audience entsprechend.403 von der Tunnels-API nach einem erfolgreichen Austausch bedeutet, dass der Scope der Regel org:manage_tunnels nicht enthält oder dass der Service-Account der Regel kein Mitglied des Workspace des Tunnels ist. Setze den Scope und füge den Service-Account zum Workspace hinzu.Bei Helm läuft die Setup-Komponente als Pre-Install-Hook-Job. Bei einem Fehler bleibt der Job zur Inspektion erhalten (kubectl logs job/mcp-tunnel-setup -n mcp-tunnel). Helm verwaltet Hook-Ressourcen nicht, lösche ihn also vor einem erneuten Versuch:
helm uninstall mcp-tunnel -n mcp-tunnel
kubectl -n mcp-tunnel delete job mcp-tunnel-setupÜberprüfe zuerst die cloudflared-Logs. Häufige Ursachen:
TUNNEL_TOKEN fehlt, ist abgelaufen oder wurde falsch kopiert.cloudflared kann auch Warnungen über UDP-Empfangspuffergrößen loggen; dies ist ein QUIC-Tuning-Hinweis, kein Fehler.
Wenn Anthropic das Zertifikat des Proxys während des inneren TLS ablehnt, loggt der Proxy tls handshake failed. Überprüfe, dass:
*.<tunnel-domain> übereinstimmt.Siehe die Zertifikatsanforderungen für die vollständigen Validierungsregeln.
Zum Schutz vor SSRF wählt der Proxy standardmäßig nur Adressen in den privaten RFC1918-Bereichen (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) an. Für die Proxy-zu-Upstream-Verbindung wird nur IPv4 unterstützt. (Der cloudflared-zu-Edge-Egress-Bereich in den Netzwerkanforderungen ist ein anderer Hop.)
Wenn der Proxy IP validation failed: <ip> is not a private address loggt, wurde der Upstream-Hostname außerhalb dieses Bereichs aufgelöst. Bei Kubernetes weisen einige verwaltete Distributionen das Service-CIDR außerhalb von RFC1918 zu; wenn kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' eine Adresse außerhalb der privaten Bereiche zurückgibt, ermittle das Service-CIDR deines Clusters und füge es hinzu.
Wenn die Adresse legitim ist, füge das engste abdeckende CIDR zu upstream.allowed_ips hinzu. Das Setzen von allowed_ips ersetzt den RFC1918-Standard, anstatt ihn zu erweitern, also schließe die privaten Bereiche ein, die deine anderen Upstream-MCP-Server verwenden:
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 onlyVermeide 0.0.0.0/0 außerhalb von lokalen Tests; es deaktiviert den SSRF-Schutz vollständig.
Was this page helpful?