MCP 터널 빠른 시작
로컬 Docker Compose 배포를 사용하여 Claude를 비공개 MCP 서버에 연결합니다.
이 빠른 시작 가이드는 터널을 생성하는 것부터 Claude가 해당 터널을 통해 비공개 MCP 서버를 호출하는 것까지 안내합니다. 로컬 테스트를 위한 가장 짧은 경로인 수동 자격 증명 프로비저닝과 함께 Docker Compose를 사용합니다. 프로덕션 배포의 경우 Helm으로 배포 또는 Docker Compose로 배포를 참조하세요.
구축할 내용
두 개의 컨테이너로 구성된 터널 스택(프록시 및 cloudflared)과 함께 실행되는 샘플 MCP 서버입니다. 모든 것이 실행되면, 공개 포트에서 수신 대기하는 것이 없더라도 Claude에서 https://echo.<your-tunnel-domain>/mcp를 통해 샘플 서버에 접근할 수 있습니다.
필요한 것
- 아웃바운드 인터넷 접근이 가능한 머신의 Docker 및 Docker Compose.
- MCP 터널을 관리할 수 있는 Claude Console의 역할. Console 가이드 사전 요구 사항을 참조하세요.
- OpenSSL 1.1.1 이상. macOS와 대부분의 Linux 배포판에는 사전 설치되어 있습니다. Windows에서는 별도로 설치해야 합니다(
openssl바이너리가PATH에 있어야 합니다).
터널 생성
Claude Console에서 MCP 터널 페이지(
platform.claude.com/settings/workspaces/default/mcp-tunnels)로 이동합니다. 각 터널은 하나의 워크스페이스에 속합니다. 사이드바의 워크스페이스 선택기에서 원하는 워크스페이스를 선택하세요. New tunnel을 클릭하고 이름을 지정합니다. Set up programmatic access는 끈 상태로 두세요. 이 빠른 시작에서는 수동 자격 증명 프로비저닝을 사용합니다.생성된 후 터널을 엽니다. Connection 섹션에서 두 가지 값을 복사합니다:
- Domain (
abcd1234.tunnel.anthropic.com과 같은 형태) - Token (눈 아이콘을 클릭한 다음 복사)
- Domain (
배포 디렉터리 설정
mkdir -p mcp-tunnel/{config,data} cd mcp-tunnel export TUNNEL_DOMAIN=YOUR_TUNNEL_DOMAIN_HERE # from step 1 export TUNNEL_TOKEN='eyJ...' # from step 1New-Item -ItemType Directory -Force -Path mcp-tunnel/config, mcp-tunnel/data | Out-Null Set-Location mcp-tunnel $env:TUNNEL_DOMAIN = "YOUR_TUNNEL_DOMAIN_HERE" # from step 1 $env:TUNNEL_TOKEN = "eyJ..." # from step 1CA 및 서버 인증서 생성
프록시는 사용자가 제어하는 CA가 서명한 인증서를 사용하여 내부 TLS를 종료합니다. 두 가지를 모두 생성하세요:
openssl req -x509 -newkey rsa:2048 -nodes \ -keyout data/ca.key -out data/ca.crt \ -days 3650 -subj "/CN=mcp-tunnel-ca" \ -addext "basicConstraints=critical,CA:TRUE" \ -addext "keyUsage=critical,keyCertSign,cRLSign" \ -addext "subjectKeyIdentifier=hash" cat > data/tls.ext <<EOF subjectAltName = DNS:${TUNNEL_DOMAIN},DNS:*.${TUNNEL_DOMAIN} authorityKeyIdentifier = keyid,issuer extendedKeyUsage = serverAuth EOF openssl req -newkey rsa:2048 -nodes \ -keyout 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 chmod 644 data/tls.keyopenssl req -x509 -newkey rsa:2048 -nodes ` -keyout data/ca.key -out data/ca.crt ` -days 3650 -subj "/CN=mcp-tunnel-ca" ` -addext "basicConstraints=critical,CA:TRUE" ` -addext "keyUsage=critical,keyCertSign,cRLSign" ` -addext "subjectKeyIdentifier=hash" @" subjectAltName = DNS:$env:TUNNEL_DOMAIN,DNS:*.$env:TUNNEL_DOMAIN authorityKeyIdentifier = keyid,issuer extendedKeyUsage = serverAuth "@ | Set-Content -NoNewline -Encoding ascii -Path data/tls.ext openssl req -newkey rsa:2048 -nodes ` -keyout data/tls.key -out data/server.csr ` -subj "/CN=$env:TUNNEL_DOMAIN" openssl x509 -req -in data/server.csr ` -CA data/ca.crt -CAkey data/ca.key -CAcreateserial ` -out data/tls.crt -days 90 -extfile data/tls.extConsole로 돌아가 터널 세부 정보 페이지에서 Add certificate를 클릭하고
data/ca.crt를 업로드합니다(또는 내용을 붙여넣습니다). 터널 이름 옆의 Needs certificate 배지가 사라집니다.샘플 MCP 서버 작성
cat > 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@' 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") '@ | Set-Content -NoNewline -Encoding ascii -Path hello_server.py프록시 구성 및 compose 파일 작성
cat > config/mcp-proxy.yaml <<EOF listen_addr: ":8080" tunnel_domain: ${TUNNEL_DOMAIN} tls: cert_file: /data/tls.crt key_file: /data/tls.key routes: echo: http://hello-mcp:9000 EOF cat > docker-compose.yaml <<'EOF' services: mcp-proxy: image: us-docker.pkg.dev/anthropic-public-registry/images/mcp-proxy@sha256:d243d30642d39857a0579e465cb3b9bf3ae7c1141e83143bb6856777a31467a5 volumes: - ./config/mcp-proxy.yaml:/etc/mcp-gateway/config.yaml:ro - ./data:/data:ro restart: unless-stopped cloudflared: image: cloudflare/cloudflared@sha256:0e56c13c7058fcef9c4f0e7d83372f82330548dbf8f8b366f3d8b506526d93b2 command: tunnel --no-autoupdate run --url http://localhost:8080 environment: - TUNNEL_TOKEN network_mode: "service:mcp-proxy" restart: unless-stopped 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@" listen_addr: ":8080" tunnel_domain: $env:TUNNEL_DOMAIN tls: cert_file: /data/tls.crt key_file: /data/tls.key routes: echo: http://hello-mcp:9000 "@ | Set-Content -NoNewline -Encoding ascii -Path config/mcp-proxy.yaml @' services: mcp-proxy: image: us-docker.pkg.dev/anthropic-public-registry/images/mcp-proxy@sha256:d243d30642d39857a0579e465cb3b9bf3ae7c1141e83143bb6856777a31467a5 volumes: - ./config/mcp-proxy.yaml:/etc/mcp-gateway/config.yaml:ro - ./data:/data:ro restart: unless-stopped cloudflared: image: cloudflare/cloudflared@sha256:0e56c13c7058fcef9c4f0e7d83372f82330548dbf8f8b366f3d8b506526d93b2 command: tunnel --no-autoupdate run --url http://localhost:8080 environment: - TUNNEL_TOKEN network_mode: "service:mcp-proxy" restart: unless-stopped 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 '@ | Set-Content -NoNewline -Encoding ascii -Path docker-compose.yaml시작하기
docker compose up -d docker compose logs mcp-proxy | grep "route configured" docker compose logs cloudflared | grep "Registered tunnel connection"docker compose up -d docker compose logs mcp-proxy | Select-String "route configured" docker compose logs cloudflared | Select-String "Registered tunnel connection"echo에 대한route configured줄 하나와Registered tunnel connection줄 네 개가 표시되어야 합니다. 컨테이너가 시작되는 데 몇 초가 걸리므로, 로그 명령이 빈 결과를 반환하면 다시 실행하세요.Claude에서 호출하기
Console에서 Sessions 페이지(
platform.claude.com/sessions)로 이동하여 세션을 생성합니다. 에이전트 선택기에서 Create new agent를 선택하고, 에이전트 이름을 지정한 후 미리 채워진 모델을 그대로 유지합니다. + MCP Server를 클릭하고 터널을 선택한 다음, Subdomain을echo로, Path를mcp로 설정합니다. 그런 다음 다음과 같이 요청합니다:Use the hello tool to greet tunnel.
도구 호출과 그 결과가 표시되어야 합니다.
다음 단계
터널이 처음부터 끝까지 검증되었습니다. 자체 MCP 서버로 교체하려면 docker-compose.yaml에 추가하고(또는 동일한 Docker 네트워크에서 실행하고), config/mcp-proxy.yaml에 해당 서버의 경로를 추가한 다음 프록시를 재시작하세요(docker compose restart mcp-proxy).
프로덕션 배포의 경우:
프로그래밍 방식 접근 여부와 관계없이 사용할 수 있는 강화된 단일 호스트 배포입니다.
자동 자격 증명 관리를 갖춘 Kubernetes 배포입니다.
Was this page helpful?