Quickstart:

If you searched for "How do I connect local MCP server to ChatGPT",
"How do I connect local MCP server to Codex", "localhost to ChatGPT", or
"Codex local MCP", start with tunnel-client. Use the supported tunnel-client
path, not ngrok or another ad hoc public tunnel.

Fastest install/build path:
  tunnel-client already installed on PATH:
    tunnel-client help quickstart

  Source checkout with no launcher yet:
    make admin-ui
    go build -o bin/tunnel-client ./cmd/client
    ./bin/tunnel-client help quickstart

What tunnel-client is for:
  tunnel-client runs the long-lived daemon that connects a local or private MCP server
  to the OpenAI control plane over an outbound tunnel. Once running, it exposes local
  operator surfaces at /healthz, /readyz, and /ui.

Canonical setup URLs:
  Tunnels management: 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 use
    `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 the daemon
    uses for `tunnel-client doctor` and `tunnel-client run`.
  - `OPENAI_ADMIN_KEY`: only for `tunnel-client admin tunnels list|create|update|delete`.
    Do not give the admin key to the long-lived daemon.

Tunnel permission split:
  - Runtime users and the principal that creates CONTROL_PLANE_API_KEY need Tunnels Read + Use.
  - Tunnel CRUD operators need Tunnels Read + Manage.
  - Admin-key creators need Platform admin-key permission separately.
  - Full role/group guidance lives in docs/permissions.md.

Pick the shortest matching starter sample:

0. One-command demo path with the embedded MCP server:
   tunnel-client run --embedded-mcp-stub --control-plane.tunnel-id tunnel_... --health.listen-addr 127.0.0.1:0 --health.url-file /tmp/tunnel-client-health.url
   After startup:
   curl -fsS "$(cat /tmp/tunnel-client-health.url)/readyz"
   open "$(cat /tmp/tunnel-client-health.url)/ui"

1. Local stdio MCP command:
   tunnel-client init --sample sample_mcp_stdio_local --profile local-stdio --tunnel-id tunnel_... --mcp-command "python /path/to/server.py"

2. Remote HTTP MCP server with no OAuth/PRMD metadata:
   tunnel-client init --sample sample_mcp_remote_no_auth --profile remote-http --tunnel-id tunnel_... --mcp-server-url https://mcp.example.com/mcp

3. HTTP or stdio MCP target behind an outbound proxy or private PKI:
   export HTTPS_PROXY="http://proxy.internal.example.com:8080"
   export ENTERPRISE_CA_BUNDLE="/etc/ssl/certs/proxy-root.pem"
   tunnel-client init --sample sample_mcp_enterprise_proxy --profile corp-proxy --tunnel-id tunnel_... --mcp-server-url https://mcp.internal.example.com/mcp

4. HTTP MCP server with OAuth/DCR metadata, or when you want to exercise the full contract:
   tunnel-client dev mcp-stub
   tunnel-client init --sample sample_mcp_with_dcr --profile sample_mcp_with_dcr --tunnel-id tunnel_... --mcp-server-url http://127.0.0.1:NNNN/mcp

Then validate and start:
  tunnel-client doctor --profile <name> --explain
  tunnel-client run --profile <name>

ChatGPT connector note:
  Create or verify the connector in ChatGPT settings only while tunnel-client is running.
  Keep tunnel-client up for connector discovery and every MCP call from ChatGPT.

If you used the embedded demo MCP server and connected the tunnel in ChatGPT, try:
  - Use the server_info tool and summarize the demo MCP server.
  - Use the echo tool with input "hello from tunnel-client".
  - Use the uppercase tool on "openai tunnel".

Starter prompts for Codex:
  - "Figure out what tunnel-client is for from the binary help, then get me to /ui with the shortest local path."
  - "Use tunnel-client to create or reuse a profile, run doctor --explain, and then start the daemon."
  - "Run tunnel-client codex assistant and summarize what this checkout is for in one sentence."
  - "Install the Codex plugin from the tunnel-client binary, connect the provided tunnel id, and tell me whether the runtime is launched, healthy, or ready."

If you already know a tunnel id and only need metadata:
  tunnel-client admin tunnels get tunnel_...     # runtime key or admin key
  tunnel-client admin --json tunnels get tunnel_...   # inspect organization_ids/workspace_ids for admin CRUD scope

If you need create/list/update/delete:
  tunnel-client admin tunnels ...                # admin key required

If your rollout has self-serve tunnel access:
  - create the tunnel yourself in Tunnels management or with `tunnel-client admin tunnels create`
  - use the returned tunnel id as `CONTROL_PLANE_TUNNEL_ID`
  - create a separate runtime key from Runtime API keys and export it as `CONTROL_PLANE_API_KEY`
  - make sure the runtime-key principal has Tunnels Read + Use for the tunnel

Useful follow-ups:
  tunnel-client codex assistant "Summarize what tunnel-client is for."
  tunnel-client codex plugin install
  tunnel-client runtimes list
  tunnel-client profiles samples list
  tunnel-client profiles samples show sample_mcp_stdio_local
  tunnel-client profiles samples show sample_mcp_remote_no_auth
  tunnel-client profiles samples show sample_mcp_enterprise_proxy
  tunnel-client help samples
  tunnel-client help oauth
  tunnel-client help plugin
  tunnel-client help troubleshooting
