How the Codex Plugin Integrates with the Codex App Server JSON-RPC Protocol
The Codex plugin establishes a type-safe communication channel with the Codex App Server using a JSON-RPC 2.0 client that maps strongly-typed methods to HTTP endpoints and WebSocket channels, enabling both synchronous procedure calls and asynchronous server-pushed notifications.
The openai/codex-plugin-cc repository implements this integration through a generated type system defined in plugins/codex/scripts/lib/app-server-protocol.d.ts. This architecture allows plugins to invoke remote methods with compile-time parameter validation while maintaining a persistent connection for real-time events.
Type-Safe Method Definitions via AppServerMethodMap
The foundation of the integration is the AppServerMethodMap interface located in plugins/codex/scripts/lib/app-server-protocol.d.ts. This generated type definition acts as a contract that enumerates every available RPC method, strictly defining the request parameter shapes and response payloads for operations such as thread/start.
This type map interacts with generated models stored in plugins/codex/scripts/lib/app-server-types/*, feeding strongly-typed definitions into the protocol layer. By binding TypeScript types to the JSON-RPC method names, the plugin ensures that calls to the App Server include correctly structured params objects and return typed result payloads, eliminating runtime schema mismatches.
The CodexAppServerClient RPC Implementation
At runtime, the CodexAppServerClient class (implemented in plugins/codex/scripts/lib/app-server-client.ts) materializes the type definitions into actual network requests. The client constructs standard JSON-RPC 2.0 payloads with the following structure:
{
"jsonrpc": "2.0",
"id": "<unique-request-id>",
"method": "thread/start",
"params": { /* ThreadStartParams */ }
}
The client transmits these payloads via HTTP POST requests. By default, it targets a broker endpoint at http://localhost:3000/broker, though configuration options allow direct communication with the App Server's HTTP endpoint when the broker is disabled. The CodexAppServerClientOptions interface defines these connection parameters, including optional clientInfo metadata such as plugin name and version.
Bi-Directional Communication and Notifications
Unlike standard HTTP request-response cycles, the Codex App Server JSON-RPC protocol supports server-initiated messages. The client opens a persistent channel—via WebSocket or Server-Sent-Events—to receive notifications that lack an id field, distinguishing them from call responses.
The AppServerNotificationHandler callback processes these asynchronous events, which include lifecycle signals like turn/start and review/start. These notifications enable the plugin to react to state changes inside the App Server without polling, maintaining synchronized UI state through the ServerNotification type definitions also exported from app-server-protocol.d.ts.
Establishing a Client Connection
To integrate with the App Server, instantiate the client with configuration options and invoke methods using the typed request method:
import {
CodexAppServerClient,
CodexAppServerClientOptions,
ThreadStartParams,
} from "./app-server-protocol";
const opts: CodexAppServerClientOptions = {
brokerEndpoint: "http://localhost:3000/broker",
clientInfo: { name: "my-codex-plugin", version: "1.0.0" },
};
const client = new CodexAppServerClient(opts);
const startParams: ThreadStartParams = {
// Parameters matching the generated type definition
};
client
.request("thread/start", startParams)
.then((response) => {
console.log("Thread started:", response.threadId);
})
.catch((err) => console.error("RPC error:", err));
This pattern leverages the AppServerMethodMap to ensure startParams conform to the expected schema before the network request executes.
Processing Real-Time Notifications
To handle server-pushed events, register a notification handler that inspects the method field of incoming messages:
client.onNotification((msg) => {
switch (msg.method) {
case "turn/start":
console.log("Turn started:", msg.params);
break;
case "review/start":
console.log("Review started:", msg.params);
break;
default:
console.log("Received notification:", msg);
}
});
This handler receives raw notification objects defined by the ServerNotification type, allowing the plugin to trigger UI updates or initiate follow-up RPC calls based on App Server state changes.
Summary
- The integration relies on
AppServerMethodMapinplugins/codex/scripts/lib/app-server-protocol.d.tsto provide compile-time type safety for all RPC operations. - The
CodexAppServerClientclass serializes TypeScript method calls into JSON-RPC 2.0 payloads transmitted via HTTP to broker or direct endpoints. - WebSocket or Server-Sent-Event channels enable the client to receive asynchronous notifications like
turn/startthrough theAppServerNotificationHandlerinterface. - Generated types in
plugins/codex/scripts/lib/app-server-types/*ensure that request parameters and response shapes remain synchronized with the App Server's actual API contract.
Frequently Asked Questions
What transport protocols does the Codex plugin use for JSON-RPC?
The Codex plugin uses HTTP POST for standard JSON-RPC request-response cycles, targeting either a broker endpoint (default http://localhost:3000/broker) or the App Server directly. For asynchronous notifications, it establishes a WebSocket or Server-Sent-Events connection to receive server-pushed messages without polling.
How does the plugin ensure type safety when calling remote methods?
Type safety is enforced through the AppServerMethodMap interface and generated types in plugins/codex/scripts/lib/app-server-types/*. These definitions specify exact parameter and return types for each method name, allowing TypeScript to validate calls at compile time before the CodexAppServerClient serializes them into JSON-RPC payloads.
What is the difference between an RPC request and a notification in this protocol?
RPC requests include a unique id field and expect a corresponding response from the server, following standard JSON-RPC 2.0 specifications. Notifications omit the id field and represent one-way messages from the App Server to the client, such as review/start events, which the AppServerNotificationHandler processes without returning a result.
Can the plugin communicate directly with the App Server without a broker?
Yes. While the default configuration uses the brokerEndpoint to route traffic through an intermediary, the CodexAppServerClientOptions interface allows direct specification of the App Server's HTTP endpoint, enabling peer-to-peer communication when the broker infrastructure is disabled or bypassed.
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 →