Codex CLI and Codex Desktop

Codex Pooler supports both Codex CLI and Codex Desktop through the Codex backend compatibility route. Both Codex surfaces share the same configuration layers and user-level CODEX_HOME/config.toml, so one provider block can serve the terminal and desktop/IDE experience.
Use /backend-api/codex, not the OpenAI-compatible /v1 SDK surface. Put provider and auth settings in the user-level config file; Codex’s project-local .codex/config.toml layers are trust-gated and do not override machine-local provider keys such as model_provider or model_providers.
Config file path
Section titled “Config file path”Codex resolves CODEX_HOME first. If CODEX_HOME is unset, current Codex sources default it to $HOME/.codex on every OS, so the user config file is CODEX_HOME/config.toml.
| OS | Default config file |
|---|---|
| macOS | $HOME/.codex/config.toml |
| Linux | $HOME/.codex/config.toml |
| Windows | $HOME\.codex\config.toml, normally %USERPROFILE%\.codex\config.toml |
Codex Desktop and the IDE extension open the same file from Codex Settings > Open config.toml.
For a deployed instance, the Codex backend base URL is:
https://codex-pooler.example.com/backend-api/codexFor local setup and local connection checks, use:
http://localhost:4000/backend-api/codexKeep your Pool API key in an environment variable. Don’t paste raw keys into CODEX_HOME/config.toml.
Websocket provider for Codex CLI and Desktop
Section titled “Websocket provider for Codex CLI and Desktop”Use the websocket-capable provider for normal Codex backend behavior in Codex CLI and Codex Desktop. Keep the provider id as codex-pooler-ws, but keep name = "OpenAI" exactly. In current Codex sources, name is not just a display label: exact OpenAI matching enables OpenAI-family behavior such as remote compaction, web search/image availability, and Codex backend request-body compression.
model_provider = "codex-pooler-ws"
[model_providers.codex-pooler-ws]name = "OpenAI"base_url = "https://codex-pooler.example.com/backend-api/codex"env_key = "CODEX_POOLER_API_KEY"wire_api = "responses"supports_websockets = truerequires_openai_auth = trueWith a local Codex Pooler instance, change base_url to http://localhost:4000/backend-api/codex.
HTTP/SSE provider
Section titled “HTTP/SSE provider”Keep an HTTP/SSE provider when you need to force non-websocket behavior for a client check or when a Codex runtime cannot open backend websocket streams.
model_provider = "codex-pooler-http"
[model_providers.codex-pooler-http]name = "OpenAI"base_url = "https://codex-pooler.example.com/backend-api/codex"env_key = "CODEX_POOLER_API_KEY"wire_api = "responses"supports_websockets = falserequires_openai_auth = trueBoth providers use the same Pool API key and the same Codex backend compatibility route in Codex CLI and Codex Desktop. Codex Pooler routes each request through Pool policy, account eligibility, limits, session continuity, and request accounting.
Leave requires_openai_auth = true unless you are deliberately running Codex Pooler as a gateway-only provider. With true, Codex still shows the local OpenAI/ChatGPT account as signed in, which keeps Codex Desktop and app-server features that depend on account state available. The Pool API key in env_key still authenticates requests to Codex Pooler.
If Codex repeatedly enters a broken login/account state with a Pooler provider, advanced users can change the provider to requires_openai_auth = false. That makes Codex treat the provider as gateway-only and use only env_key for runtime auth, but Codex will no longer appear signed in for that provider and account-dependent features, including mobile/app-server features, may be unavailable.
When Codex Pooler serves current model metadata, Codex does not need explicit client-side context overrides. If you must pin gpt-5.6-terra before Codex has refreshed backend metadata, use Codex’s raw window fields: model_context_window = 372000 and model_auto_compact_token_limit = 334800. Codex computes an effective 95% turn budget, so the client-visible budget is 353400 tokens, and it does not send an OpenAI SDK-style output cap on normal /responses turns.
Request compression behavior
Section titled “Request compression behavior”Codex CLI and Codex Desktop do not need a client-side switch for Codex Pooler’s per-Pool request compression. When an operator enables request_compression_enabled, eligible backend Responses, backend compact, backend /v1/responses aliases, translated backend chat, and websocket response.create requests may have upstream-bound Responses tool-output payloads compressed before dispatch.
The feature is request-side only. Codex Pooler does not store raw outputs, does not store upstream response bodies, and does not implement CCR/retrieval. Request logs may show safe aggregate payload_compression savings, preferring saved token count and token savings percent when token counts are available and falling back to byte savings when they are not.
Optional operator MCP endpoint
Section titled “Optional operator MCP endpoint”Codex Pooler also exposes an operator MCP endpoint at /mcp. This is an optional operator-only metadata add-on. Omit it for normal Codex runtime use. MCP uses an operator-owned MCP token, not a Pool API key.
[mcp_servers.codex_pooler]url = "https://codex-pooler.example.com/mcp"bearer_token_env_var = "CODEX_POOLER_MCP_KEY"Set the token separately:
export CODEX_POOLER_MCP_KEY="<operator-mcp-token>"Use http://localhost:4000/mcp only for local setup.
Existing session migration
Section titled “Existing session migration”Codex filters resumable conversations by model_provider in local Codex state. If you already have Codex CLI or Codex Desktop sessions created with the built-in openai provider and want them to appear under codex-pooler-ws, re-tag both the JSONL transcripts and the newer SQLite state database.
Close Codex first; these commands edit local Codex state in place. If you made the HTTP provider your default, replace only the destination value codex-pooler-ws with codex-pooler-http before copying.
macOS (zsh)
Section titled “macOS (zsh)”Run these two zsh one-liners:
if [ -d "$HOME/.codex/sessions" ]; then find "$HOME/.codex/sessions" -type f -name '*.jsonl' -exec perl -0pi -e 's/("model_provider"\s*:\s*)"openai"/$1"codex-pooler-ws"/g' {} +; fifor db in "$HOME"/.codex/state_*.sqlite(N); do sqlite3 "$db" "UPDATE threads SET model_provider = 'codex-pooler-ws' WHERE model_provider = 'openai';"; doneLinux (bash)
Section titled “Linux (bash)”Run these two bash one-liners:
if [ -d "$HOME/.codex/sessions" ]; then find "$HOME/.codex/sessions" -type f -name '*.jsonl' -exec perl -0pi -e 's/("model_provider"\s*:\s*)"openai"/$1"codex-pooler-ws"/g' {} +; fifor db in "$HOME"/.codex/state_*.sqlite; do [ -e "$db" ] || continue; sqlite3 "$db" "UPDATE threads SET model_provider = 'codex-pooler-ws' WHERE model_provider = 'openai';"; doneWindows (PowerShell)
Section titled “Windows (PowerShell)”Run the same migration from PowerShell. This expects sqlite3 to be available on PATH.
$ErrorActionPreference = "Stop"
$FromProvider = "openai"$ToProvider = "codex-pooler-ws"$CodexHome = Join-Path $HOME ".codex"
$FromJson = '"model_provider":"' + $FromProvider + '"'$ToJson = '"model_provider":"' + $ToProvider + '"'
Get-ChildItem -Path (Join-Path $CodexHome "sessions") -Recurse -Filter "*.jsonl" | ForEach-Object { $Path = $_.FullName $TempPath = "$Path.tmp" $Reader = [System.IO.StreamReader]::new($Path) $Writer = [System.IO.StreamWriter]::new( $TempPath, $false, [System.Text.UTF8Encoding]::new($false) )
try { while (($Line = $Reader.ReadLine()) -ne $null) { $Writer.WriteLine($Line.Replace($FromJson, $ToJson)) } } finally { $Reader.Dispose() $Writer.Dispose() }
Move-Item -Force $TempPath $Path }
Get-ChildItem -Path $CodexHome -Filter "state_*.sqlite" | ForEach-Object { sqlite3 $_.FullName ` "UPDATE threads SET model_provider = '$ToProvider' WHERE model_provider = '$FromProvider';" }Route boundaries
Section titled “Route boundaries”/backend-api/codex/* is an authenticated Codex backend compatibility surface for Codex CLI and Codex Desktop. It is not a wildcard proxy and it is not the OpenAI-compatible /v1 SDK surface.
The backend route family includes GET /backend-api/codex/models, POST /backend-api/codex/responses, backend websocket response-stream compatibility on GET /backend-api/codex/responses, and POST /backend-api/codex/responses/compact.
Codex Pooler supports Codex model-provider traffic only. Do not point chatgpt_base_url at Codex Pooler for account, realtime, identity, or other app-server helper calls.