OpenAI: Codex App Server
Source: Unlocking the Codex harness: how we built the App Server
Published: 4 February 2026.
Evidence type: architecture description and integration recommendations for a specific agent runtime.
Why the protocol exists
OpenAI needed CLI, IDE, desktop, web, and partner clients to reuse the same agent harness without reimplementing its loop. Simple request/response or a generic tool call could not faithfully represent workspace exploration, streaming progress, diffs, and interactive approvals. The resulting App Server is a long-lived process plus a bidirectional JSON-RPC-style protocol designed for backward-compatible client evolution.
Harness responsibilities
OpenAI calls the wire format “JSON-RPC lite”: it retains request, response, and
notification shapes, omits the "jsonrpc": "2.0" field, and frames one JSON
object per line over stdio. Hosted runtimes can tunnel those streams over a
persistent connection without changing the protocol model.
The core covers more than inference:
- thread creation, resume, fork, archive, and persisted event history;
- configuration, defaults, authentication, and credential state;
- sandboxed built-in tool execution;
- MCP servers and skills under a policy model;
- one core runtime session per thread.
A translation layer turns internal runtime events into a smaller stable set of UI-ready notifications. One client request can produce many notifications, and the server can send a request for approval and pause the active turn.
Conversation primitives
- Item: typed atomic input/output such as a user message, agent message, tool execution, approval, or diff. It starts, may stream deltas, and completes with a terminal payload.
- Turn: one unit of work initiated by user input and containing the ordered items produced until completion or pause.
- Thread: a durable multi-turn container that can be resumed, forked, and archived and whose history can reconstruct the timeline.
An initial handshake negotiates client identity, protocol version, capabilities, feature flags, and defaults. Typed schemas can generate client bindings. The approval flow is part of the event protocol, not a separate UI convention.
The client must send one initialize request before any other method. A normal
conversation then uses thread/start and turn/start, while the server emits
thread/started, turn/started, item events, and finally turn/completed.
Item lifecycles are explicit:
item/starteditem/*/delta # zero or more, for streaming item typesitem/completedA command approval is a server-initiated request such as
item/commandExecution/requestApproval; the turn pauses until the client
returns allow or deny. This bidirectionality is why a one-way event stream is
insufficient.
Client deployment patterns
TypeScript clients can generate bindings with codex app-server generate-ts;
other clients can generate a JSON Schema bundle with
codex app-server generate-json-schema. OpenAI reports clients in Go, Python,
TypeScript, Swift, and Kotlin. A full protocol trace can be exercised with
codex debug app-server send-message-v2.
Local IDEs bundle or fetch a platform binary, pin it to a tested version, and hold a bidirectional stdio channel. Some clients decouple server and client release cadence, relying on backward compatibility to receive runtime fixes without a client release.
The web runtime provisions a container and workspace, launches the server inside it, and tunnels events to the browser. Because tabs and networks are ephemeral, server-held task state—not the browser—is authoritative. Reconnect and catch-up use the persisted thread.
Moving a terminal UI onto the same protocol removes a special-case in-process client and permits remote compute to continue while a laptop disconnects.
Choosing an integration surface
- MCP is suitable when Codex should be a callable tool in an existing MCP orchestration, but richer diff and session semantics may be lost.
- Cross-provider protocols improve portability but often represent only the common capability subset.
- App Server is for the full interactive harness and stable event stream, with greater client-integration cost.
- A non-interactive exec command is for bounded CI tasks with structured logs and a clear exit result.
- A language SDK suits native server workflows that do not need the complete protocol surface.
Standards implications
- Model messages, tool actions, approvals, diffs, and artifacts as typed state, not terminal text to scrape.
- Keep runtime state server-side for resumable work.
- Negotiate capabilities and maintain backward-compatible event contracts.
- Require clients to handle unknown additive events, reconnect, replay, approval pauses, and partial item streams.
- Choose the lightest integration surface that preserves required semantics; portability and richness are a deliberate trade-off.