This note summarizes how to drive Codex as a backend for a custom surface (web UI, mobile app, CI bot, etc.) using the same server protocol the TUI uses.
Run the app-server sidecar and use the default stdio transport:
codex app-server --listen stdio://After startup, send one JSON-RPC initialize request first, then a matching initialized notification. Subsequent calls on the same connection are rejected until this handshake completes.
thread/start(orthread/resume)- create a new conversation or reopen an existing one
- response includes a
threadwiththreadId
turn/start- send user input to begin the first model turn
- response includes the
turnobject - notification stream starts with
turn/started
- Listen for stream notifications and render them in order
turn/starteditem/starteditem/completedturn/completedenteredReviewModeexitedReviewModetokenCountupdates (if your UI shows context window / usage)
These are the same events the TUI drives, so you can keep one event parser for both a skin and a custom client.
To run automated review in-band with a thread:
- Call
review/startwith a review target - Watch for:
enteredReviewMode(review mode begins)- review item events (
item/started/item/completedforenteredReviewMode/exitedReviewMode) - final review result message in item output
Because the TUI now queues /review requests while a turn is busy, external clients should do the same:
- keep a single in-memory queue per active thread
- when busy, push new
/reviewand user-turn work into that queue instead of sending immediately - when
turn/completedarrives, send the next queued request - if you need to cancel an in-flight turn, send
turn/interrupt
Use:
turn/interruptwith(threadId, turnId)to cancel the active turn- on interrupt, expect the active turn to finish with a status like interrupted
- then send the next queued item (user or
/review) as part of your queue drain policy
- Serialize outbound commands for one thread.
- Never fire a new
turn/startorreview/startwhile another turn is in-flight. - Drain queue only on terminal events (
turn/completed,turn/aborted, explicitturn/interruptcompletion). - Keep user feedback in sync by mirroring the same state transitions the TUI uses (
enteredReviewMode/exitedReviewMode, running indicator, etc.).