by openai
Customer-run client for Secure MCP Tunnel: connect private or localhost MCP servers to ChatGPT, Codex, the Responses API, and AgentKit without exposing them to the public internet.
# Add to your Claude Code skills
git clone https://github.com/openai/tunnel-clientGuides for using ai agents skills like tunnel-client.
Last scanned: 8/4/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-08-04T06:27:27.460Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}tunnel-client is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by openai. Customer-run client for Secure MCP Tunnel: connect private or localhost MCP servers to ChatGPT, Codex, the Responses API, and AgentKit without exposing them to the public internet. It has 221 GitHub stars.
Yes. tunnel-client passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/openai/tunnel-client" and add it to your Claude Code skills directory (see the Installation section above).
tunnel-client is primarily written in Go. It is open-source under openai on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh tunnel-client against similar tools.
No comments yet. Be the first to share your thoughts!
tunnel-client is the customer-run agent behind Secure MCP Tunnel. It connects
a private or localhost MCP (Model Context Protocol) server to ChatGPT, Codex,
the Responses API, and AgentKit through an OpenAI-hosted MCP tunnel endpoint,
while keeping the MCP server off the public internet.
Use it when:
/healthz, /readyz, /metrics,
and /ui before a connector or API call depends on it.If you searched for "secure MCP tunnel", "MCP tunnel ChatGPT", "connect local
MCP server to ChatGPT", "connect local MCP server to Codex", "localhost to
ChatGPT", or "Codex local MCP", start with tunnel-client help quickstart,
then read the onboarding guide below.
docs/onboarding.md.docs/architecture.md.docs/permissions.md.docs/deployment/overview.md.docs/troubleshooting.md.docs/protocol.md and use
docs/openapi.json.examples/go-sdk-inmemory.The module can run in the same process as a Go MCP server. The MCP server does
not need to bind a port or use stdio: give the server side of an in-memory MCP
transport pair to your server and the client side to tunnelclient.New.
go get github.com/openai/tunnel-client
import (
"context"
"github.com/modelcontextprotocol/go-sdk/mcp"
tunnelclient "github.com/openai/tunnel-client"
)
ctx := context.Background()
server := mcp.NewServer(&mcp.Implementation{Name: "my-server", Version: "1.0.0"}, nil)
serverTransport, tunnelTransport := mcp.NewInMemoryTransports()
go server.Run(ctx, serverTransport)
client, err := tunnelclient.New(tunnelclient.Config{
TunnelID: "tunnel_0123456789abcdef0123456789abcdef",
APIKey: apiKey,
}, tunnelTransport)
if err != nil {
return err
}
return client.Run(ctx)
The runnable Go SDK example registers an echo
tool and connects it to the OpenAI Tunnel control plane.
developers.openai.com/api/docs/guides/secure-mcp-tunnelsdocs/end-user-guide.mddocs/onboarding.mddocs/permissions.mddocs/architecture.mddocs/connectors.mddocs/protocol.mddocs/openapi.jsondocs/enterprise-customer-onboarding.mddocs/configuration.mddocs/deployment/overview.mddocs/deployment/cloudflared.mddocs/troubleshooting.mddocs/development.mdexamples/go-sdk-inmemorydocs/roadmap.mdTo generate the shareable guide output locally:
make end-user-guide-screenshots
make end-user-guide-html
make end-user-guide-slides
If you want the shortest supported path from a local or localhost MCP server to
ChatGPT or Codex, start with tunnel-client help quickstart. For Codex plugin
lifecycle work, use the native tunnel-client runtimes ... and
tunnel-client admin-profiles ... command trees surfaced by
tunnel-client help plugin.
Supervision choice:
tunnel-client run ... when you intentionally want a foreground daemon
attached to the current terminal.tunnel-client runtimes connect .... Do not use nohup or disown as the
tunnel-client supervision path.runtimes connect, check tunnel-client runtimes status <alias>
before reporting success. Only report success when status shows the managed
runtime running with health reported. Use --json when Codex needs the
explicit process_running, healthy, and ready fields.Use these exact setup pages during first use:
https://platform.openai.com/settings/organization/tunnelshttps://platform.openai.com/settings/organization/people/roleshttps://platform.openai.com/settings/organization/people/groupshttps://platform.openai.com/settings/organization/api-keyshttps://platform.openai.com/settings/organization/admin-keyshttps://chatgpt.com/#settings/ConnectorsWhich value comes from where:
CONTROL_PLANE_TUNNEL_ID: create or inspect it in Tunnels management, or via
tunnel-client admin tunnels create|list|get ... with OPENAI_ADMIN_KEY.CONTROL_PLANE_API_KEY: create it in Runtime API keys; this is the key used
by tunnel-client doctor and tunnel-client run.OPENAI_ADMIN_KEY: only for tunnel-client admin tunnels list|create|update|delete. Do not use the admin key for the long-lived
daemon.Required tunnel permissions:
CONTROL_PLANE_API_KEY need
Tunnels Read + Use.See docs/permissions.md for the group/role workflow
and screenshots.
Binary-first flow:
tunnel-client help quickstart
tunnel-client profiles samples list
tunnel-client profiles samples show sample_mcp_enterprise_proxy
tunnel-client init --sample sample_mcp_stdio_local --profile local-stdio --tunnel-id tunnel_0123456789abcdef0123456789abcdef --mcp-command "python /path/to/server.py"
tunnel-client doctor --profile local-stdio --explain
tunnel-client run --profile local-stdio
tunnel-client run --profile-file ./profiles/local-stdio.yaml
If you need the tunnel id or runtime/admin keys first, open the matching URL
above before running init. If your rollout has self-serve tunnel access,
create the tunnel yourself in Tunnels management or with
tunnel-client admin tunnels create, then export the returned id as
CONTROL_PLANE_TUNNEL_ID and a separate runtime key as
CONTROL_PLANE_API_KEY. Create or verify the connector from the ChatGPT
settings URL above only while tunnel-client run ... is healthy, and keep the
daemon running for connector discovery and every MCP call from ChatGPT.
The Platform Tunnels page download button is sourced from tunnel-service's gated tunnel metadata response. When a new public tunnel-client release becomes the supported download, update tunnel-service's hard-coded public artifact URL alongside the release handoff.
Validate a source checkout with native Go tooling:
go build ./...
go test ./...
Build the CLI binary:
make admin-ui
go build -o bin/tunnel-client ./cmd/client
./bin/tunnel-client help quickstart
Public releases use plain semantic-version tags such as v0.0.10. Source
archives from release tags carry the release version in
pkg/version/VERSION. A plain go build from a downloaded release .tar.gz
therefore reports the tag semantic version through tunnel-client --version,
User-Agent, and the explicit control-plane version headers.
Supported release archives also bundle pinned cloudflared 2026.7.2 beside
the CLI for Linux amd64/arm64, macOS amd64/arm64, and Windows
amd64/arm64.
Docker images bundle the Linux amd64/arm64 companion. For a logical tunnel
created with managed Cloudflare provisioning, let the authenticated client fetch
the runtime token and start the companion without distributing a static token:
tunnel-client run \
--cloudflared.managed \
--control-plane.tunnel-id tunnel_0123456789abcdef0123456789abcdef \
--mcp.server-url https://mcp.example.com/mcp
For a pre-provisioned Cloudflare tunnel, a static token remains available as an explicit override and is never put in argv:
export CLOUDFLARED_TOKEN='...'
tunnel-client run \
--cloudflared.token env:CLOUDFLARED_TOKEN \
--control-plane.tunnel-id tunnel_0123456789abcdef0123456789abcdef \
--mcp.server-url https://mcp.example.com/mcp
See docs/deployment/cloudflared.md for
platform coverage, readiness/failure behavior, Go module provenance, and
security-update ownership.
If an operator intentionally runs cloudflared without `t