# How the Codex Plugin Communicates with the Codex App Server via JSON-RPC

> Learn how the Codex plugin communicates with the Codex app server using JSON-RPC. Discover its typed client, serialization methods, and real-time notification channels.

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

---

**The Codex plugin uses a typed JSON-RPC 2.0 client that serializes requests to a configurable broker or direct HTTP endpoint while maintaining a persistent WebSocket or Server-Sent Events channel to receive asynchronous notifications from the server.**

The `openai/codex-plugin-cc` repository implements a type-safe communication layer that enables bidirectional data flow between the Codex plugin and the Codex app server. This architecture leverages generated TypeScript definitions to enforce strict contracts for remote procedure calls and real-time event handling.

## Type-Safe Method Definitions

The communication protocol relies on compile-time type checking to ensure all JSON-RPC exchanges match the server's expected interface.

### The AppServerMethodMap Interface

The [`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) file exports `AppServerMethodMap`, a comprehensive TypeScript interface that maps every available RPC method to its request parameters and response shape. This map validates calls such as `thread/start` against the `ThreadStartParams` type before serialization, preventing malformed payloads from reaching the network layer.

## The CodexAppServerClient Architecture

The client implementation handles transport logic, request lifecycle management, and notification routing.

### Client Configuration

The `CodexAppServerClient` accepts an options object defined by `CodexAppServerClientOptions`. By default, the client targets the broker endpoint at `http://localhost:3000/broker`, though it can be reconfigured to communicate directly with the app server's HTTP endpoint when broker functionality is disabled.

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

```

### Sending JSON-RPC Requests

When invoking a method, the client constructs a standard JSON-RPC 2.0 payload containing the `jsonrpc`, `id`, `method`, and `params` fields. The client POSTs this payload to the configured endpoint and returns a Promise that resolves with 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 generates a payload structure identical to:

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

```

## Bidirectional Communication Channels

The architecture supports full-duplex communication through separate mechanisms for synchronous requests and asynchronous events.

### WebSocket and Server-Sent Events

To receive server-initiated messages, the client establishes a persistent connection using either **WebSocket** or **Server-Sent Events (SSE)**. This channel remains open to listen for notifications that lack an `id` field, distinguishing them from request responses according to the JSON-RPC 2.0 specification.

### Notification Handling

The `AppServerNotificationHandler` interface processes incoming messages defined by the `ServerNotification` type in [`app-server-protocol.d.ts`](https://github.com/openai/codex-plugin-cc/blob/main/app-server-protocol.d.ts). The client delegates notifications such as `turn/start` and `review/start` to registered callbacks that can update UI state or trigger follow-up RPC calls.

```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 additional notifications as needed
  }
});

```

## Key Source Files

The JSON-RPC implementation spans several critical files in the 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)**: Contains the `AppServerMethodMap`, `ServerNotification`, and `CodexAppServerClientOptions` type definitions that enforce compile-time contracts.
- **[`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)**: Implements the concrete `CodexAppServerClient` class responsible for HTTP transport, JSON serialization, and notification dispatching.
- **`plugins/codex/scripts/lib/app-server-types/*`**: Houses generated models (`.generated/app-server-types/...`) that feed the protocol definitions with concrete data structures for request and response payloads.

## Summary

- The Codex plugin uses **JSON-RPC 2.0** to communicate with the Codex app server through a strictly typed client architecture.
- The **`AppServerMethodMap`** in [`app-server-protocol.d.ts`](https://github.com/openai/codex-plugin-cc/blob/main/app-server-protocol.d.ts) provides compile-time validation for all RPC methods and their payloads.
- The **`CodexAppServerClient`** sends HTTP POST requests to a broker endpoint (default `http://localhost:3000/broker`) or directly to the app server, serializing `ThreadStartParams` and other types into standard JSON-RPC requests.
- **WebSocket or SSE connections** enable the client to receive asynchronous notifications via the `AppServerNotificationHandler`, processing events like `turn/start` without polling.
- Generated types in `app-server-types` ensure end-to-end type safety between the plugin and the Codex app server.

## Frequently Asked Questions

### What protocol does the Codex plugin use to communicate with the app server?

The Codex plugin uses **JSON-RPC 2.0** as 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). This protocol structures all remote method calls with a standard envelope containing `jsonrpc`, `id`, `method`, and `params` fields, enabling both request-response patterns and server-pushed notifications.

### How does the Codex plugin handle asynchronous events from the server?

The plugin establishes a persistent connection via **WebSocket or Server-Sent Events** to listen for notifications. The `AppServerNotificationHandler` processes incoming messages that lack a JSON-RPC `id` field—such as `turn/start` and `review/start`—allowing the server to push real-time updates without the client explicitly polling.

### Where are the TypeScript type definitions for the JSON-RPC methods located?

All type 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)**, which exports `AppServerMethodMap` and `ServerNotification` interfaces. Supporting generated models are stored in the `app-server-types` subdirectory, providing concrete types for parameters and return values used in the JSON-RPC exchange.

### Can the Codex plugin communicate directly with the app server without a broker?

Yes. While the default `CodexAppServerClientOptions` configuration routes requests through a broker at `http://localhost:3000/broker`, the client can be reconfigured to send HTTP requests directly to the Codex app server's endpoint. This flexibility allows the plugin to operate in brokerless environments when necessary.