# How the Codex Plugin Uses JSON-RPC to Communicate with the App Server

> Learn how the Codex plugin uses JSON-RPC to communicate with the Codex app server. Discover its type-safe protocol, HTTP POST requests, and WebSocket notifications for seamless integration.

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

---

**The Codex plugin communicates with the Codex app server through a type-safe JSON-RPC 2.0 protocol implemented by the `CodexAppServerClient` class, which sends HTTP POST requests to a broker endpoint and listens for asynchronous server notifications via WebSocket.**

The `openai/codex-plugin-cc` repository implements a robust communication layer that bridges the Codex plugin with the app server using JSON-RPC. This architecture enables synchronous method calls with typed request/response payloads while supporting asynchronous server-initiated events through a dual-transport design.

## The JSON-RPC 2.0 Architecture

The communication system rests on three core pillars: a **typed method map** that defines available RPC operations, a **generic client** that serializes and transmits requests, and a **notification pipeline** that handles server-pushed messages. This structure ensures type safety across the boundary between the plugin and the app server.

### Typed Method Definitions with AppServerMethodMap

According to the `openai/codex-plugin-cc` source code, the protocol definitions reside 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 exports the `AppServerMethodMap` interface, which acts as a central registry of every RPC method the server supports.

Each entry in the map specifies the exact shape of request parameters and response payloads. For example, the `thread/start` method expects parameters matching the `ThreadStartParams` type and returns a response containing a `threadId`. These generated TypeScript definitions ensure compile-time validation of all JSON-RPC calls.

### The CodexAppServerClient Implementation

The concrete implementation lives in [`plugins/codex/scripts/lib/app-server-client.ts`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/scripts/lib/app-server-client.ts). The `CodexAppServerClient` class consumes the type definitions to provide a developer-friendly API over raw JSON-RPC.

#### Initializing the Client

To instantiate the client, pass a configuration object satisfying the `CodexAppServerClientOptions` interface:

```typescript
import {
  CodexAppServerClient,
  CodexAppServerClientOptions,
} 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);

```

The `brokerEndpoint` determines where the client posts JSON-RPC payloads. When the broker is disabled, the client communicates directly with the app server's HTTP endpoint.

#### Making Typed RPC Requests

The `request` method on `CodexAppServerClient` accepts a method name defined in `AppServerMethodMap` and its corresponding parameters. It returns a Promise resolving to the typed response.

```typescript
import { ThreadStartParams } from "./app-server-protocol";

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));

```

Internally, the client constructs a JSON-RPC 2.0 payload:

```json
{
  "jsonrpc": "2.0",
  "id": "a1b2c3d4",
  "method": "thread/start",
  "params": {
    // Fields from ThreadStartParams
  }
}

```

The client POSTs this payload to the configured broker or app server endpoint, then awaits the response, mapping it back to the TypeScript return type defined in the method map.

## Handling Asynchronous Server Notifications

Beyond request-response cycles, the app server pushes asynchronous notifications to the client. These messages follow the JSON-RPC notification specification—they omit the `id` field because they do not require a response.

### Registering Notification Handlers

The `CodexAppServerClient` exposes an `onNotification` method that accepts an `AppServerNotificationHandler` callback. The handler receives `ServerNotification` objects defined 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).

```typescript
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;
    // Handle other server notifications
  }
});

```

The client maintains a WebSocket or Server-Sent Events connection to receive these notifications in real-time, enabling the plugin to react to server-side events like conversation turns or review cycles without polling.

## Transport Layer Implementation

The JSON-RPC client abstracts two distinct transport mechanisms under a unified interface.

### HTTP POST for Synchronous Calls

For method calls requiring immediate responses, the client serializes the request to JSON and POSTs it to the broker endpoint. The broker forwards the request to the app server and returns the JSON-RPC response to the client.

### WebSocket for Real-Time Events

For notifications, the client establishes a persistent WebSocket connection. This bidirectional channel allows the server to push `turn/start` or `review/start` events to the plugin immediately as they occur, maintaining an active communication channel alongside the HTTP request flow.

## Summary

- The **JSON-RPC 2.0** protocol in `openai/codex-plugin-cc` provides type-safe communication between the Codex plugin and app server.
- The **AppServerMethodMap** 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) defines all available RPC methods with complete TypeScript typings.
- The **CodexAppServerClient** class handles serialization of requests, HTTP POST transmission to the broker endpoint, and response deserialization.
- **Notifications** flow through a separate WebSocket channel, handled by the `AppServerNotificationHandler` to process server-initiated events like `turn/start` and `review/start`.
- The architecture separates synchronous method calls from asynchronous events while maintaining strict type safety through generated TypeScript definitions.

## Frequently Asked Questions

### What is the default broker endpoint for the Codex plugin?

By default, the `CodexAppServerClient` targets `http://localhost:3000/broker` when the `brokerEndpoint` option is not explicitly configured in `CodexAppServerClientOptions`. This endpoint acts as a proxy between the plugin and the Codex app server, though the client can connect directly to the app server when broker mode is disabled.

### How does the CodexAppServerClient handle server-initiated notifications?

The client opens a persistent WebSocket connection to receive JSON-RPC notifications—messages without an `id` field. It dispatches these to registered handlers via the `onNotification` method, allowing the plugin to respond to events like `turn/start` or `review/start` asynchronously without polling the server.

### Where are the JSON-RPC method types defined in the codebase?

All type definitions for the JSON-RPC protocol reside 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 includes the `AppServerMethodMap` interface mapping method names to their parameter and return types, as well as the `ServerNotification` type for incoming events.

### What JSON-RPC version does the Codex plugin implement?

The Codex plugin uses **JSON-RPC 2.0**, as evidenced by the `"jsonrpc": "2.0"` field present in every request payload constructed by the `CodexAppServerClient`. This version supports both standard request-response cycles and notification messages that require no response.