Summary
Codex App Server exposes structured thread control, including turn/steer and turn/interrupt, and supports both stdio and Unix-socket transports. However, a Codex Desktop-owned thread is currently hosted by a private stdio app-server process that external clients such as codex-bridge cannot connect to.
As a result, the protocol supports interruption, but an external local integration cannot interrupt or steer the active turn that the Desktop app actually owns.
Official protocol reference: https://developers.openai.com/codex/app-server
Observed environment
- macOS
- Codex Desktop
26.820.60940
- Observation date: 2026-08-29
- External client:
codexapp-cli / codex-bridge
- Shared control socket used by the bridge:
~/.codex/app-server-control/app-server-control.sock
This version scope is a local observation, not a claim that every Codex Desktop version is affected.
Reproduction
- Start Codex Desktop and open a thread.
- Start work in that thread so it has an active turn.
- Inspect the local process topology: Desktop starts its own app-server over private stdio.
- Connect an external client to the shared Unix-socket app-server and complete the
initialize / initialized handshake.
- Send
turn/interrupt with the Desktop thread ID and active turn ID (the current bridge uses codex app-server proxy --sock PATH).
- The request cannot control the Desktop-owned turn because that thread belongs to the separate private stdio server.
The same ownership split prevents a true same-turn turn/steer. Falling back to codex exec resume is only a follow-up operation and may fail with an active-writer conflict.
Expected behavior
Codex Desktop should provide a documented, supported way for an authorized local client to control the same app-server instance that owns the Desktop thread. For example, Desktop could:
- honor a documented configuration that connects it to a shared local app-server;
- expose a local-only authenticated Unix socket for its app-server; or
- document another supported attachment/control endpoint for Desktop-owned threads.
Then an external client could use the protocol's existing turn/steer and turn/interrupt methods without taking over the thread writer.
Actual behavior
The Desktop app-server is private to the Desktop process over stdio. The shared socket is a different server instance, so structured control requests cannot reach the active Desktop turn.
codexapp-cli therefore reports an explicit app_server_unavailable / app_server_rejected failure. It deliberately does not queue a textual /stop and report success, because that would not prove the turn was interrupted.
Impact
- No reliable external interruption of a Desktop-owned turn.
- No true same-turn steering from
codex-bridge.
- Approval/control integrations cannot share the Desktop app-server session.
codex exec resume is not an equivalent replacement and can conflict with active-writer ownership.
- Local hardware workflows that need an external controller must use a separate, tightly allowlisted host executor rather than app-server control.
Evidence boundary
Confirmed locally:
- Rollout state provides the active thread and turn IDs.
- The installed app-server schema supports
turn/steer and turn/interrupt.
- The Desktop-owned thread is not controllable through the shared socket.
- Failure is reproduced without sending UI events or taking over the writer.
Not yet confirmed:
- Whether Codex Desktop has an undocumented supported control endpoint.
- The first affected Desktop version or whether platforms other than macOS are affected.
- Whether the behavior is intentional isolation or a regression.
Security considerations
Any shared control endpoint should remain local-only, require restrictive filesystem permissions (for example 0600 on a Unix socket), and preserve app-server initialization/authentication boundaries. This request is for structured thread control, not an unauthenticated arbitrary host-command channel.
Project references
Summary
Codex App Server exposes structured thread control, including
turn/steerandturn/interrupt, and supports both stdio and Unix-socket transports. However, a Codex Desktop-owned thread is currently hosted by a private stdio app-server process that external clients such ascodex-bridgecannot connect to.As a result, the protocol supports interruption, but an external local integration cannot interrupt or steer the active turn that the Desktop app actually owns.
Official protocol reference: https://developers.openai.com/codex/app-server
Observed environment
26.820.60940codexapp-cli/codex-bridge~/.codex/app-server-control/app-server-control.sockThis version scope is a local observation, not a claim that every Codex Desktop version is affected.
Reproduction
initialize/initializedhandshake.turn/interruptwith the Desktop thread ID and active turn ID (the current bridge usescodex app-server proxy --sock PATH).The same ownership split prevents a true same-turn
turn/steer. Falling back tocodex exec resumeis only a follow-up operation and may fail with an active-writer conflict.Expected behavior
Codex Desktop should provide a documented, supported way for an authorized local client to control the same app-server instance that owns the Desktop thread. For example, Desktop could:
Then an external client could use the protocol's existing
turn/steerandturn/interruptmethods without taking over the thread writer.Actual behavior
The Desktop app-server is private to the Desktop process over stdio. The shared socket is a different server instance, so structured control requests cannot reach the active Desktop turn.
codexapp-clitherefore reports an explicitapp_server_unavailable/app_server_rejectedfailure. It deliberately does not queue a textual/stopand report success, because that would not prove the turn was interrupted.Impact
codex-bridge.codex exec resumeis not an equivalent replacement and can conflict with active-writer ownership.Evidence boundary
Confirmed locally:
turn/steerandturn/interrupt.Not yet confirmed:
Security considerations
Any shared control endpoint should remain local-only, require restrictive filesystem permissions (for example
0600on a Unix socket), and preserve app-server initialization/authentication boundaries. This request is for structured thread control, not an unauthenticated arbitrary host-command channel.Project references