codex-oauth-proxy

module
v0.0.0-...-e9f67e9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2026 License: MIT

README

Codex OAuth Proxy

Codex OAuth Proxy exposes the models included with your ChatGPT Codex access through OpenAI-compatible HTTP endpoints. It handles Codex OAuth credentials, forwards requests to the ChatGPT Codex backend, and translates streaming responses for clients such as OpenCode, editors, and agent tools.

It also provides an MCP server at /mcp. Agents can use it to discover the Codex models available to your account and send one-shot prompts without configuring an OpenAI API client.

  ┌───────────────┐          ┌───────────────────┐          ┌───────────────────────┐
  │ External Tool │          │    Local Proxy    │          │    Codex Backend      │
  │ (OpenCode/etc)│          │                   │          │ (ChatGPT Responses)   │
  └───────┬───────┘          └─────────┬─────────┘          └───────────┬───────────┘
          │                            │                                │
          │  API or MCP request        │    Codex API request           │
          │ ─────────────────────────▶ │ ─────────────────────────────▶ │
          │                            │    OAuth access token          │
          │                            │                                │
          │  API or MCP response       │    Codex API response          │
          │ ◀───────────────────────── │ ◀───────────────────────────── │
          │    JSON or SSE stream      │                                │
          │                            │                                │
          ▼                            ▼                                ▼

Use it when a client supports the OpenAI Chat Completions or Responses API but cannot sign in to Codex directly.

Quick start

You need a ChatGPT account with Codex access and an existing Codex CLI login.

Install the proxy with npm:

npm install -g codex-oauth-proxy

Other installation options:

# mise
mise use -g go:github.com/dvcrn/codex-oauth-proxy/cmd/codex-oauth-proxy@latest

# Go
go install github.com/dvcrn/codex-oauth-proxy/cmd/codex-oauth-proxy@latest

Sign in with the Codex CLI if you have not already, then start the proxy with a key of your choice:

codex login
ADMIN_API_KEY="replace-with-a-long-random-value" codex-oauth-proxy

The server listens on http://localhost:9879 by default. Send the admin key as the bearer token:

curl http://localhost:9879/v1/chat/completions \
  -H "Authorization: Bearer replace-with-your-admin-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "messages": [{"role": "user", "content": "Explain this repository in one sentence."}],
    "stream": false
  }'

Point OpenAI-compatible clients at http://localhost:9879/v1 and use the same admin key as their API key.

Authentication

There are two separate credentials:

  • Codex OAuth credentials authenticate the proxy with the upstream ChatGPT Codex service. The default auto store imports an existing Codex CLI login into $XDG_CONFIG_HOME/codex-oauth-proxy/auth.json (or ~/.config/codex-oauth-proxy/auth.json when XDG_CONFIG_HOME is unset), keeps its token chain separate from the CLI, and refreshes it when needed.
  • ADMIN_API_KEY authenticates clients with your proxy. Protected endpoints accept either Authorization: Bearer <key> or X-API-Key: <key>.

The default credential mode should work for most local installations. Other modes are available when you need an explicit source:

codex-oauth-proxy --creds-store=xdg
codex-oauth-proxy --creds-store=xdg --creds-path=/path/to/auth.json
codex-oauth-proxy --creds-store=legacy

Endpoints

Endpoint Purpose
POST /v1/chat/completions OpenAI-compatible chat completions
POST /v1/responses OpenAI-compatible Responses API
GET /v1/models Models available to the signed-in account, including reasoning-effort variants
POST /mcp Stateless MCP server with ask_codex and ask_codex_models
POST /admin/auth/start Start Workers device authorization
GET /admin/auth/status Read the current device authorization state
POST /admin/auth/status Poll device authorization and store completed credentials
POST /admin/tokens Store Codex credentials manually in Workers KV
GET /admin/status Report whether Workers credentials are configured
GET /health Health check

The model list comes from the Codex backend. Query /v1/models instead of hard-coding model IDs. Clients that cannot set reasoning effort separately can append a suffix such as -low, -medium, -high, -xhigh, or -max when supported by that model.

MCP clients

The /mcp endpoint lets MCP clients use your Codex account through two tools. It uses stateless streamable HTTP with JSON responses, so the server keeps no conversation or session state between calls.

MCP requests use the proxy's Codex OAuth credentials upstream and the same ADMIN_API_KEY as the protected API endpoints. No separate OpenAI API key is required.

MCP configuration varies by client. Configure a streamable HTTP server with:

Setting Value
URL http://localhost:9879/mcp
Header Authorization: Bearer replace-with-your-admin-key

For clients that use an mcpServers JSON object:

{
  "mcpServers": {
    "ask-codex": {
      "type": "http",
      "url": "http://localhost:9879/mcp",
      "headers": {
        "Authorization": "Bearer replace-with-your-admin-key"
      }
    }
  }
}

The client discovers these tools after it connects:

Tool Input Result
ask_codex_models None Available model IDs, display names, and supported reasoning efforts
ask_codex model, prompt The requested model, model that served the request, and response text

Call ask_codex_models first when the model ID is not already known. Reasoning effort can be selected with a model suffix such as gpt-5.5-high when that effort appears in the model listing.

ask_codex is one-shot. It does not retain conversation history, so prompt must include all context needed for that call. The returned model may differ from requested_model when the proxy normalizes a model ID.

Configuration

Setting Default Description
ADMIN_API_KEY required Key used to protect generation, admin, and MCP requests
PORT 9879 Listening port
ENV development Use production for JSON logs
DISABLE_HEALTH_LOGS false Disable request logs for /health
--creds-store auto Credential source for normal Codex CLI logins: auto, xdg, or legacy
--creds-path platform default Credential file for xdg or legacy mode

Deploy to Cloudflare Workers

The ChatGPT Codex endpoints reject direct Cloudflare Workers egress with HTTP 403. A Workers VPC tunnel is therefore required so requests leave through a machine outside Cloudflare's Worker IP ranges.

Install mise, just, and Wrangler 4, then run mise install and wrangler login. The account, namespace, and tunnel IDs checked into wrangler.toml belong to the maintainer deployment and must be replaced for another Cloudflare account.

  1. In Cloudflare Dashboard > Workers VPC > Tunnels, create a remotely managed tunnel. Run the generated cloudflared installer on a machine with normal Internet access. Workers VPC requires cloudflared 2025.7.0 or newer and QUIC access over outbound UDP port 7844. See Cloudflare's tunnel setup.

  2. Create a KV namespace:

    wrangler kv namespace create CODEX_OAUTH_PROXY_KV
    
  3. Put the account ID, returned KV ID, and tunnel UUID in wrangler.toml:

    account_id = "<ACCOUNT_ID>"
    
    kv_namespaces = [
      { binding = "CODEX_AUTH", id = "<KV_NAMESPACE_ID>" }
    ]
    vpc_networks = [
      { binding = "CODEX_EGRESS", tunnel_id = "<TUNNEL_ID>", remote = true }
    ]
    

    The VPC network binding is documented in Cloudflare's VPC Networks guide.

  4. Deploy and set the client-facing admin key at Wrangler's secure prompt:

    wrangler deploy
    wrangler secret put ADMIN_API_KEY
    
  5. Optional: configure a hostname as a Workers Custom Domain instead of creating a CNAME to workers.dev:

    routes = [
      { pattern = "codex.example.com", custom_domain = true }
    ]
    

    Run wrangler deploy again after adding the route.

Authorize Codex on Workers

The device flow is available only in the Workers build. All admin requests require Authorization: Bearer <ADMIN_API_KEY> or X-API-Key: <ADMIN_API_KEY>.

read -rs ADMIN_API_KEY
export ADMIN_API_KEY
BASE_URL="https://<WORKER_NAME>.<SUBDOMAIN>.workers.dev"

curl -X POST "$BASE_URL/admin/auth/start" \
  -H "Authorization: Bearer $ADMIN_API_KEY"

Open the returned verificationUrl, enter userCode, and approve access. Poll no faster than retryAfterSeconds. Stop on authenticated, denied, expired, or failed; the session also expires automatically after 15 minutes:

curl -X POST "$BASE_URL/admin/auth/status" \
  -H "Authorization: Bearer $ADMIN_API_KEY"

curl "$BASE_URL/admin/status" \
  -H "Authorization: Bearer $ADMIN_API_KEY"

POST /admin/tokens provides manual credential setup. It accepts accessToken plus optional refreshToken, accountId, idToken, and RFC 3339 lastRefresh fields. Successful device or manual authorization stores credentials in the configured CODEX_AUTH KV namespace.

Development

mise run test
mise run build

Directories

Path Synopsis
cmd
internal
app
env

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL