tunnel-client
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.
Install / Use
claude mcp add openai -- npx -y github:openai/tunnel-clientIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
AutomationSupported Platforms
Our assessment of tunnel-client
tunnel-client scores 92/100 on our quality scale, 766th of 2,871 Automation skills we index (top 27%).
Its MCP Server is 36 KB long, well organised into 16 sections with 21 code examples: a thorough specification that gives an agent plenty to work with.
It has 616 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated today, so tunnel-client is actively maintained.
- Our last check on 2026-10-18 found the source still online.
- It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.
AI review by kimi-k2.7-code on 2026-09-24. Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
tunnel-client compared with similar skills
All 4 of these similar skills score higher than tunnel-client; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| tunnel-client (this skill)by openai | 92 | 616 | today | MCP Server |
| Agent-Reachby Panniantong | 100 | 108.6k | today | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 78.8k | today | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.8k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 96.0k | today | MCP Server |
Frequently asked questions
- How do I install tunnel-client?
- Run
claude mcp add openai -- npx -y github:openai/tunnel-client. The install tabs above show the steps for each supported agent. - Which AI agents does tunnel-client work with?
- It is written for Claude Code, Claude Desktop and OpenAI Codex, as a MCP Server file. Other agents that read the same format can often use it too.
- Is tunnel-client safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It is Apache-2.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is tunnel-client still maintained?
- The repository was last updated today, so tunnel-client is actively maintained.
Skill content
View source on GitHubSecure MCP Tunnel client
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:
- You have an MCP server on a laptop, VM, Kubernetes cluster, or private network and need an OpenAI-hosted product to reach it.
- Security will not approve a new inbound firewall rule or public endpoint for the MCP server.
- You want an operator-visible daemon with
/healthz,/readyz,/metrics, and/uibefore 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.
Start Here
- Need the shortest working path from localhost or a private MCP server to
ChatGPT or Codex? Start with
docs/onboarding.md. - Need the customer-shareable network and trust-boundary story? Read
docs/architecture.md. - Need roles, groups, tunnel IDs, or API keys? Read
docs/permissions.md. - Need Docker, Kubernetes, or VM deployment guidance? Read
docs/deployment/overview.md. - Need to debug readiness, connector discovery, or OAuth? Read
docs/troubleshooting.md. - Building a compatible client in another language? Read
docs/protocol.mdand usedocs/openapi.json. Optional client features use the commonX-Tunnel-Client-Capabilitiesheader. - Upgrading for server-directed polling placement? Read the routing correction and activation notes. Supporting clients work with existing services immediately; corrections are enabled separately after client release. No configuration change is needed.
- Embedding an MCP server directly in a Go process? Use the Go SDK with
the MCP SDK's in-memory transport; see
examples/go-sdk-inmemory.
Try the embedded demo
With a runtime API key and tunnel ID, run the built-in server_info, echo,
and uppercase tools without a separate MCP server:
export CONTROL_PLANE_API_KEY="sk-..."
export CONTROL_PLANE_TUNNEL_ID="tunnel_0123456789abcdef0123456789abcdef"
tunnel-client run --embedded-stateless-mcp-stub --health.listen-addr 127.0.0.1:0
--embedded-stateless-mcp-stub uses stateless MCP handling even when a client
sends initialize and notifications/initialized. It issues no MCP session
ID, and these demo tools do not require MCP session affinity between processes.
OAuth and application state have separate requirements.
--embedded-mcp-stub keeps its existing compatibility behavior: legacy
initialization and session requests use stateful handling; self-contained
modern discovery and tool requests use stateless handling. Choose one embedded
mode per run. Both share the embedded listen-address, Unix-socket, server-name, and
server-version options; see embedded demo configuration
for defaults and target conflicts.
Embed as a Go SDK
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.
Documentation Map
- Public Secure MCP Tunnel guide:
developers.openai.com/api/docs/guides/secure-mcp-tunnels - Shareable end-user guide:
docs/end-user-guide.md - Start here:
docs/onboarding.md - Permissions, roles, and groups:
docs/permissions.md - Architecture diagrams:
docs/architecture.md - Connector behavior:
docs/connectors.md - Wire protocol for client implementers:
docs/protocol.md - OpenAPI contract:
docs/openapi.json - Enterprise customer handoff:
docs/enterprise-customer-onboarding.md - Configuration reference:
docs/configuration.md - Deployment guides:
docs/deployment/overview.md - Bundled Cloudflare companion:
docs/deployment/cloudflared.md - Troubleshooting:
docs/troubleshooting.md - Development & testing:
docs/development.md - In-memory Go SDK example:
examples/go-sdk-inmemory - Roadmap / design notes:
docs/roadmap.md
Install with Homebrew
On macOS, Homebrew is the supported installation path. Directly downloaded
release ZIPs are not currently notarized and can be blocked by Gatekeeper. If
a manually downloaded archive is blocked, do not use xattr, spctl, or
Open Anyway to bypass the check; install from the official OpenAI tap
instead:
brew install openai/tools/tunnel-client
Verify the installed version, then start with the guided setup:
tunnel-client --version
tunnel-client help quickstart
The Formula installs the matching tunnel-client, bundled cloudflared,
and companion manifest together, while exposing only the tunnel-client
command. For Docker, Kubernetes, or VM deployments, see
docs/deployment/overview.md.
To generate the shareable guide output locally:
make end-user-guide-screenshots
make end-user-guide-html
make end-user-guide-slides
For Codex / Copilot
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:
- Use
tunnel-client run ...when you intentionally want a foreground daemon attached to the current terminal. - For a long-lived local runtime managed by Codex, prefer
tunnel-client runtimes connect .... Do not usenohupordisownas the tunnel-client supervision path. - After
runtimes connect, checktunnel-client runtimes status <alias>before reporting success. Only report success when status shows the managed runtime running with health reported. Use--jsonwhen Codex needs the explicitprocess_running,healthy, andreadyfields.
Use these exact setup pages during first use:
- Tunnels management and supported tunnel-client download:
https://platform.openai.com/settings/organization/tunnels - Organization roles:
https://platform.openai.com/settings/organization/people/roles - Organization groups:
https://platform.openai.com/settings/organization/people/groups - Runtime API keys:
https://platform.openai.com/settings/organization/api-keys - Admin API keys:
https://platform.openai.com/settings/organization/admin-keys - ChatGPT connector settings:
https://chatgpt.com/#settings/Connectors
Which value comes from where:
CONTROL_PLANE_TUNNEL_ID: create or inspect it in Tunnels management, or viatunnel-client admin tunnels create|list|get ...withOPENAI_ADMIN_KEY.CONTROL_PLANE_API_KEY: create it in Runtime API keys; this is the key used bytunnel-client doctorandtunnel-client run.OPENAI_ADMIN_KEY: only fortunnel-client admin tunnels list|create|update|delete. Do not use the admin key for the long-lived daemon.
Required tunnel permissions:
- Runtime users and the principal that creates
CONTROL_PLANE_API_KEYneed Tunnels Read + Use. - Tunnel managers need Tunnels Read + Manage, plus Use if they also run the daemon or attach ChatGPT connectors.
- Admin-key creators need the Platform admin-key permission in addition to any tunnel permissions they need.
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
Stdio deployment limit: run only one active tunnel-client instance per
tunnel ID when using --mcp.command / MCP_COMMAND. Multiple active instances
sharing that tunnel ID are not supported, including overlap during a
restart. Each instance launches a separate MCP child, and initialization and
later requests can reach different children. Stop the old instance before
starting its replacement, or use distinct tunnel IDs for independent instances.
See stdio deployment limits.
Stdio initialization is checked automatically. Legacy calls require a successful
initialize exchange followed by notifications/initialized; premature calls
return mcp_initialization_required immediately. Self-contained MCP requests
using protocol version 2026-07-28 or later pass through without a handshake.
The caller owns initialization, including after child replacement. See
configuration for lifecycle behavior.
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 ./...
Independent tests, subtests, and fuzz seed cases use t.Parallel(). Give each
case its own mutable fixtures, and use t.Cleanup for resources shared by
parallel children. Keep dependent state transitions in one test. Keep tests
that mutate process-wide globals, environment variables, signals, or stdio
serial.
Check concurrent execu
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
108.6kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
78.8kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
47.8kOpen-source personal AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Scrapling
96.0k🕷️ The BEST Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
