MCP 隧道目前处于研究预览阶段。申请访问权限以进行试用。
本指南将隧道堆栈作为加固容器部署在单个主机上。相同的配置可以在多个主机上复制以实现可用性。
您需要:
tnl_...)。手动配置始终从 Console 创建的隧道开始。fdrl_...)和您的组织 ID。openssl(1.1.1 或更高版本)。api.anthropic.com(443 TCP)和隧道边缘(7844 TCP 和 UDP)的出站网络连接。请参阅完整的网络要求。routes 下配置的地址访问。如果您还没有,请使用示例服务器。如果您没有可用于测试的 MCP 服务器,请使用这个最小化的服务器:
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")
EOF以下安装步骤会 cd 进入 mcp-tunnel/,并说明在何处添加相应的服务和路由。
本指南提供了一种使用 Docker Compose 的参考方法。您有责任对其进行调整以满足您组织的安全要求。
此路径要求主机具有 OIDC 身份提供者(例如云虚拟机元数据服务器或 SPIFFE)。如果没有,请改用不使用编程访问选项卡。
设置组件使用 Workload Identity Federation 获取隧道令牌、生成 CA 和服务器证书,并向 Anthropic 注册 CA。
准备部署目录
mkdir -p mcp-tunnel/{config,data}
cd mcp-tunnel
sudo chown 65532:65532 data容器以非 root UID 65532 运行,需要对 data/ 的写入权限。
编写 docker-compose.yaml
该 compose 文件通过 SHA-256 摘要固定镜像,以非 root 身份和只读文件系统运行每个容器,丢弃所有 Linux 能力,并禁用权限提升。
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
# 共享代理的 netns,以便 localhost:8080 能访问到它。
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"
EOF如果您使用示例 MCP 服务器,请将其作为服务追加:
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
EOF配置隧道
设置标识符。不设置 TUNNEL_ID 可让设置组件创建隧道;设置它则附加到来自 Console 的现有隧道:
# export TUNNEL_ID=tnl_... # 设置此项以连接到现有隧道
export ANTHROPIC_FEDERATION_RULE_ID=fdrl_...
export ANTHROPIC_ORGANIZATION_ID=00000000-0000-0000-0000-000000000000如果您的联合规则的作用域是组织默认工作区以外的工作区,还需设置 ANTHROPIC_WORKSPACE_ID=wrkspc_...;否则设置组件使用默认工作区。自动创建的隧道会在该工作区中创建。
将 ANTHROPIC_IDENTITY_TOKEN 设置为来自此主机身份提供者的 OIDC JWT。按照适用于您的提供者的 WIF 指南注册颁发者、设置规则的主体并铸造令牌;规则的受众必须与您铸造令牌时请求的受众匹配。
运行设置组件:
docker compose run --rm setupsetup init 对 data/ 是幂等的:重新运行它会重用已存储在那里的隧道 ID 和 CA,并且永远不会创建第二个隧道。只有当 data/ 为空或 TUNNEL_ID 已更改时,才会生成并注册新的 CA;在这种情况下,两个活动证书的上限适用,因此如果两个槽位都已占满,请先在 Console 中吊销一个。
如果出现错误,请参阅设置组件身份验证失败。
检索您的隧道域名并将其导出以供后续步骤使用:
export TUNNEL_DOMAIN=$(sudo cat data/tunnel-domain)
echo "$TUNNEL_DOMAIN"Workload Identity Federation 令牌是短期的(默认为 1 小时)并会自动过期;设置完成后无需吊销任何内容。
编写代理配置
tunnel_domain 是必需的:代理使用它在查找 routes 中的子域名之前,从传入的主机名中剥离域名后缀。routes 是从子域名到上游 URL 的扁平映射,而不是列表。
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
EOFecho: 路由指向示例 MCP 服务器;请将其替换为(或添加)您自己的路由。有关所有可用字段,请参阅代理配置参考。
启动部署
export TUNNEL_TOKEN=$(sudo cat data/tunnel-token)
docker compose up -d该 compose 文件从主机环境读取 TUNNEL_TOKEN 且没有默认值,因此必须在每个新的 shell 中以及重启后重复执行导出操作。
对于多虚拟机部署,将 mcp-tunnel/ 目录复制到每个主机,设置 TUNNEL_TOKEN,然后运行 docker compose up -d。在编程流程中,TUNNEL_TOKEN 是 $(sudo cat data/tunnel-token);在手动流程中,它是您从 Console 复制的值。相同的隧道令牌和证书适用于所有副本。
通过从 Anthropic 侧调用上游 MCP 服务器进行端到端验证:请参阅使用隧道化的 MCP 服务器。使用示例 MCP 服务器时,路由的 URL 为 https://echo.<your-tunnel-domain>/mcp。如果验证失败,请参阅故障排除。
在 mcp-tunnel/ 部署目录内运行本节中的命令。
使用编程访问时,在 setup 服务命令中递增 --token-version,设置 Workload Identity Federation 标识符,铸造新的 OIDC JWT,然后重新运行设置组件:
# 编辑 docker-compose.yaml:递增 setup 服务的
# --token-version 参数中的整数(例如,将 --token-version=1 改为
# --token-version=2)。如果该值未更改,setup 二进制文件
# 将拒绝轮换。
# export TUNNEL_ID=tnl_... # 仅当您在安装时设置过它时才需设置
export ANTHROPIC_FEDERATION_RULE_ID=fdrl_...
export ANTHROPIC_ORGANIZATION_ID=00000000-0000-0000-0000-000000000000
# export ANTHROPIC_WORKSPACE_ID=wrkspc_... # 如果您的规则限定于工作区
# 请按照适用于您环境的 WIF 提供商指南重新铸造 ANTHROPIC_IDENTITY_TOKEN
# (自安装以来它已经过期)。
export ANTHROPIC_IDENTITY_TOKEN=...
docker compose run --rm setup
export TUNNEL_TOKEN=$(sudo cat data/tunnel-token)
docker compose up -d cloudflared--token-version 参数是在 docker-compose.yaml 中编辑的,而不是在命令行上传递的,这样新值会在设置组件的后续运行中持久保留。设置组件使用 Workload Identity Federation 进行身份验证;没有需要吊销的 API 令牌。
不使用编程访问时,在 Console 的隧道详情页面上点击轮换令牌,然后在每个主机上更新 TUNNEL_TOKEN 环境变量并重启 cloudflared(docker compose up -d cloudflared)。
点击轮换令牌会立即使当前令牌失效。在该时刻与在每个主机上更新 TUNNEL_TOKEN 并重启 cloudflared 之间,任何 cloudflared 重启(崩溃、主机重启)的主机都无法重新连接。轮换后请及时更新每个主机。
您有责任监控过期时间并在服务器证书过期之前进行续期。
使用编程访问时:
docker compose run --rm setup renew-cert --output=dir:/dataCLI 参数会替换 setup 服务的 command(即 init 参数),但保留其 entrypoint,因此这会运行 /setup renew-cert --output=dir:/data。
传递 --renew-before=720h 可使该命令在剩余有效期超过 30 天时不执行任何操作。这使得按固定计划运行它是安全的。
不使用编程访问时,使用您现有的 CA 签署新的服务器证书(在 Console 中注册的 CA 不会更改)并替换 data/tls.crt。如果您是在新的 shell 中运行此操作,请先设置 TUNNEL_DOMAIN。
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.ext在任一流程中,代理都会轮询 tls.cert_file 并自动重新加载它,因此无需重启。
Was this page helpful?