Appearance
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.",客户端应指数退避重试。
消息格式
请求包含 method、params 和 id:
json
{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.4" } }响应回显 id 并包含 result 或 error:
json
{ "id": 10, "result": { "thread": { "id": "thr_123" } } }通知省略 id,只有 method 和 params:
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快速入门
- 启动服务:
codex app-server(默认 stdio)或codex app-server --listen ws://127.0.0.1:4500(实验性 WebSocket) - 发送
initialize请求,然后发送initialized通知 - 创建 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 消息、命令执行、文件变更、工具调用等)
生命周期概览
- 每次连接初始化一次:打开传输连接后立即发送
initialize(携带客户端元数据),再发送initialized。握手完成前服务端拒绝所有请求 - 创建或恢复 thread:
thread/start新对话,thread/resume继续已有对话,thread/fork分叉历史 - 开始 turn:调用
turn/start,传入目标threadId和用户输入 - 引导当前 turn:
turn/steer向飞行中的 turn 追加用户输入 - 流式事件:
turn/start后持续读取通知:item/started、item/completed、item/agentMessage/delta等 - 完成 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/started、turn/completed、turn/diff/updateditem/started、item/completeditem/agentMessage/delta(流式 agent 回复文本)item/commandExecution/outputDelta(命令输出流)thread/status/changed、thread/closed
审批机制
当命令执行或文件变更需要审批时,app-server 向客户端发送 JSON-RPC 请求,客户端返回决策(accept、acceptForSession、decline、cancel)。
常见问题
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 事件(含 message、codexErrorInfo、additionalDetails),然后以 status: "failed" 结束 turn。常见错误码包括 ContextWindowExceeded、UsageLimitExceeded、Unauthorized 等,根据 codexErrorInfo 的值做针对性处理。