Access OpenAI Codex app-server from a responsive Web UI or CLI running on your homelab, NAS, Mac mini, or Linux host. Continue the same tasks from any device while Codex stays beside your repositories.
Project site ·
Install ·
codexctl reference ·
Design ·
Debugging
codex-bridge connects directly to app-server and its rollout store. It keeps task history, live
tools and diffs, Queue/Steer/Stop controls, models, and task metadata behind one typed local
protocol—without using the ChatGPT app as a remote-control relay. Keep the Web UI on loopback, or
publish it through Cloudflare Access, a VPN, or an authenticated reverse proxy. Model requests
still use the account and network configured by Codex itself.
- A shared task list and persistent live connection for the Web UI and
codexctl. - Structured messages, tool calls, diffs, status, models, and paginated history.
- Remote Queue, Steer, withdrawal, interruption, pinning, renaming, and archiving.
- Editable voice transcription through app-server, with an optional managed local whisper.cpp fallback for private Mac, Linux, homelab, and NAS deployments.
- Bounded caches and workspace-scoped downloads for long-running, always-on hosts.
- Faster large sessions: viewport-driven hydration keeps first paint bounded and loads completed turn details only as they approach the screen.
- Atomic message handoff: Queue and Steer entries remain visible until the matching authoritative user message is rendered from app-server history.
- Observable runtime health: the compact architecture panel now reports browser audio support, managed voice readiness, process memory, and bounded session/cache usage.
- Large Desktop responses: the compatibility WebSocket accepts up to 64 MiB frames and messages on both legs, with regression coverage above the previous 16 MiB ceiling.
See the complete v0.2.8 release notes, the v0.2.7 Queue and Steer release, or the complete release history.
- Eventually consistent Queue and Steer: stable submission identities connect optimistic UI, app-server negotiation, the native queue, and final rollout history without losing repeated follow-ups or clearing their pending state too early.
- Event-driven live updates: app-server WebSocket events drive activity, pending-message, and history reconciliation; bounded polling remains only as a recovery path when the stream drops.
- Stable long-session navigation: recent-message reconciliation keeps global cursor identity, viewport anchoring avoids large jumps, and linked Codex worktrees stay grouped with their repository project without changing their execution directory.
- Compact completed turns: completed runs collapse intermediate assistant progress and tools while keeping the prompt and final response visible, with an expandable full transcript.
- Useful completion metadata: turn summaries expose duration, the final cumulative token-usage snapshot, and structured memory-citation sources without leaking internal markup into the chat.
- Reliable first messages and refresh: a newly created empty thread starts its first native app-server turn directly, while paginated history stays visible during live updates.
- Desktop direct resume: managed Desktop app-server startup now seeds the disabled MCP transport
base required when Desktop sends only its incremental
enabled_toolsconfiguration. - Compatible worktrees: new isolated sessions use
CODEX_HOME/worktrees/<UUID>/<repo>and stay assigned to their original project in both the Web UI and Desktop. - Hot-deployment boundary: Bridge-only upgrades still preserve app-server; applying the new process-level MCP base to an app-server started by v0.2.4 requires one intentional restart.
Try the interactive demo. It runs the production Vite frontend against a live Rust/WASM simulator entirely in the browser. Submit different prompts to see template-driven progress and structured tools, steer or queue another message while it runs, withdraw queued work, cancel the run, or try simulated voice-to-text. Demo submissions and images never contact Codex or leave the page.
The private UI is responsive across mobile and desktop. It includes project and task navigation, rendered tool calls and diffs, task pinning, renaming, and archiving, model selection, Git change summaries, English and Chinese text, queue/steer message handoff, and opt-in browser notifications when a run finishes while the page is in the background. Notifications require site permission and an open Web UI page; clicking one focuses the page and opens that session. Local file links can download regular files smaller than 16 MiB; the server resolves each link against that task's workspace and rejects paths or symlinks that escape it. Authenticated clients receive a random download ticket that expires after five minutes and tolerates browser or proxy retries. Tickets live only in bridge process memory and become invalid after a restart, so downloads do not expose a long-lived anonymous file endpoint or depend on Basic Auth being forwarded by a navigation.
There are two supported deployment shapes.
Codex Desktop ── TCP WebSocket ── ws-unix-bridge ── Unix WebSocket ── app-server
▲ ▲
│ │
codex-bridge daemon ── rollout store
▲
Web UI / codexctl
The app-server executable comes from ChatGPT.app. In the installed desktop mode,
codex-bridge supervises both that process and the loopback adapter, then publishes
CODEX_APP_SERVER_WS_URL through the user's launchd environment. launchd only has to keep the one
bridge daemon alive. This transport interposition is local and does not patch or re-sign the app
bundle. Bridge-only upgrades preserve the healthy app-server process and adopt its Unix socket on
restart, so active turns do not move to a new app-server PID. The managed Desktop app-server also
starts with a disabled mcp_servers.codex_app base entry; Desktop can then send its incremental
enabled_tools configuration and resume an existing thread directly, without a Web UI preload.
standalone codex app-server ── Unix WebSocket ── codex-bridge daemon ── Web UI / codexctl
│
rollout store
In the installed standalone mode, codex-bridge supervises the open-source app-server on its Unix
socket. Without Codex Desktop there is no Desktop connection to intercept, so ws-unix-bridge is
unnecessary.
See Installation and service setup for global Cargo installation, launchd and systemd examples, optional Web UI configuration, validation, and rollback.
The user-level installers build the embedded frontend, install the required Cargo binaries, write
~/.config/codex-bridge/config.toml, and start the appropriate user services without sudo:
./scripts/install-macos.sh --web-ui # Codex Desktop + launchd
./scripts/install-linux.sh --web-ui # standalone app-server + systemd --userThe generated launchd/systemd bridge service contains only codex-bridge --config .... Runtime
mode, managed app-server/adapter lifecycle, sockets, Web UI, authentication, and cache choices live
in the TOML file rather than being duplicated across startup scripts. Existing argument-only and
externally managed deployments remain supported.
After installing and starting the services:
codexctl status
codexctl ls --limit 10
codexctl show --last 20The optional Web UI listens on 127.0.0.1:18791 by default and normally requires a private
password file. Successful browser Basic Auth creates a seven-day HttpOnly session cookie whose
private token survives ordinary bridge restarts. A same-host authenticated reverse proxy may use
--web-ui-no-auth; that mode is rejected unless the listener is bound to a loopback address. See
the installation guide before binding another interface or placing it behind an HTTPS proxy.
crates/codex-bridge: local daemon, shared protocol, rollout reader, app-server client, and embedded Web UI.crates/codexctl: terminal client for the bridge Unix socket.crates/codex-gui-bridge:ws-unix-bridgeDesktop transport plus retained experimental broker tooling.web-ui: Vite source and deterministic production assets embedded incodex-bridgeat compile time.crates/codex-bridge-demo: bounded Rust/WASM simulator used by GitHub Pages.scripts/install-macos.shandscripts/install-linux.sh: user-owned service installers.config.example.toml: documented bridge runtime configuration template.
The daemon control socket defaults to ~/.codex-bridge/control.sock; override it with --socket
or CODEX_BRIDGE_SOCKET. It creates its default directory as 0700 and socket as 0600.
npm --prefix web-ui ci
npm --prefix web-ui run build
CARGO_INCREMENTAL=0 cargo test --workspaceThe frontend production bundle is checked in under web-ui/dist and embedded with include_str!.
Rebuild it before compiling Rust after a UI change. For frontend-only work, run
npm --prefix web-ui run dev; Vite proxies /api to 127.0.0.1:18791.
The Web UI and CLI share typed bridge requests. Rollout files provide durable reads; live
operations use the selected app-server endpoint. Commands never choose a write target by file
modification time. See docs/codexctl.md for command semantics and current
implementation limits.
