A local relay proxy and operator console for Codex CLI, focused on two jobs: managing multiple relays and keeping Codex as close as possible to the native ChatGPT-backed experience while those relays are in use.
Some Codex features do not appear just because /responses can be forwarded. ChatGPT auth shape, OpenAI provider identity, /models metadata, /responses/compact, and hosted image_generation all affect what Codex decides to expose. Some sub2api-style and other relays also return shapes that work for normal chat but are not quite what Codex expects.
codex-helper keeps that compatibility layer local. Codex talks to the helper proxy, and the helper picks OpenAI or one of your relays through provider/routing config. It also handles model-list translation, client presets, capability diagnostics, balance visibility, and fallback policy.
Current release: v0.19.0
中文说明: README.md

Use codex-helper if:
~/.codex/config.toml;/models, /responses/compact, hosted image_generation, or provider-specific model names;It is probably unnecessary if you only use one official account and do not need provider switching or request observability.
127.0.0.1:3211 by default.~/.codex/config.toml; unrelated Codex edits are preserved.chatgpt-bridge keeps ChatGPT login shape, imagegen-bridge exposes hosted image generation, and official-relay / official-imagegen make relays that forward official Responses semantics use remote compaction by default; compaction and responses_websocket are separate switches for the compaction path and Responses WebSocket v2.POST /v1/images/generations and JSON POST /v1/images/edits, translates them into Responses hosted image_generation requests, and keeps using the same provider routing / fallback chain for local skills and scripts./models, /responses, and /responses/compact, then recommends the preset that matches the selected relay.version = 5 route graph schema. Define providers once, then use routing entry/routes for order, pinning, grouping, or tag preference./user/balance endpoints; lookup failures are not treated as exhausted.config.toml proxy section yet.codex-helper-gui/egui remains available as an optional legacy GUI entrypoint. The Tauri desktop source lives under apps/desktop and has passed Windows packaged smoke, but v0.19.0 does not ship a public desktop installer yet; that release path is deferred until signing, release-channel, and rollback operations are ready.Recommended: install prebuilt binaries with the release installer scripts. Rust is not required.
macOS / Linux:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Latias94/codex-helper/releases/download/v0.19.0/codex-helper-installer.sh | sh
Windows PowerShell:
powershell -ExecutionPolicy Bypass -c "irm https://github.com/Latias94/codex-helper/releases/download/v0.19.0/codex-helper-installer.ps1 | iex"
This installs codex-helper, the short alias ch, and the optional legacy GUI entrypoint codex-helper-gui (egui, deprecated but retained). The Tauri desktop client remains a source-tree preview in v0.19.0 and is not uploaded as a public release artifact; local validation can still build it from apps/desktop with pnpm tauri:build.
If you do not want to pipe a shell script, download the archive for your platform from GitHub Releases and verify it with the matching .sha256 file.
Rust users can also install with cargo-binstall:
cargo install cargo-binstall
cargo binstall codex-helper
Build from source:
cargo build --release
codex-helper
# or
ch
By default this will:
~/.codex-helper/config.toml, backing up the old file as .bak first;model_providers.codex_proxy when needed;Start the proxy without the TUI:
codex-helper serve --no-tui
Advanced: run a resident/attached proxy. Only the explicit --resident/daemon/tui subcommands let the proxy outlive the current console:
codex-helper serve --resident
codex-helper daemon status
codex-helper daemon stop
codex-helper tui --codex
By default, codex-helper serve and the GUI follow “the console owns the proxy”: exiting the UI stops the proxy it started and restores the local client patch. daemon status/stop is only for resident proxies you explicitly started. The tui subcommand attaches read-only to an existing resident proxy, so exiting that attached TUI does not stop the proxy. For automatic restart after child crashes, run codex-helper daemon supervise --codex; the supervisor records lightweight crash markers under ~/.codex-helper/run/.
daemon status best-effort shows the resident proxy owner marker (manual CLI, supervisor, or a future desktop/tray owner). The marker is only observability metadata: read or cleanup failures never block proxy startup or shutdown. A hidden managed sidecar mode is reserved for the future desktop shell, so ordinary users do not need to choose it manually.
The Tauri desktop client uses a more Clash-like resident-client lifecycle: closing the main window hides it to the tray, Quit App exits only the desktop process, and stopping the proxy remains an explicit Stop Proxy action. The Windows NSIS packaged path has passed isolated lifecycle smoke, but it is not part of the v0.19.0 public release; macOS/Linux packaged parity, signing, and rollback operations still need separate follow-up work.
Manage the Codex proxy patch explicitly:
codex-helper switch on
codex-helper switch on --preset chatgpt-bridge
codex-helper switch on --preset official-relay
codex-helper switch on --preset official-relay --responses-websocket
codex-helper switch on --preset official-imagegen
codex-helper switch status
codex-helper switch off
NAS / remote relay targets:
ch relay add nas \
--proxy-url http://nas.local:3211 \
--admin-url http://nas.local:4211 \
--admin-token-env CODEX_HELPER_NAS_ADMIN_TOKEN \
--preset official-relay
ch relay list
ch relay status nas
ch relay nas
ch relay nas --no-tui
ch relay nas --attach-only
ch relay off
Plain ch still starts the local foreground helper. ch relay local is the explicit target form for the same local flow. ch relay <name> patches the local Codex client to the remote proxy and attaches a local TUI to that target's admin API. Use --no-tui for switch-only and --attach-only for observe-only. Admin tokens are read from the environment variable named by --admin-token-env; token values are not written to ~/.codex-helper/config.toml. The container/NAS side should set advertised-admin-base-url, or the client should pass --admin-url when adding the target.
A remote target does not give the server access to this client's local Codex transcript/session files. Container deployments keep host-local transcript/session capabilities disabled unless those paths are explicitly mounted and enabled by server policy.
Preset choices:
| Preset | Use it when | Effect |
|---|---|---|
default |
You only need the local proxy, multiple providers, and fallback | Codex sends model requests to the local helper; helper picks the upstream |
chatgpt-bridge |
You are already signed in to ChatGPT in official Codex and want app/mobile account behavior, but model traffic should use a relay | Keeps the ChatGPT auth shape while upstream credentials still come from helper config |
imagegen-bridge |
The relay does not support official provider identity, but you want Codex to expose hosted image_generation |
Writes the empty {} auth facade and does not require official login |
official-relay |
The relay forwards official OpenAI Responses semantics, especially /responses/compact |
Makes Codex treat the local helper as an OpenAI provider and use the remote compaction path by default |
official-imagegen |
The relay is backed by an official subscription account and supports both /responses/compact and hosted image generation |
Combines OpenAI provider identity, the default remote compaction path, and the imagegen auth facade |
chatgpt-bridge requires a completed ChatGPT login in official Codex first. If ~/.codex/auth.json lacks the full token, email, and account metadata, codex-helper refuses the patch instead of leaving Codex in a half-login state.
official-relay and official-imagegen are experimental. They only change how Codex chooses client-side capabilities; the relay still has to support the underlying endpoints. By default, official-* makes Codex choose the remote compaction path. To keep other official preset behavior while forcing local compaction, set [codex.client_patch].compaction = "local" or run codex-helper switch on --preset official-imagegen --compaction local. Real request credentials come from ~/.codex-helper/config.toml, and the bridge presets do not forward Codex ChatGPT tokens to third-party relays that do not have helper-side credentials. Legacy names official-relay-bridge / official-imagegen-bridge are still accepted as aliases, but are no longer the recommended spelling.
To avoid degrading capable relays, codex-helper normalizes compressed HTTP request bodies before routing by default (zstd, gzip / x-gzip, br, and deflate). For Codex /responses, /responses/compact, and Responses WebSocket, helper also completes missing session_id, x-session-id, official session-id / thread-id, and prompt_cache_key fields from existing request evidence: header session ids, body session_id, prompt_cache_key, or metadata.session_id. previous_response_id is only used for stale-response repair, not as a session identity source. It does not invent a synthetic session id and does not overwrite session fields the client already sent.
Selected provider endpoint affinity is persisted under helper state so a helper restart does not silently move a Codex remote-compaction session to a different provider endpoint. State-bound compact requests, including v1 compact bodies carrying encrypted_content, previous_response_id, or compaction_summary and remote compaction v2 requests carrying compaction_trigger, use the known route affinity or fail with an explicit continuity error. Helper keeps this provider-opaque: it does not infer whether a relay is OpenAI, sub2api, New API, or another intermediary. This keeps relay stickiness through /responses, /responses/compact, and v2 compact's /responses request shape; it does not add compact or WebSocket support to relays that lack those endpoints. For rare relays that require the original compressed Codex body, run helper with CODEX_HELPER_REQUEST_BODY_ENCODING=passthrough.
Codex request semantics also include two targeted repairs: if an upstream explicitly says a previous_response_id response no longer exists, helper removes that field and retries the same upstream once; if a relay ignores Accept-Encoding: identity and returns gzip JSON, helper decodes it before forwarding plain JSON. service_tier remains observational and attribution-only: logs distinguish requested / effective / actual values, but helper default config does not rewrite the client's fast-mode request tier.
Assuming the upstream supports the required endpoints, official-imagegen is the most complete preset. If the upstream also passes Responses WebSocket v2 smoke, adding responses_websocket is the closest current setup to the official experience:
default
< chatgpt-bridge / imagegen-bridge
< official-relay
< official-imagegen
< official-imagegen + responses_websocket
Do not enable the strongest combination blindly: official-imagegen requires the relay to support /responses, /responses/compact, and hosted image_generation; responses_websocket additionally requires a passing WebSocket live smoke.
If the upstream is known to support Responses
$ claude mcp add codex-helper \
-- python -m otcore.mcp_server <graph>