Codex App Server Protocol: JSON-RPC 2.0 Transport for the OpenAI Codex Plugin
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:
- Spawned Process (STDIO) – The
SpawnedCodexAppServerClientclass launchescodex app-serverdirectly and communicates via standard input/output streams. - Unix Socket Broker – The
BrokerCodexAppServerClientclass 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 to provide compile-time safety. This file exports:
AppServerMethodMap– A comprehensive mapping of available methods includinginitialize,thread/start,review/start,turn/interrupt, andturn/start.- Request/Response Interfaces – Typed payloads such as
InitializeParams,ThreadStartParams, andInitializeResponsethat enforce parameter shapes. - Server Notifications – The
ServerNotificationunion type defining asynchronous pushes likeitem/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:
- Generates a unique numeric
idfor the request. - Stores a Promise resolver in the internal
this.pendingMap keyed by that ID. - Serializes the JSON-RPC request with the
methodname andparamspayload. - Waits for the server to return a line containing matching
idand eitherresultorerror.
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:
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– Complete TypeScript contract defining method signatures, parameter types, and notification shapes.plugins/codex/scripts/lib/app-server.mjs– Client implementation containing transport abstraction,handleLineparsing 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, with methods defined inAppServerMethodMap. - The
CodexAppServerClientclass 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. 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →