App Server Protocol for Codex Plugin Communication: JSON-RPC Architecture Explained

The Codex plugin communicates with the local Codex App Server via a lightweight JSON-RPC-style protocol over HTTP, using typed method calls defined in app-server-protocol.d.ts to execute operations like thread/start and review/start while receiving asynchronous updates through server notifications.

The openai/codex-plugin-cc repository implements a structured communication layer between the Claude Code interface and the local Codex App Server. Understanding the app server protocol for Codex plugin communication is essential for developers building custom automations or extending the plugin's functionality beyond standard UI interactions.

Protocol Architecture and Transport Layer

The protocol follows a JSON-RPC 2.0 structure over standard HTTP transport. All requests target the local Codex App Server process, which exposes an endpoint at localhost:8080 by default.

Each interaction consists of a POST request containing a JSON body that specifies the method name and parameters. The server responds with a JSON payload containing either the typed result or a structured error object. This synchronous request-response pattern handles initialization, thread management, and review operations, while a separate notification channel delivers asynchronous updates from server to client.

Core Method Definitions in app-server-protocol.d.ts

The complete RPC contract resides in plugins/codex/scripts/lib/app-server-protocol.d.ts, which exports the AppServerMethodMap interface. This type-safe mapping ensures compile-time verification of request and response shapes across nine primary methods.

The protocol exposes the following method signatures:

  • initialize – Accepts InitializeParams and returns InitializeResponse to establish client capabilities and server readiness.
  • externalAgentConfig/import – Uses ExternalAgentConfigImportParams to import external agent configurations.
  • thread/start – Creates new conversation threads using ThreadStartParams (a trimmed variant omitting persistExtendedHistory) and returns ThreadStartResponse.
  • thread/resume – Restores existing threads via ThreadResumeParams (also trimmed) yielding ThreadResumeResponse.
  • thread/name/set – Renames threads through ThreadSetNameParams and returns ThreadSetNameResponse.
  • thread/list – Retrieves active threads using ThreadListParams.
  • review/start – Initiates code reviews with ReviewStartParams, returning a job identifier in ReviewStartResponse.
  • turn/start – Begins new conversation turns via TurnStartParams.
  • turn/interrupt – Cancels ongoing turns via TurnInterruptParams.

Handling Asynchronous Server Notifications

Beyond synchronous RPC calls, the protocol supports server-to-client notifications defined by the ServerNotification type (aliased as AppServerNotification). These asynchronous messages enable real-time progress updates and completion notices without polling.

Clients register a handler implementing AppServerNotificationHandler to process events such as turnProgress updates. This bidirectional communication pattern allows the plugin UI to display streaming progress while the underlying HTTP transport remains stateless for method calls.

Implementing the Client: Practical Code Examples

The CodexAppServerClient class in plugins/codex/scripts/lib/app-server-client.ts wraps the HTTP transport, handling JSON-RPC envelope construction and type parsing. Below are practical implementations demonstrating key protocol interactions.

Initialize the client connection:

import { CodexAppServerClient, CodexAppServerClientOptions } from './lib/app-server-client';

const opts: CodexAppServerClientOptions = {
  env: process.env,
  clientInfo: { name: 'my-plugin', version: '1.0.0' },
  capabilities: { canInterrupt: true },
};
const client = new CodexAppServerClient(opts);

Initialize the server session:

async function initServer() {
  const initParams = { /* InitializeParams fields */ };
  const initResp = await client.request('initialize', initParams);
  console.log('Server ready, capabilities:', initResp.capabilities);
}

Start a new Codex thread:

async function startThread() {
  const startParams = {
    name: 'feature-xyz',
    repoPath: process.cwd(),
    // persistExtendedHistory omitted per trimmed type definition
  };
  const startResp = await client.request('thread/start', startParams);
  console.log('Thread created:', startResp.threadId);
}

Initiate a code review:

async function startReview(threadId: string) {
  const reviewParams = {
    threadId,
    target: { type: 'branch', ref: 'main' },
  };
  const reviewResp = await client.request('review/start', reviewParams);
  console.log('Review queued, job ID:', reviewResp.jobId);
}

Listen for server notifications:

client.onNotification((msg) => {
  if (msg.type === 'turnProgress') {
    console.log(`Turn ${msg.turnId} progress: ${msg.percentage}%`);
  }
});

Key Source Files and Type Definitions

Four primary files define the app server protocol for Codex plugin communication:

  • plugins/codex/scripts/lib/app-server-protocol.d.ts – Central TypeScript definitions containing AppServerMethodMap, request/response interfaces, and notification types.
  • plugins/codex/scripts/lib/app-server-client.ts – HTTP client implementation that serializes typed method calls into POST requests and dispatches incoming notifications.
  • plugins/codex/scripts/codex.ts – Main plugin entry point that orchestrates user commands (/codex:review, /codex:rescue) by invoking the appropriate RPC methods.
  • .generated/app-server-types/ – Build-time generated TypeScript definitions providing low-level shape definitions for all protocol payloads, imported by the main protocol definition file.

Summary

  • The Codex plugin uses a JSON-RPC-style protocol over HTTP POST requests to localhost:8080 for all synchronous operations.
  • Type safety is enforced through AppServerMethodMap in app-server-protocol.d.ts, covering methods like initialize, thread/start, and review/start.
  • Asynchronous notifications flow from server to client via the AppServerNotification system, enabling real-time progress tracking without polling.
  • The CodexAppServerClient class abstracts transport details, automatically handling JSON-RPC envelopes and TypeScript type parsing.
  • Third-party scripts can leverage the same protocol used by the Claude Code UI to drive Codex programmatically.

Frequently Asked Questions

What transport mechanism does the Codex plugin use to communicate with the App Server?

The Codex plugin communicates via standard HTTP POST requests to a local endpoint (default localhost:8080), sending JSON-RPC 2.0 formatted payloads. Each request contains a method name and parameters, while responses include either the typed result or a structured error object.

How are server notifications handled in the Codex App Server protocol?

Server notifications use an asynchronous push model where the server sends AppServerNotification messages to registered clients. Developers implement the AppServerNotificationHandler callback—typically via client.onNotification()—to process events like turnProgress updates without blocking the main request-response cycle.

Where are the type definitions for the App Server protocol located?

The primary type definitions reside in plugins/codex/scripts/lib/app-server-protocol.d.ts, which imports low-level shapes from .generated/app-server-types/. These files define the AppServerMethodMap, individual request/response interfaces (such as ThreadStartParams and ReviewStartResponse), and notification types.

Can third-party scripts use the Codex App Server protocol?

Yes, any script can utilize the protocol by importing the CodexAppServerClient class from plugins/codex/scripts/lib/app-server-client.ts and following the method signatures defined in app-server-protocol.d.ts. This enables programmatic control of Codex operations identical to the native Claude Code UI integration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →