# Overview

> What `codex app-server` exposes, who should integrate against it, supported transports, and the shortest path from `initialize` to a running turn.

- Repository: openai/codex
- GitHub: https://github.com/openai/codex
- Human docs: https://grok-wiki.com/public/docs/openai-codex-c82680b15ec1
- Complete Markdown: https://grok-wiki.com/public/docs/openai-codex-c82680b15ec1/llms-full.txt

## Source Files

- `README.md`
- `Cargo.toml`
- `src/main.rs`
- `src/lib.rs`
- `src/message_processor.rs`
- `src/request_processors.rs`

---

---
title: "Overview"
description: "What `codex app-server` exposes, who should integrate against it, supported transports, and the shortest path from `initialize` to a running turn."
---

`codex app-server` is the `codex-app-server` binary and `codex_app_server` library that expose Codex agent capabilities over JSON-RPC 2.0. Each transport connection gets a per-connection `initialize` handshake, then v2 RPC methods such as `thread/start` and `turn/start` drive conversations while the server streams `turn/*` and `item/*` notifications and may issue server-initiated requests (approvals, auth refresh, attestation).

## Who integrates against app-server

| Integrator | Typical transport | Role |
| --- | --- | --- |
| IDE and desktop hosts (for example the Codex VS Code extension) | `stdio://` subprocess or `unix://` control socket | Primary product UI: threads, turns, approvals, config |
| Local control-plane clients | `unix://` at `$CODEX_HOME/app-server-control/app-server-control.sock` | Long-lived local server; optional `codex app-server proxy` byte bridge |
| In-process CLI surfaces (TUI, exec) | `in_process` module (no socket) | Same protocol semantics without a process boundary; wrapped by `codex-app-server-client` |
| Experimental remote listeners | `ws://IP:PORT` | Health probes and JSON-RPC over WebSocket frames (**experimental / unsupported for production**) |

New integrations should target the **v2** API surface in `codex-app-server-protocol` (`<resource>/<method>` names, camelCase wire fields). Identify the client in `initialize.params.clientInfo` — enterprise integrations may need registration for compliance logging (see README).

## What the server exposes

- **Wire protocol:** JSON-RPC 2.0, bidirectional (client RPCs, server notifications, and server-initiated requests). The `"jsonrpc":"2.0"` header is omitted on the wire.
- **API contract:** Typed requests, responses, and notifications in `codex-app-server-protocol`, with TypeScript and JSON Schema export via `codex app-server generate-ts` and `codex app-server generate-json-schema`.
- **Agent runtime:** `MessageProcessor` dispatches RPCs to focused request processors (`ThreadRequestProcessor`, `TurnRequestProcessor`, `ConfigRequestProcessor`, `McpRequestProcessor`, and others) backed by `codex-core` (`ThreadManager`, config, auth, rollout state).
- **Persistence:** SQLite state under the server’s Codex home (`rollout_state_db`) for thread metadata and related state when available.

<Note>
Active API development is v2 only. Do not add new surface area to v1.
</Note>

## Runtime architecture

`run_main_with_transport_options` in `lib.rs` runs two cooperating Tokio tasks:

1. **Processor loop** — accepts `TransportEvent`s, parses JSON-RPC, and calls `MessageProcessor::process_request`.
2. **Outbound router** — writes responses and notifications to per-connection writers, honoring initialization flags, experimental API opt-in, and per-connection notification opt-out.

```mermaid
flowchart TB
  subgraph clients [Clients]
    IDE[IDE / extension]
    CTL[Control socket client]
    IPC[In-process embedder]
  end

  subgraph transport [codex-app-server-transport]
    STDIO[stdio JSONL]
    UNIX[unix socket + WS upgrade]
    WS[websocket listener]
  end

  subgraph appserver [codex-app-server lib.rs]
    PROC[Processor loop]
    OUT[Outbound router]
    MP[MessageProcessor]
  end

  subgraph processors [Request processors]
    INIT[InitializeRequestProcessor]
    THR[ThreadRequestProcessor]
    TRN[TurnRequestProcessor]
    CFG[ConfigRequestProcessor]
    OTH[Account / MCP / FS / ...]
  end

  subgraph core [codex-core + stores]
    TM[ThreadManager]
    DB[(SQLite state)]
  end

  IDE --> STDIO
  CTL --> UNIX
  IPC --> MP
  STDIO --> PROC
  UNIX --> PROC
  WS --> PROC
  PROC --> MP
  MP --> INIT
  MP --> THR
  MP --> TRN
  MP --> CFG
  MP --> OTH
  THR --> TM
  TRN --> TM
  TM --> DB
  MP --> OUT
  OUT --> STDIO
  OUT --> UNIX
  OUT --> WS
```

Bounded channels (`CHANNEL_CAPACITY` = 128 between transport ingress, processing, and outbound writes) provide backpressure. Saturated ingress returns JSON-RPC error code `-32001` with message `"Server overloaded; retry later."` — clients should retry with exponential backoff and jitter.

## Supported transports

| `--listen` value | Behavior | Default |
| --- | --- | --- |
| `stdio://` | Newline-delimited JSON (JSONL) on stdin/stdout; process exits when the sole stdio connection closes | **Yes** (`AppServerTransport::DEFAULT_LISTEN_URL`) |
| `unix://` or `unix://PATH` | WebSocket connections over HTTP Upgrade on `$CODEX_HOME/app-server-control/app-server-control.sock` (or custom path); startup lock under the same directory | |
| `ws://IP:PORT` | One JSON-RPC message per WebSocket text frame; `GET /readyz` and `GET /healthz` health probes | Experimental |
| `off` | No local listener (remote control may still apply when enabled and state DB is available) | |

Additional CLI context from `main.rs`:

<ParamField body="--session-source" type="string" default="vscode">
Derives product restrictions and metadata (`SessionSource::from_startup_arg`).
</ParamField>

<ParamField body="--strict-config" type="boolean" default="false">
Fail startup when `config.toml` contains unknown fields.
</ParamField>

Tracing: `RUST_LOG` filters verbosity; `LOG_FORMAT=json` emits structured logs to stderr.

## Core primitives

| Primitive | Meaning |
| --- | --- |
| **Thread** | A conversation between a user and the Codex agent; holds multiple turns and persisted rollout history |
| **Turn** | One user-driven cycle (input → agent work → completion); contains items |
| **ThreadItem** | User inputs and agent outputs (messages, reasoning, shell commands, file edits, tool calls, etc.) |

`thread/start`, `thread/resume`, and `thread/fork` create or reopen threads and auto-subscribe the connection to thread/turn/item notifications. `turn/start` attaches user input and begins generation.

## Shortest path: `initialize` to a running turn

Per connection, complete initialization before any other RPC. The server marks the session initialized when the `initialize` **request** succeeds; the client then sends the `initialized` **notification** per protocol (the server currently logs client notifications but gates RPCs on the completed `initialize` request).

```mermaid
sequenceDiagram
  participant C as Client
  participant T as Transport
  participant P as MessageProcessor
  participant Core as ThreadManager

  C->>T: JSON-RPC initialize
  T->>P: process_request
  P->>P: InitializeRequestProcessor.initialize
  P-->>C: InitializeResponse (userAgent, codexHome, platform*)
  Note over C: Send initialized notification
  C->>T: thread/start
  T->>P: ThreadRequestProcessor
  P->>Core: start thread
  P-->>C: thread in result
  P-->>C: notification thread/started
  C->>T: turn/start (threadId, input)
  T->>P: TurnRequestProcessor
  P-->>C: turn in result (status inProgress)
  P-->>C: notification turn/started
  P-->>C: item/started, deltas, item/completed
  P-->>C: notification turn/completed
```

<Steps>
<Step title="Open a transport">
Spawn `codex app-server` (default `stdio://`) or connect to the unix control socket / experimental websocket listener.
</Step>

<Step title="Initialize the connection">
Send `initialize` with `clientInfo` (and optional `capabilities` such as `experimentalApi`, `optOutNotificationMethods`, `requestAttestation`). Read `userAgent`, `codexHome`, `platformFamily`, and `platformOs` from the response.
</Step>

<Step title="Acknowledge with initialized">
Emit the `initialized` client notification (no params).
</Step>

<Step title="Start a thread">
Call `thread/start` (or `thread/resume` / `thread/fork`). Expect a `thread` in the response and a `thread/started` notification.
</Step>

<Step title="Start a turn">
Call `turn/start` with `threadId` and `input` (text, image, or local image items). Expect an `inProgress` turn in the response, then stream `turn/started`, `item/*`, and `turn/completed`.
</Step>
</Steps>

<RequestExample>
```json
{ "method": "initialize", "id": 0, "params": {
  "clientInfo": { "name": "my_client", "title": "My Client", "version": "1.0.0" }
} }
```
</RequestExample>

<ResponseExample>
```json
{ "id": 0, "result": {
  "userAgent": "…",
  "codexHome": "/Users/me/.codex",
  "platformFamily": "unix",
  "platformOs": "macos"
} }
```
</ResponseExample>

<RequestExample>
```json
{ "method": "initialized" }
```
</RequestExample>

<RequestExample>
```json
{ "method": "thread/start", "id": 10, "params": {
  "cwd": "/path/to/project"
} }
```
</RequestExample>

<RequestExample>
```json
{ "method": "turn/start", "id": 30, "params": {
  "threadId": "thr_123",
  "input": [ { "type": "text", "text": "Run tests" } ]
} }
```
</RequestExample>

### Initialization errors and capabilities

| Condition | Error |
| --- | --- |
| RPC before `initialize` completes | `"Not initialized"` (`-32600` invalid request) |
| Second `initialize` on same connection | `"Already initialized"` |
| Experimental method without `capabilities.experimentalApi` | Experimental-required message from protocol helpers |

After initialization, websocket-oriented transports mirror session state into the outbound router and emit connection-scoped `config/warning` and `remoteControl/status/changed` notifications before general broadcast traffic.

## In-process embedding

The public `in_process` module runs the same `MessageProcessor` and outbound routing without sockets. `start` performs the `initialize` / `initialized` handshake internally and returns an `InProcessClientHandle` for typed `ClientRequest` / event consumption — intended for same-process CLI surfaces; higher-level callers should use `codex-app-server-client`.

## Related pages

<CardGroup>
<Card title="Installation" href="/installation">
Launch `codex-app-server`, default listen URLs, logging env vars, and success signals.
</Card>
<Card title="Quickstart" href="/quickstart">
End-to-end first connection with verification and recovery.
</Card>
<Card title="Protocol and transport" href="/protocol-and-transport">
JSON-RPC wire rules, transport details, health probes, and backpressure.
</Card>
<Card title="Connection lifecycle" href="/connection-lifecycle">
`clientInfo`, notification opt-out, subscribe/unsubscribe, and server requests.
</Card>
<Card title="Threads, turns, and items" href="/page-threads-turns-items">
Core primitives, subscriptions, and rollout persistence.
</Card>
<Card title="RPC methods reference" href="/rpc-methods">
Grouped v2 method catalog with stable vs experimental markers.
</Card>
</CardGroup>
