# Codex App Server Protocol: JSON-RPC 2.0 Transport for the OpenAI Codex Plugin

> Learn about the Codex App Server protocol a lightweight JSON-RPC 2.0 transport for the OpenAI Codex plugin. Discover its STDIO and Unix socket connection support.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: api-reference
- Published: 2026-07-08

---

**The Codex App Server protocol is a lightweight, line-delimited JSON-RPC 2.0 transport used by the Codex plugin to communicate with the companion process that runs the model, supporting both STDIO and Unix socket connections.**

The Codex App Server protocol defines the communication contract between the Codex plugin and the Codex App Server in the `openai/codex-plugin-cc` repository. This protocol enables bidirectional messaging for thread management, turn handling, and review commands through a typed, asynchronous interface. It abstracts the underlying transport layer—whether a directly spawned process or a broker socket—behind a consistent **JSON-RPC 2.0** over **line-delimited JSON (JSONL)** format.

## Transport Layer and Message Format

The protocol operates over two distinct transport modes defined in `plugins/codex/scripts/lib/app-server.mjs`:

1. **Spawned Process (STDIO)** – The `SpawnedCodexAppServerClient` class launches `codex app-server` directly and communicates via standard input/output streams.
2. **Unix Socket Broker** – The `BrokerCodexAppServerClient` class connects to a running broker process through a Unix socket, enabling shared model instances across multiple clients.

In both modes, the serialization format follows strict **JSON-RPC 2.0** conventions over **line-delimited JSON (JSONL)**. Each message is a single JSON object terminated by a newline character. The core fields include `jsonrpc` (version "2.0"), `method`, `id`, `params`, `result`, and `error`. According to the source code in `app-server.mjs`, the client library automatically appends the trailing newline after each serialized object to ensure proper message boundary detection.

## Core Type Definitions and Method Map

All protocol types are codified in [`plugins/codex/scripts/lib/app-server-protocol.d.ts`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/scripts/lib/app-server-protocol.d.ts) to provide compile-time safety. This file exports:

- **`AppServerMethodMap`** – A comprehensive mapping of available methods including `initialize`, `thread/start`, `review/start`, `turn/interrupt`, and `turn/start`.
- **Request/Response Interfaces** – Typed payloads such as `InitializeParams`, `ThreadStartParams`, and `InitializeResponse` that enforce parameter shapes.
- **Server Notifications** – The `ServerNotification` union type defining asynchronous pushes like `item/agentMessage/delta`.

The generated types ensure that both request parameters and response structures are validated at compile time, preventing protocol mismatches between the plugin client and the app server.

## Message Flow and Lifecycle

The protocol follows a strict lifecycle implemented in the `CodexAppServerClient` class:

### Connection and Initialization

The entry point `CodexAppServerClient.connect(cwd, options)` determines the transport mode automatically. Upon connection, the client immediately sends an `initialize` request containing `clientInfo` and `capabilities`. The server responds with an `InitializeResponse` containing server capabilities and version information.

### Request-Response Pattern

For method calls like `thread/start` or `review/start`, the client:

1. Generates a unique numeric `id` for the request.
2. Stores a Promise resolver in the internal `this.pending` Map keyed by that ID.
3. Serializes the JSON-RPC request with the `method` name and `params` payload.
4. Waits for the server to return a line containing matching `id` and either `result` or `error`.

The `handleLine` method (lines 22–55 of `app-server.mjs`) parses incoming lines, validates JSON, and routes responses to their pending promises or forwards notifications to the registered handler.

### Asynchronous Notifications

Server-initiated messages without an `id` field are treated as **notifications**. These are dispatched to the handler registered via `setNotificationHandler()`, allowing the server to push real-time updates such as message deltas without blocking the request-response cycle.

## Error Handling and Special Codes

Errors are returned as standard JSON-RPC error objects with `code`, `message`, and optional `data` fields. The protocol defines a special busy state code:

- **`BROKER_BUSY_RPC_CODE` (`-32001`)** – Indicates the broker socket is currently unable to accept new connections or process requests.

This code allows the client to implement retry logic or queueing strategies when the app server is under heavy load.

## Working with the Protocol

The following example demonstrates connecting to the app server, handling notifications, and executing thread and turn operations:

```javascript
import { CodexAppServerClient } from "./plugins/codex/scripts/lib/app-server.mjs";

async function demo() {
  // Connect to the app-server (broker if available, otherwise spawn)
  const client = await CodexAppServerClient.connect(process.cwd());

  // Set up a notification handler (optional)
  client.setNotificationHandler(msg => {
    console.log("Notification:", msg);
  });

  // Start a new thread
  const threadResp = await client.request("thread/start", {
    name: "demo-thread",
    persistExtendedHistory: false
  });
  console.log("Thread started:", threadResp.threadId);

  // Send a user input turn
  const turnResp = await client.request("turn/start", {
    threadId: threadResp.threadId,
    input: "Explain the Codex App Server protocol."
  });
  console.log("Turn started:", turnResp.turnId);

  // Clean up
  await client.close();
}

demo().catch(console.error);

```

The high-level `CodexAppServerClient` wrapper abstracts the JSON-RPC details, allowing developers to work with typed request objects directly while the underlying `app-server.mjs` implementation manages the line-delimited parsing and pending request map.

## Key Implementation Files

Understanding the protocol requires familiarity with these source files in the `openai/codex-plugin-cc` repository:

- **[`plugins/codex/scripts/lib/app-server-protocol.d.ts`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/scripts/lib/app-server-protocol.d.ts)** – Complete TypeScript contract defining method signatures, parameter types, and notification shapes.
- **`plugins/codex/scripts/lib/app-server.mjs`** – Client implementation containing transport abstraction, `handleLine` parsing logic, and the request/response lifecycle.
- **`plugins/codex/scripts/lib/codex.mjs`** – Orchestration layer that utilizes the app-server client across various plugin commands.
- **`plugins/codex/scripts/app-server-broker.mjs`** – Reference implementation showing how the broker process forwards requests using the same protocol.

## Summary

- The **Codex App Server protocol** is a **JSON-RPC 2.0** transport using **line-delimited JSON** over STDIO or Unix sockets.
- All messages are typed via [`app-server-protocol.d.ts`](https://github.com/openai/codex-plugin-cc/blob/main/app-server-protocol.d.ts), with methods defined in `AppServerMethodMap`.
- The **`CodexAppServerClient`** class manages connection lifecycle, request correlation via numeric IDs, and asynchronous notification dispatch.
- Special error code **`-32001`** (`BROKER_BUSY_RPC_CODE`) indicates server congestion.
- The protocol supports core operations including `initialize`, `thread/start`, `turn/start`, and real-time delta notifications.

## Frequently Asked Questions

### What transport mechanisms does the Codex App Server protocol support?

The protocol supports two transport mechanisms as implemented in `app-server.mjs`: a **spawned process** using STDIO streams (`SpawnedCodexAppServerClient`) and a **Unix socket broker** (`BrokerCodexAppServerClient`). Both use the same JSON-RPC 2.0 message format over line-delimited JSON, differing only in how the underlying bytes are transmitted between client and server.

### How does the protocol handle asynchronous notifications from the server?

The server sends notifications as JSON-RPC messages containing a `method` field but no `id` field. The client's `handleLine` parser detects the absence of an ID and routes the message to the notification handler registered via `setNotificationHandler()`. This allows the server to push real-time updates like `item/agentMessage/delta` without blocking the request-response cycle.

### What is the significance of error code -32001 in the Codex App Server protocol?

Error code **`-32001`** is defined as `BROKER_BUSY_RPC_CODE` in the protocol constants. When the client receives this code in a JSON-RPC error response, it indicates that the broker socket or app server is currently unable to process new requests. Client implementations should handle this code by implementing retry logic or queueing mechanisms to manage temporary server congestion.

### Where are the TypeScript type definitions for the protocol located?

The complete type definitions are located in **[`plugins/codex/scripts/lib/app-server-protocol.d.ts`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/scripts/lib/app-server-protocol.d.ts)**. This file contains the `AppServerMethodMap` interface, all request/response payload types (such as `InitializeParams` and `ThreadStartParams`), and the `ServerNotification` union type. These generated types ensure compile-time safety for all protocol interactions.