Secure MCP Tunnel Client
Connect private or localhost MCP servers to OpenAI products without exposing them to the public internet.
The evidence clearly separates runtime and administrative keys, specifies minimum role permissions, and describes HTTPS long-polling, MCP forwarding, OAuth metadata retrieval, instance identifiers, and admin-UI data flows. Tokens can be supplied through environment references or separate secret files; mTLS and redacted support bundles are documented. Release automation pins GitHub Actions by commit and produces SHA-256 files, container SBOMs, and provenance attestations, but checksum signing remains optional and commented out, so dependency security is not full. Administrative CRUD, profile writes, runtime lifecycle operations, and plugin installation/removal are disclosed, but the supplied files do not establish interactive confirmation for each consequential action; user confirmation and external effects are therefore partial. Stop, rm, uninstall, and foreground-operation paths provide rollback options, but recovery from tunnel deletion or overwritten configuration is not fully documented. Repository, module, image-source, license, and verified OpenAI publisher information provide strong attribution.
The README, module manifest, and release workflows agree on module identity, Go version, platform matrix, semantic versioning, and the bundled cloudflared companion. CI downloads modules, runs the Go suite, validates release and companion versions, verifies public artifact URLs, and smoke-tests Homebrew installation. doctor --explain, health/readiness endpoints, explicit runtime status fields, and concrete workflow errors provide thorough failure feedback. Dependencies are version constrained and releases cover major desktop/server architectures, but operation still depends on the OpenAI control plane, networking, and external MCP services; continued artifact availability cannot be established from these static files, so dependency availability is reduced.
The material explicitly addresses laptops, VMs, Kubernetes, private networks, foreground daemons, managed local runtimes, containers, Homebrew, source builds, and an in-process Go SDK, with scenarios for ChatGPT, Codex, the Responses API, AgentKit, and compatible-client implementers. Boundaries are stated for main and additional channels, Harpoon registration, supported MCP transports, the OAuth metadata source, and optional backends. Precise command trees, startup prerequisites, success fields, and supervision choices make invocation conditions clear. Cross-platform artifacts, proxy/private-CA samples, mTLS, stdio/HTTP/in-memory transports, and startup-wait configuration provide strong environment fit, with no concrete deduction warranted by the supplied evidence.
The README offers task-oriented entry points, a detailed documentation map, installation and build commands, configuration provenance, examples, troubleshooting routes, and a runnable SDK example. Commands and environment variables are consistently named, and migration compatibility for the older singular API path is documented. Apache-2.0 metadata matches the complete LICENSE. Semantic tags, embedded source versions, stable/prerelease alias rules, and generated release notes exist, but no standalone changelog content is supplied, reducing versioning/changelog. Some constraints are explicit, including platform coverage, optional Rust/Redis build requirements, daemon-liveness requirements, and legacy-path migration; however, the referenced roadmap and troubleshooting contents are absent, so a comprehensive limitations record cannot be confirmed. Official organization provenance, release automation, and stated cloudflared security-patch ownership make maintenance responsibility and the update path clear.
The outputs are operationally usable: guided initialization, configuration diagnostics, health/readiness/metrics endpoints, an admin UI, structured JSON status, redacted support bundles, several deployment formats, and a runnable SDK example. The marginal value is concrete: private MCP services can reach OpenAI-hosted products without a new inbound firewall rule or public service exposure, while gaining observability and local supervision. Basic tradeoffs are disclosed, including a continuously running daemon, control-plane dependency, bundled cloudflared, permissions and key setup, and deployment choices. Resource consumption, latency, capacity, and operating-cost evidence are absent, so cost/benefit is not full.
Major claims map to concrete commands, environment variables, HTTP routes, headers, status fields, platform matrices, and workflow steps. License, module identity, version policy, and release coverage in the README are corroborated by LICENSE, go.mod, and the two workflows; commit-pinned actions, version checks, checksums, SBOM generation, and provenance attestations improve auditability. However, many runtime security and behavior claims appear only in the README, while the supplied evidence omits core implementation files and corresponding tests needed to corroborate them individually. Some product assertions are also not explicitly separated as design intent versus verified behavior, reducing fact/inference separation.
- This is a low-confidence static review; no binary, tests, network connection, installation path, or published artifact was executed or independently verified.
- Core tunnel, credential-handling, redaction, administrative CRUD, and runtime-supervision implementations were not supplied, so the corresponding README claims are not independently confirmed.
- Release archives have SHA-256 checksums, but the workflow's GPG-signing section is optional and commented out. Production users should pin an exact version or digest and verify artifacts through a trusted channel.
- The client relays private MCP requests and responses through the OpenAI control plane and may retrieve OAuth metadata. Review data classification, log-redaction coverage, organization permissions, and the side effects of the connected MCP tools before deployment.
- Administrative commands include tunnel deletion, runtime commands include rm, and initialization writes configuration. The supplied material does not fully demonstrate per-action confirmation or recovery from operator mistakes.
What does this agent do, and when should you use it?
Secure MCP Tunnel Client is a customer-run Go client that connects an MCP server on a laptop, VM, Kubernetes cluster, or private network to an OpenAI-hosted tunnel endpoint. It long-polls the OpenAI control plane over HTTPS, receives JSON-RPC requests, and forwards them to the target MCP server over Streamable HTTP, stdio, or an in-memory transport. The repository provides a CLI, an embeddable Go SDK, native runtime-management commands, and Codex assistant and plugin entry points. Its operational surface includes `/healthz`, `/readyz`, `/metrics`, and `/ui`, along with live log-level control and redacted support-bundle export. It fits organizations that can permit outbound access to OpenAI but cannot approve a public MCP endpoint; the core path depends on OpenAI Secure MCP Tunnel rather than offering a provider-neutral tunnel.
At startup, the client calls GET /v1/tunnels/{tunnel_id} for tunnel metadata and fetches OAuth Protected Resource Metadata from the MCP server for diagnostics. It then long-polls GET /v1/tunnels/{tunnel_id}/poll, routes received requests to the main binding, an additional configured channel, or a registered harpoon target, invokes the MCP server over Streamable HTTP, stdio, or Go in-memory transport, and submits results through POST /v1/tunnels/{tunnel_id}/response. It can relay Streamable HTTP session termination, present a separate client certificate and key to the control plane, and automatically select the OpenAI mTLS host when appropriate. tunnel-client init writes a validated profile, doctor --explain diagnoses missing startup requirements, run starts the foreground poller, and runtimes create|connect|list|status|stop|rm manages supervised local runtimes. The admin server publishes health, readiness, and Prometheus metrics; its UI exposes instance and channel state, runtime log controls, and a redacted bundle containing recent logs, a metrics snapshot, and runtime YAML.
- An enterprise platform team needs ChatGPT to call an MCP server inside a Kubernetes private network, while security policy prohibits public endpoints and new inbound firewall rules.
- A developer has a localhost MCP server on a laptop and wants a short CLI path to use it from ChatGPT or Codex.
- An operations team needs a long-running tunnel daemon with health probes, readiness checks, Prometheus metrics, and a local UI for production troubleshooting.
- A Go service author wants the MCP server and tunnel client in one process, using
mcp.NewInMemoryTransports()instead of binding a port or using stdio. - A team operating behind an outbound proxy, private PKI, mTLS, or Cloudflare tunnel wants documented configuration samples and deployment paths.
- A Codex user wants a supervised local connection through
runtimes connectand explicit process, health, and readiness checks before declaring it operational.
What are this agent's strengths and limitations?
- Customer-initiated long polling avoids exposing the private MCP server through a public endpoint or adding an inbound firewall rule.
- Streamable HTTP, stdio, and Go in-memory MCP transports cover network services, local child processes, and same-process embedding.
- Built-in health, readiness, Prometheus metrics, admin UI, live log-level changes, and redacted support bundles provide a substantial operator-facing surface.
- The project documents Homebrew, source, Docker, Kubernetes, and VM paths, and release artifacts bundle a pinned
cloudflaredcompanion for listed operating systems and architectures. - Runtime and administrative credentials are separated, with explicit Read, Use, and Manage permission requirements.
- The core connection depends on the OpenAI-hosted Secure MCP Tunnel control plane, so it is not a provider-neutral MCP tunneling layer.
- Adoption requires a tunnel ID, a runtime API key, and correctly assigned organization permissions; tunnel administration may also require a separate admin key.
- Connector discovery and every remote MCP call depend on the customer-run process remaining active, healthy, and ready.
- Building from source requires Go, and rebuilding the Svelte-based admin UI adds a separate asset-generation step.
- Production users of release images or the Cloudflare companion must manage exact versions or digests, supported architectures, and security-update ownership.
How do you install or deploy this agent?
Install the official Homebrew formula:
brew install openai/tools/tunnel-client
tunnel-client --version
tunnel-client help quickstartA source build requires the Go toolchain:
go build ./...
go test ./...
make admin-ui
go build -o bin/tunnel-client ./cmd/client
./bin/tunnel-client help quickstartFor an embedded Go integration:
go get github.com/openai/tunnel-clientBefore first use, obtain a CONTROL_PLANE_TUNNEL_ID and create a separate runtime API key, CONTROL_PLANE_API_KEY, whose principal has Tunnels Read + Use. OPENAI_ADMIN_KEY is only for tunnel-client admin tunnels list|create|update|delete; it must not be used by the long-running daemon.
How do you use this agent?
Create and validate a profile for a local stdio MCP server:
tunnel-client profiles samples list
tunnel-client profiles samples show sample_mcp_stdio_local
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-stdiorun keeps the daemon attached to the current terminal, and it must remain active for connector discovery and every MCP request. For a long-lived runtime managed by Codex, use tunnel-client runtimes connect ..., followed by tunnel-client runtimes status <alias>; automation can add --json and inspect process_running, healthy, and ready. Create or verify the ChatGPT connector only while the client is healthy. For managed Cloudflare provisioning, a documented invocation is:
tunnel-client run --cloudflared.managed --control-plane.tunnel-id tunnel_0123456789abcdef0123456789abcdef --mcp.server-url https://mcp.example.com/mcpHow does this agent compare with similar options?
Compared with placing an MCP server on a public endpoint, this client uses outbound HTTPS long polling from the customer network to the OpenAI control plane and avoids a new inbound firewall rule. tunnel-client run is the foreground option attached to the current terminal, whereas tunnel-client runtimes connect is the documented choice for a long-lived local runtime managed by Codex. The raw binary offers the smallest setup surface, tunnel-client codex assistant provides a Codex-native terminal path, and the embedded plugin exposes the native runtimes and admin-profiles workflows inside Codex. For MCP connectivity, Streamable HTTP targets network services, stdio targets local processes, and the Go SDK's in-memory transport targets same-process embedding.
FAQ
Does the MCP server need an inbound public port?
Which permissions does the runtime credential need?
CONTROL_PLANE_API_KEY need Tunnels Read + Use. Tunnel managers need Read + Manage, plus Use if they also run the daemon or attach ChatGPT connectors.How should operators verify a successful connection?
tunnel-client doctor --profile <name> --explain first. For a managed runtime, also run tunnel-client runtimes status <alias> and only report success when the process is running with health reported; JSON output exposes process_running, healthy, and ready explicitly.Can it be embedded without running a separate MCP network service?
tunnelclient.New through mcp.NewInMemoryTransports(), so the server does not need to bind a port or use stdio.