# What Is the app-server Component in OpenAI Codex?

> Discover the app-server component in OpenAI Codex. Learn how this JSON-RPC 2.0 gateway enables conversation management, model generation, and tool execution for Codex clients.

- Repository: [OpenAI/codex](https://github.com/openai/codex)
- Tags: internals
- Published: 2026-03-06

---

**The `app-server` is the core JSON-RPC 2.0 gateway that powers all Codex clients, exposing a bidirectional API for conversation management, model generation, and sandboxed tool execution.**

In the `openai/codex` repository, the `app-server/` component serves as the authoritative server-side interface that abstracts the underlying agent, sandbox, and persistence layers behind a stable, versioned protocol. All rich clients—including the VS Code extension, terminal UI, and SDKs—communicate with Codex exclusively through this server, making the system modular and enabling third-party integrations.

## Core Architecture and JSON-RPC 2.0 Protocol

The app-server implements a **JSON-RPC 2.0** protocol over `stdio` by default, with experimental WebSocket support available. According to the source code in [`codex-rs/app-server/src/transport.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/transport.rs), the transport layer handles back-pressure queues, logging, and connection management while omitting the standard `"jsonrpc":"2.0"` envelope on-wire to reduce overhead—a design decision that mirrors the Model Context Protocol (MCP) specification.

The entry point in [`codex-rs/app-server/src/lib.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/lib.rs) builds the transport infrastructure and request router, creating a unified handler that processes incoming JSON-RPC messages and dispatches them to the appropriate internal services.

### Transport Modes

- **stdio** (default): Line-delimited JSON (JSONL) streams suitable for local process spawning
- **WebSocket** (experimental): Enables remote or browser-based clients to connect over the network

## Core Primitives: Thread, Turn, and Item

As defined in [`codex-rs/app-server-protocol/src/protocol/v2.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server-protocol/src/protocol/v2.rs), the API organizes conversation state around three hierarchical primitives:

- **Thread**: A container representing a single conversation session
- **Turn**: A single exchange within a thread, typically consisting of a user message and the model's response
- **Item**: Atomic units within a turn, including user messages, agent messages, tool calls, and tool results

This structure allows clients to resume long-running conversations, inspect historical turns, and stream incremental item updates as the model generates content.

## Lifecycle and API Surface

The typical client lifecycle follows a strict handshake pattern implemented in [`codex-rs/app-server/src/message_processor.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/message_processor.rs):

1. **initialize**: Exchange client/server capabilities and version information
2. **thread/start**: Create a new conversation thread
3. **turn/start**: Submit user input and initiate model generation
4. **Streaming events**: Receive `item/*` notifications (e.g., `item/agentMessage/delta`) in real-time
5. **turn/completed**: Final signal that the turn has finished processing

The API surface includes dozens of methods categorized by resource type:

- **Conversation management**: `thread/start`, `thread/list`, `thread/resume`
- **Generation control**: `turn/start`, `turn/stop`
- **Model discovery**: `model/list`, `model/select`
- **Tool integration**: `skills/list`, `shell/exec`, `file/edit`
- **System operations**: `auth/login`, `feedback/submit`, `plugins/install`

## Security, Approvals, and Sandboxing

Requests that affect the user's system—such as shell commands or file modifications—are gated behind an approval flow defined in the server configuration. The app-server respects the user's `approvalPolicy` settings and sandbox mode, ensuring that destructive operations require explicit client confirmation before execution.

This approval system is tightly integrated with the JSON-RPC notification stream, allowing clients to render confirmation dialogs when the server emits `approval/required` events before proceeding with sensitive operations.

## Schema Generation and Type Safety

To guarantee type safety across language boundaries, the app-server provides built-in schema generation commands:

```bash

# Generate TypeScript definitions matching the current server binary

codex app-server generate-ts --out api-schema

# Generate JSON Schema for validation

codex app-server generate-json-schema --out schemas/

```

These commands produce types that mirror the Rust structs defined in `codex-rs/app-server-protocol/`, ensuring that TypeScript clients, Python SDKs, and other consumers remain synchronized with the server's exact API version.

### Experimental API Access

Clients can opt into unstable features by setting `capabilities.experimentalApi: true` during the initialization handshake. This gatekeeping mechanism allows the core protocol to remain stable while enabling rapid iteration on new capabilities without breaking existing integrations.

## Key Implementation Files

The app-server implementation spans several critical files in the `codex-rs/` directory:

| File | Purpose |
|------|---------|
| [`codex-rs/app-server/src/lib.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/lib.rs) | Entry point and server initialization |
| [`codex-rs/app-server/src/transport.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/transport.rs) | stdio and WebSocket transport implementation |
| [`codex-rs/app-server/src/message_processor.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/message_processor.rs) | JSON-RPC request routing and dispatch |
| [`codex-rs/app-server-protocol/src/protocol/v2.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server-protocol/src/protocol/v2.rs) | Shared protocol structs (Thread, Turn, Item) |
| `codex-rs/debug-client/` | Minimal CLI client for testing and examples |

## Practical Usage Examples

### Rust Client Integration

The following example demonstrates connecting to the app-server from Rust using the debug client library:

```rust
use codex_app_server_test_client::Client;

fn main() -> anyhow::Result<()> {
    // Spawn the server process with stdio transport
    let mut client = Client::spawn()?;

    // Initialize handshake
    client.initialize(codex_app_server_test_client::InitializeParams {
        client_info: codex_app_server_test_client::ClientInfo {
            name: "my_demo".into(),
            title: "Demo client".into(),
            version: "0.1.0".into(),
        },
        ..Default::default()
    })?;

    // Create conversation thread
    let thread = client.call_thread_start(None)?;

    // Start a turn with user input
    let _turn = client.call_turn_start(
        thread.id,
        codex_app_server_test_client::TurnStartParams {
            user_input: Some("Explain Rust ownership".into()),
            ..Default::default()
        },
    )?;

    // Stream notifications until completion
    for notification in client.notifications()? {
        match notification {
            codex_app_server_test_client::Notification::ItemCompleted { item, .. } => {
                if let Some(content) = &item.content {
                    println!("{}: {}", item.kind, content);
                }
            }
            codex_app_server_test_client::Notification::TurnCompleted { .. } => break,
            _ => {}
        }
    }
    Ok(())
}

```

### Command Line Invocation

For shell scripts or debugging, you can interact with the server directly via JSON-RPC over stdio:

```bash

# Start server in background

codex app-server &
SERVER_PID=$!

# Initialize connection

echo '{"method":"initialize","id":0,"params":{"clientInfo":{"name":"cli","version":"1.0"}}}' | codex app-server

# Create thread and capture ID

THREAD_ID=$(echo '{"method":"thread/start","id":1,"params":{}}' | codex app-server | jq -r '.result.id')

# Start turn with streaming output

echo "{\"method\":\"turn/start\",\"id\":2,\"params\":{\"threadId\":\"$THREAD_ID\",\"userInput\":\"Hello\"}}" | codex app-server | jq -r '
  select(.method=="item/agentMessage/delta") | .params.delta
'

```

## Summary

- The **app-server** is the centralized JSON-RPC 2.0 gateway that exposes Codex functionality to all client applications.
- It manages **conversation state** through Thread/Turn/Item hierarchies defined in `codex-rs/app-server-protocol/`.
- All system-interacting operations require **explicit approval**, respecting user-configured sandbox policies.
- The server supports **schema generation** to maintain type safety across TypeScript, Python, and other language bindings.
- Implementation resides primarily in `codex-rs/app-server/src/`, with transport logic in [`transport.rs`](https://github.com/openai/codex/blob/main/transport.rs) and request routing in [`message_processor.rs`](https://github.com/openai/codex/blob/main/message_processor.rs).

## Frequently Asked Questions

### How does the app-server communicate with clients?

The app-server uses **JSON-RPC 2.0** over `stdio` (line-delimited JSON) by default, making it easy to spawn as a subprocess from editors or CLI tools. Experimental WebSocket support exists in [`codex-rs/app-server/src/transport.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/src/transport.rs) for network-based or browser clients.

### What are the main API primitives in the app-server protocol?

The protocol organizes data into three core primitives: **Thread** (conversation container), **Turn** (single exchange within a thread), and **Item** (atomic message or tool call). These structures are defined in [`codex-rs/app-server-protocol/src/protocol/v2.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server-protocol/src/protocol/v2.rs) and enable features like conversation resumption and incremental streaming.

### How does the app-server handle dangerous operations like shell commands?

The server implements an **approval flow** that gates sensitive actions behind user confirmation. When a tool request requires system access, the server emits an approval notification and waits for client authorization, respecting the `approvalPolicy` and sandbox configuration set during initialization.

### Can I generate TypeScript types for the app-server API?

Yes. Run `codex app-server generate-ts --out <directory>` to produce TypeScript definitions that exactly match the current server binary's protocol version. This guarantees type safety for external clients and matches the Rust structs used internally.