App Server Protocol Used by Codex-Plugin-CC's Broker: JSON-RPC over IPC
The broker communicates with the Codex app-server using a JSON-RPC 1.0/2.0-style protocol delivered over local IPC channels, utilizing Unix domain sockets on macOS and Linux and named pipes on Windows.
The openai/codex-plugin-cc repository implements a broker architecture that mediates communication between client processes and the Codex app-server. Understanding the app server protocol used by codex-plugin-cc's broker is essential for developers building plugins or debugging connectivity issues. The protocol relies on newline-delimited JSON-RPC messages exchanged over platform-specific IPC transports.
Protocol Overview
The broker implements a JSON-RPC 1.0/2.0-style protocol that transmits structured messages between the client and the app-server. Each message contains standard JSON-RPC fields including id, method, params, and result or error as defined in the generated type definitions (plugins/codex/scripts/lib/app-server-protocol.d.ts).
IPC Transport Layer
The transport mechanism is platform-specific:
- Unix-like systems: Uses Unix domain sockets with paths formatted as
unix:/path/to/broker.sock - Windows: Uses named pipes with paths formatted as
pipe:\\.\pipe\...-codex-app-server
The helper function parseBrokerEndpoint in broker-endpoint.mjs handles the abstraction of these transport paths.
Creating Broker Endpoints
When initializing a broker session, the system generates an appropriate endpoint string based on the operating system.
import { createBrokerEndpoint } from "plugins/codex/scripts/lib/broker-endpoint.mjs";
const endpoint = createBrokerEndpoint("/tmp/cxc-12345", "darwin");
// → "unix:/tmp/cxc-12345/broker.sock"
This function resides in plugins/codex/scripts/lib/broker-endpoint.mjs (lines 10-16).
Parsing Endpoint Strings
The broker and client use parseBrokerEndpoint to interpret endpoint strings and determine the transport mechanism.
import { parseBrokerEndpoint } from "plugins/codex/scripts/lib/broker-endpoint.mjs";
const info = parseBrokerEndpoint("pipe:\\\\.\\pipe\\my-pipe");
// → { kind: "pipe", path: "\\\\.\\pipe\\my-pipe" }
This parsing logic is implemented in plugins/codex/scripts/lib/broker-endpoint.mjs (lines 24-31).
Message Format and Communication
Messages follow a newline-delimited JSON (NDJSON) format, where each line represents a single JSON-RPC message. The JSON objects include the standard fields required for request/response correlation and method dispatch.
Establishing Connections
The CodexAppServerClient.connect method automatically detects the presence of a broker endpoint and instantiates the appropriate client implementation.
import { CodexAppServerClient } from "plugins/codex/scripts/lib/app-server.mjs";
const client = await CodexAppServerClient.connect(
process.cwd(),
{ reuseExistingBroker: true }
);
// Send a JSON-RPC request
const init = await client.request("initialize", {
clientInfo: { title: "MyTool", name: "my-tool", version: "1.0.0" },
capabilities: {}
});
This connection logic is found in plugins/codex/scripts/lib/app-server.mjs (lines 35-49). When a broker endpoint is available, the method creates a BrokerCodexAppServerClient that opens the IPC channel and exchanges JSON-RPC messages.
Handling Incoming Messages
The broker processes incoming data by splitting on newlines and parsing each JSON-RPC message individually.
// Inside BrokerCodexAppServerClient.handleChunk()
socket.on("data", chunk => {
// Each line = one JSON-RPC message
const line = chunk.trim();
const msg = JSON.parse(line);
// Access msg.id, msg.method, msg.params...
});
This message handling implementation appears in plugins/codex/scripts/lib/app-server.mjs (lines 85-99).
Key Source Files
The protocol implementation spans several files in the repository:
plugins/codex/scripts/lib/broker-endpoint.mjs: Constructs and parses broker endpoint strings for both Unix sockets and Windows pipes.plugins/codex/scripts/lib/app-server.mjs: Implements theCodexAppServerClientclass andBrokerCodexAppServerClientsubclass, handling JSON-RPC serialization and IPC communication.plugins/codex/scripts/lib/broker-lifecycle.mjs: Manages broker session lifecycle, including spawning the broker process and awaiting IPC endpoint availability.plugins/codex/scripts/lib/app-server-protocol.d.ts: TypeScript definitions for JSON-RPC methods, parameters, and response types.tests/broker-endpoint.test.mjs: Unit tests verifying correct endpoint creation across platforms.
Summary
- The codex-plugin-cc broker uses JSON-RPC 1.0/2.0-style messages exchanged over local IPC transports.
- Unix domain sockets handle communication on macOS and Linux, while named pipes are used on Windows.
- The
parseBrokerEndpointutility abstracts platform differences in path formatting. - Messages are newline-delimited JSON containing standard JSON-RPC fields (
id,method,params,result/error). - The
BrokerCodexAppServerClientclass inapp-server.mjsmanages the connection and message exchange.
Frequently Asked Questions
What transport mechanism does codex-plugin-cc use on Windows?
On Windows, the broker communicates via named pipes using the format pipe:\\.\pipe\...-codex-app-server. The parseBrokerEndpoint function in broker-endpoint.mjs identifies these paths by their pipe: prefix and routes them accordingly.
How does the broker handle multiple concurrent JSON-RPC requests?
The broker uses the standard JSON-RPC id field to correlate requests with responses. Each message is sent as a newline-delimited JSON object, allowing the client to match incoming results or errors with the originating request based on the unique identifier.
Can I connect to the app-server without using the broker?
Yes. The CodexAppServerClient supports both direct spawning (SpawnedCodexAppServerClient) and broker-mediated connections (BrokerCodexAppServerClient). If no broker endpoint is provided, the client spawns the app-server directly and communicates via stdio rather than IPC.
Where are the JSON-RPC method types defined?
Type definitions for the app-server protocol are located in plugins/codex/scripts/lib/app-server-protocol.d.ts. This file contains the TypeScript interfaces for method names, parameter structures, and return types used in the JSON-RPC communication.
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 →