Les tunnels MCP sont en aperçu de recherche. Demandez l'accès pour les essayer.
Ce guide déploie la pile de tunnel sous forme de conteneurs renforcés sur un hôte unique. La même configuration peut être répliquée sur plusieurs hôtes pour assurer la disponibilité.
Vous avez besoin de :
tnl_...). Le provisionnement manuel commence toujours à partir d'un tunnel créé dans la Console.fdrl_...) et votre ID d'organisation.openssl (1.1.1 ou ultérieur).api.anthropic.com (443 TCP) et la bordure du tunnel (7844 TCP et UDP). Consultez les exigences réseau complètes.routes. Si vous n'en avez pas encore, utilisez le serveur d'exemple.Si vous n'avez pas de serveur MCP disponible pour les tests, utilisez ce serveur minimal :
mkdir -p mcp-tunnel
cat > mcp-tunnel/hello_server.py <<'EOF'
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-server", host="0.0.0.0", port=9000)
@mcp.tool()
def hello(name: str = "world") -> str:
"""Say hello to someone."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run(transport="streamable-http")
EOFLes étapes d'installation suivantes font un cd dans mcp-tunnel/ et indiquent où ajouter le service et la route correspondants.
Ce guide fournit une approche de référence utilisant Docker Compose. Il vous incombe de l'adapter pour répondre aux exigences de sécurité de votre organisation.
Ce chemin nécessite que l'hôte dispose d'un fournisseur d'identité OIDC (tel qu'un serveur de métadonnées de VM cloud ou SPIFFE). Si ce n'est pas le cas, utilisez plutôt l'onglet Sans accès programmatique.
Le composant de configuration utilise Workload Identity Federation pour récupérer le jeton de tunnel, générer une CA et un certificat serveur, et enregistrer la CA auprès d'Anthropic.
Préparer le répertoire de déploiement
mkdir -p mcp-tunnel/{config,data}
cd mcp-tunnel
sudo chown 65532:65532 dataLes conteneurs s'exécutent avec l'UID non root 65532 et ont besoin d'un accès en écriture à data/.
Écrire docker-compose.yaml
Le fichier compose épingle les images par empreinte SHA-256, exécute chaque conteneur en tant que non-root avec un système de fichiers en lecture seule, supprime toutes les capacités Linux et désactive l'élévation de privilèges.
cat > docker-compose.yaml <<'EOF'
services:
setup:
image: us-docker.pkg.dev/anthropic-public-registry/images/mcp-proxy@sha256:9d4c80593b559fc3ca3814866418744fa94858b02a4d4a4cc52d423e732ccc81
entrypoint: ["/setup"]
command:
- init
- --api-url=https://api.anthropic.com
- --output=dir:/data
- --token-version=1
environment:
- TUNNEL_ID
- ANTHROPIC_FEDERATION_RULE_ID
- ANTHROPIC_ORGANIZATION_ID
- ANTHROPIC_WORKSPACE_ID
- ANTHROPIC_IDENTITY_TOKEN
volumes:
- ./data:/data
user: "65532:65532"
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
profiles: ["setup"]
cloudflared:
image: cloudflare/cloudflared@sha256:6b599ca3e974349ead3286d178da61d291961182ec3fe9c505e1dd02c8ac31b0
command: tunnel --no-autoupdate run --url http://localhost:8080
environment:
- TUNNEL_TOKEN
# Partage le netns du proxy pour que localhost:8080 puisse l'atteindre.
network_mode: "service:mcp-proxy"
restart: unless-stopped
user: "65532:65532"
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
stop_grace_period: 30s
logging:
options:
max-size: "10m"
max-file: "3"
mcp-proxy:
image: us-docker.pkg.dev/anthropic-public-registry/images/mcp-proxy@sha256:9d4c80593b559fc3ca3814866418744fa94858b02a4d4a4cc52d423e732ccc81
volumes:
- ./config/mcp-proxy.yaml:/etc/mcp-gateway/config.yaml:ro
- ./data:/data:ro
restart: unless-stopped
user: "65532:65532"
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
stop_grace_period: 30s
logging:
options:
max-size: "10m"
max-file: "3"
EOFSi vous utilisez le serveur MCP d'exemple, ajoutez-le en tant que service :
cat >> docker-compose.yaml <<'EOF'
hello-mcp:
image: python:3.13-slim
working_dir: /app
volumes:
- ./hello_server.py:/app/hello_server.py:ro
command: sh -c "pip install --quiet mcp && python hello_server.py"
restart: unless-stopped
EOFProvisionner le tunnel
Définissez les identifiants. Laissez TUNNEL_ID non défini pour que le composant de configuration crée un tunnel ; définissez-le pour vous attacher à un tunnel existant depuis la Console :
# export TUNNEL_ID=tnl_... # à définir pour se rattacher à un tunnel existant
export ANTHROPIC_FEDERATION_RULE_ID=fdrl_...
export ANTHROPIC_ORGANIZATION_ID=00000000-0000-0000-0000-000000000000Si votre règle de fédération est limitée à un espace de travail autre que l'espace de travail par défaut de votre organisation, définissez également ANTHROPIC_WORKSPACE_ID=wrkspc_... ; sinon, le composant de configuration utilise l'espace de travail par défaut. Un tunnel créé automatiquement est créé dans cet espace de travail.
Définissez ANTHROPIC_IDENTITY_TOKEN sur un JWT OIDC provenant du fournisseur d'identité de cet hôte. Suivez le guide WIF pour votre fournisseur pour enregistrer l'émetteur, définir le sujet de la règle et émettre le jeton ; l'audience de la règle doit correspondre à l'audience que vous demandez lors de l'émission.
Exécutez le composant de configuration :
docker compose run --rm setupsetup init est idempotent sur data/ : le réexécuter réutilise l'ID de tunnel et la CA déjà stockés à cet emplacement et ne crée jamais de second tunnel. Une nouvelle CA n'est générée et enregistrée que lorsque data/ est vide ou que TUNNEL_ID a changé ; dans ce cas, la limite de deux certificats actifs s'applique, donc révoquez-en un dans la Console au préalable si les deux emplacements sont occupés.
Consultez Échecs d'authentification du composant de configuration en cas d'erreur.
Récupérez votre domaine de tunnel et exportez-le pour les étapes ultérieures :
export TUNNEL_DOMAIN=$(sudo cat data/tunnel-domain)
echo "$TUNNEL_DOMAIN"Les jetons Workload Identity Federation ont une durée de vie courte (1 heure par défaut) et expirent automatiquement ; il n'y a rien à révoquer une fois la configuration terminée.
Écrire la configuration du proxy
tunnel_domain est obligatoire : le proxy l'utilise pour retirer le suffixe de domaine des noms d'hôte entrants avant de rechercher le sous-domaine dans routes. routes est une table de correspondance plate entre sous-domaine et URL en amont, pas une liste.
cat > config/mcp-proxy.yaml <<EOF
listen_addr: ":8080"
log_level: info
shutdown_timeout: 30s
tunnel_domain: ${TUNNEL_DOMAIN}
tls:
cert_file: /data/tls.crt
key_file: /data/tls.key
routes:
echo: http://hello-mcp:9000
EOFLa route echo: cible le serveur MCP d'exemple ; remplacez-la par (ou ajoutez) vos propres routes. Consultez la référence de configuration du proxy pour tous les champs disponibles.
Démarrer le déploiement
export TUNNEL_TOKEN=$(sudo cat data/tunnel-token)
docker compose up -dLe fichier compose lit TUNNEL_TOKEN depuis l'environnement de l'hôte sans valeur par défaut, donc l'export doit être répété dans chaque nouveau shell et après un redémarrage.
Pour un déploiement multi-VM, copiez le répertoire mcp-tunnel/ sur chaque hôte, définissez TUNNEL_TOKEN et exécutez docker compose up -d. Dans le flux programmatique, TUNNEL_TOKEN est $(sudo cat data/tunnel-token) ; dans le flux manuel, c'est la valeur que vous avez copiée depuis la Console. Le même jeton de tunnel et les mêmes certificats fonctionnent sur toutes les répliques.
Vérifiez de bout en bout en appelant un serveur MCP en amont depuis le côté d'Anthropic : consultez Utiliser les serveurs MCP tunnelisés. Avec le serveur MCP d'exemple, l'URL routée est https://echo.<your-tunnel-domain>/mcp. Si la vérification échoue, consultez Dépannage.
Exécutez les commandes de cette section depuis l'intérieur du répertoire de déploiement mcp-tunnel/.
Avec l'accès programmatique, incrémentez --token-version dans la commande du service setup, définissez les identifiants Workload Identity Federation, émettez un nouveau JWT OIDC et réexécutez le composant de configuration :
# Modifiez docker-compose.yaml : incrémentez l'entier dans l'argument
# --token-version du service setup (par exemple, --token-version=1 vers
# --token-version=2). Le binaire setup refuse d'effectuer la rotation si la valeur
# n'a pas changé.
# export TUNNEL_ID=tnl_... # à définir uniquement si vous l'avez défini lors de l'installation
export ANTHROPIC_FEDERATION_RULE_ID=fdrl_...
export ANTHROPIC_ORGANIZATION_ID=00000000-0000-0000-0000-000000000000
# export ANTHROPIC_WORKSPACE_ID=wrkspc_... # si votre règle est limitée à l'espace de travail
# Régénérez ANTHROPIC_IDENTITY_TOKEN selon le guide du fournisseur WIF pour votre
# environnement (il aura expiré depuis l'installation).
export ANTHROPIC_IDENTITY_TOKEN=...
docker compose run --rm setup
export TUNNEL_TOKEN=$(sudo cat data/tunnel-token)
docker compose up -d cloudflaredL'argument --token-version est modifié dans docker-compose.yaml plutôt que passé en ligne de commande afin que la nouvelle valeur persiste pour les exécutions futures du composant de configuration. Le composant de configuration s'authentifie avec Workload Identity Federation ; il n'y a pas de jeton API à révoquer.
Sans accès programmatique, cliquez sur Rotate token sur la page de détail du tunnel dans la Console, puis mettez à jour la variable d'environnement TUNNEL_TOKEN sur chaque hôte et redémarrez cloudflared (docker compose up -d cloudflared).
Cliquer sur Rotate token invalide immédiatement le jeton actuel. Entre ce moment et la mise à jour de TUNNEL_TOKEN sur chaque hôte et le redémarrage de cloudflared, tout hôte dont cloudflared redémarre (plantage, redémarrage de l'hôte) ne peut pas se reconnecter. Mettez à jour chaque hôte rapidement après la rotation.
Il vous incombe de surveiller l'expiration et de renouveler le certificat serveur avant qu'il n'expire.
Avec l'accès programmatique :
docker compose run --rm setup renew-cert --output=dir:/dataLes arguments CLI remplacent la command du service setup (les arguments init) mais conservent son entrypoint, donc cela exécute /setup renew-cert --output=dir:/data.
Passez --renew-before=720h pour que la commande ne fasse rien lorsqu'il reste plus de 30 jours de validité. Cela permet de l'exécuter en toute sécurité selon un calendrier fixe.
Sans accès programmatique, signez un nouveau certificat serveur avec votre CA existante (la CA enregistrée dans la Console ne change pas) et remplacez data/tls.crt. Définissez d'abord TUNNEL_DOMAIN si vous exécutez ceci depuis un nouveau shell.
export TUNNEL_DOMAIN=YOUR_TUNNEL_DOMAIN_HERE
openssl req -new -key data/tls.key -out /tmp/server.csr \
-subj "/CN=${TUNNEL_DOMAIN}"
openssl x509 -req -in /tmp/server.csr \
-CA data/ca.crt -CAkey data/ca.key -CAcreateserial \
-out data/tls.crt -days 90 \
-extfile data/tls.extDans les deux flux, le proxy interroge tls.cert_file et le recharge automatiquement, donc aucun redémarrage n'est nécessaire.
Attachez un serveur MCP en amont à un Managed Agent ou à l'API Messages.
Conseils de renforcement, rotation des identifiants et réponse aux violations.
Diagnostiquez les problèmes de connectivité, de TLS et de routage.
Was this page helpful?