Skip to content

Codex app-server 是 Codex 内部用于驱动富客户端的接口,通过 JSON-RPC 2.0(stdio 或 WebSocket)进行双向通信。适合需要深度集成的场景:会话历史、流式 Agent 事件、文件变更审批、Skills/Apps 调用。如果只是在 CI 中自动化任务,应使用 Codex SDK 而非 app-server。

Codex App Server

Codex app-server 是 Codex 驱动富客户端(如 VS Code 扩展)的接口。当你需要在自己的产品中深度集成时使用它:认证管理、会话历史、审批流程、流式 agent 事件。app-server 的实现是开源的,见 openai/codex/codex-rs/app-server

如果你只是在 CI 中自动化任务,请使用 Codex SDK


协议

MCP 类似,codex app-server 使用 JSON-RPC 2.0 消息进行双向通信(消息体中省略 "jsonrpc":"2.0" 头)。

支持两种传输方式:

  • stdio--listen stdio://,默认):换行符分隔的 JSON(JSONL)
  • websocket--listen ws://IP:PORT,实验性):每个 WebSocket 文本帧一条 JSON-RPC 消息

WebSocket 模式下,app-server 使用有界队列。请求队列满时,服务端会以 JSON-RPC 错误码 -32001 拒绝新请求,消息为 "Server overloaded; retry later.",客户端应指数退避重试。


消息格式

请求包含 methodparamsid

json
{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.4" } }

响应回显 id 并包含 resulterror

json
{ "id": 10, "result": { "thread": { "id": "thr_123" } } }

通知省略 id,只有 methodparams

json
{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }

可从 CLI 生成 TypeScript schema 或 JSON Schema bundle(输出与当前 Codex 版本匹配):

bash
codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemas

快速入门

  1. 启动服务:codex app-server(默认 stdio)或 codex app-server --listen ws://127.0.0.1:4500(实验性 WebSocket)
  2. 发送 initialize 请求,然后发送 initialized 通知
  3. 创建 thread 并开始 turn,持续读取传输流的通知

Node.js / TypeScript 示例:

ts
const proc = spawn("codex", ["app-server"], {
  stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });

const send = (message: unknown) => {
  proc.stdin.write(`${JSON.stringify(message)}\n`);
};

let threadId: string | null = null;

rl.on("line", (line) => {
  const msg = JSON.parse(line) as any;

  if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
    threadId = msg.result.thread.id;
    send({
      method: "turn/start",
      id: 2,
      params: {
        threadId,
        input: [{ type: "text", text: "Summarize this repo." }],
      },
    });
  }
});

send({ method: "initialize", id: 0, params: { clientInfo: { name: "my_product", title: "My Product", version: "0.1.0" } } });
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-5.4" } });

核心原语

  • Thread:用户与 Codex agent 之间的对话,包含多个 turn
  • Turn:单次用户请求及 agent 的后续工作,包含 item 并流式推送增量更新
  • Item:输入或输出单元(用户消息、agent 消息、命令执行、文件变更、工具调用等)

生命周期概览

  1. 每次连接初始化一次:打开传输连接后立即发送 initialize(携带客户端元数据),再发送 initialized。握手完成前服务端拒绝所有请求
  2. 创建或恢复 threadthread/start 新对话,thread/resume 继续已有对话,thread/fork 分叉历史
  3. 开始 turn:调用 turn/start,传入目标 threadId 和用户输入
  4. 引导当前 turnturn/steer 向飞行中的 turn 追加用户输入
  5. 流式事件turn/start 后持续读取通知:item/starteditem/completeditem/agentMessage/delta
  6. 完成 turn:服务端发出 turn/completed,携带最终状态

初始化

每个传输连接必须先发送一次 initialize 请求,再发送 initialized 通知,之后才能调用其他方法。

initialize.params.capabilities 支持通过 optOutNotificationMethods 关闭特定通知(精确匹配方法名,不支持通配符)。

重要:用 clientInfo.name 标识你的客户端,用于 OpenAI 合规日志平台。


实验性 API

通过 capabilities.experimentalApi: true 开启实验性方法:

json
{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": { "name": "my_client", "title": "My Client", "version": "0.1.0" },
    "capabilities": { "experimentalApi": true }
  }
}

API 概览

方法说明
thread/start创建新 thread
thread/resume恢复已有 thread
thread/fork分叉 thread 为新 ID
thread/read读取存储的 thread(不订阅)
thread/list分页列出 thread
thread/archive / thread/unarchive归档/取消归档
thread/rollback回滚最近 N 个 turn
turn/start开始新 turn
turn/steer向当前 turn 追加输入
turn/interrupt中断当前 turn
review/start触发代码审查
command/exec执行单条命令(无需创建 thread)
model/list列出可用模型
skills/list列出可用 skills
app/list列出可用 apps(connectors)
account/read / account/login/start认证相关

事件与通知

启动或恢复 thread 后,持续读取传输流中的通知:

  • turn/startedturn/completedturn/diff/updated
  • item/starteditem/completed
  • item/agentMessage/delta(流式 agent 回复文本)
  • item/commandExecution/outputDelta(命令输出流)
  • thread/status/changedthread/closed

审批机制

当命令执行或文件变更需要审批时,app-server 向客户端发送 JSON-RPC 请求,客户端返回决策(acceptacceptForSessiondeclinecancel)。


常见问题

Q: app-server 和 Codex SDK 该选哪个?

A: 需要深度集成(自定义 UI、流式事件、审批界面)时用 app-server;只需在代码里驱动 Codex 任务时用 SDK——SDK 更简单,屏蔽了底层 JSON-RPC 细节。

Q: WebSocket 模式是否稳定,可以用于生产?

A: WebSocket 模式目前为实验性,可能有变化。生产环境建议使用默认的 stdio 模式,稳定性更高。

Q: 如何处理 app-server 返回的错误?

A: turn 失败时服务端发出 error 事件(含 messagecodexErrorInfoadditionalDetails),然后以 status: "failed" 结束 turn。常见错误码包括 ContextWindowExceededUsageLimitExceededUnauthorized 等,根据 codexErrorInfo 的值做针对性处理。