openinterpreter(Codex)MCP Server 接口深度解析:用 JSON-RPC 与 MCP 标准传输控制本地 Codex 引擎
【免费下载链接】openinterpreterA coding agent for open models like Kimi K3 and GLM 5.3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter
本文基于仓库中的 codex_mcp_interface.md 原文档展开,系统讲解 Codex 实验性 MCP Server 接口:它以标准 Model Context Protocol(MCP)stdio 传输承载 JSON-RPC 2.0 协议,用于从任意 MCP 客户端控制本地 Codex 引擎,管理线程(thread)、轮次(turn)、账号、配置与审批。读完本文,你将能够启动该 MCP 服务、理解其线程/轮次对象模型、订阅实时事件流、处理服务端发起的审批请求,并掌握codex/codex-reply两个核心工具的参数结构,同时了解接口背后的 Rust 实现调用链与稳定性边界。
一、接口定位:实验性状态与基本形态
原始文档在开头就明确了三个关键事实:
- 状态:experimental,接口可能随时变更,不保证向后兼容;
- 服务二进制:
codex mcp-server(或独立的codex-mcp-server可执行文件); - 传输:标准 MCP over stdio,即 JSON-RPC 2.0 + 行分隔(line-delimited)编码。
从源码结构看,这个接口与 Codex 的app-server共用同一套协议类型:文档指出类型定义位于 protocol 目录(common、v1、v2等文件),由 app-server 的实现消费。MCP Server 本身则是独立的 crate,入口在 mcp-server/src/main.rs,它通过arg0_dispatch_or_else支持二进制被重命名分发(如codex或codex-mcp-server两种调用形态),最终都调用 lib.rs 中的run_main启动服务。
二、启动 MCP 服务器并接入客户端
文档给出的标准接入方式是管道连接任意 MCP 客户端:
codex mcp-server | your_mcp_client对于交互式排查,文档推荐官方 Inspector 工具:
npx @modelcontextprotocol/inspector codex mcp-server此外要注意区分两个容易混淆的入口:codex mcp-server是把 Codex 自身作为 MCP 服务器暴露;而codex mcp子命令是用于管理在config.toml中配置的、由 Codex 去启动的第三方 MCP server launcher。两者方向相反。
2.1 底层事件循环:三个并发任务
run_main在 lib.rs 中构建了典型的三任务管道,这解释了为什么传输必须基于行分隔 JSON:
- stdin 读取任务:用
BufReader按行读取标准输入,每行反序列化为一条 JSON-RPC 消息,放入容量为CHANNEL_CAPACITY = 128的有界 channel(注释说明这是吞吐与内存的折中,对交互式 CLI 足够); - 消息处理任务:
MessageProcessor(定义于 message_processor.rs)消费消息,按 Request / Response / Notification / Error 四类分发处理; - stdout 写入任务:把
OutgoingMessage序列化为 JSON 字符串并追加换行符写出——这正是"line-delimited"约定的实现位置。
典型退出路径是 stdin 读到 EOF,incoming_tx被 drop,shutdown 依次传播到 processor 与 stdout 任务,最后由tokio::join!汇合退出。
初始化阶段还会完成:配置构建(支持-cCLI 覆盖,strict_config在 mcp-server 场景下为false)、认证配置校验、OTel 遥测初始化(服务名codex_mcp_server)、状态库state_db初始化以及EnvironmentManager构建。MessageProcessor内部持有ThreadManager(会话来源标记为SessionSource::Mcp)、ActiveTurnRegistry与出站消息发送器,并安装了 git attribution、image generation、skills 等扩展。
2.2 initialize 握手:一次且仅一次
MCP 客户端连接后必须先发送initialize。handle_initialize的行为(见 message_processor.rs):
- 重复调用会返回
invalid request: initialize called more than once错误; - 客户端的
clientInfo.name与version会被拼接成 user-agent 后缀,用于向模型后端标识调用方; - 响应中
serverInfo为codex-mcp-server+ 当前包版本,标题Codex,并额外保留一个非规范字段serverInfo.user_agent; - 能力声明为
tools+toolListChanged。
三、线程与轮次:v2 API 是新的集成面
文档明确要求:所有新集成应使用 v2 的 thread/turn API。完整方法一览:
thread/start、thread/resume、thread/fork、thread/read、thread/listturn/start、turn/steer、turn/interruptaccount/read、account/login/start、account/login/cancel、account/logout、account/rateLimits/readconfig/read、config/value/write、config/batchWritemodel/list、app/list、collaborationMode/list
语义上:thread/start创建线程,turn/start提交用户输入,turn/interrupt中断进行中的轮次,thread/list/thread/read暴露持久化历史。
兼容层方面,getConversationSummary仍保留给需要按conversationId或rolloutPath查摘要的老客户端;文档特别提示:优先用conversationId查询,因为按rolloutPath的查询在非本地 thread store 下不可用。
完整的请求/响应形状,文档指向 app-server 的 README 与 v2.rs 中的协议定义;app-server/README.md 中对 Thread / Turn / Item 三个核心原语有更完整的描述(线程包含多个轮次,轮次由用户消息开始、以 agent 消息结束,并包含多个 item)。
从 MCP Server 的实现看,它把客户端请求收敛为 MCP 标准方法面:initialize、ping、tools/list、tools/call,以及资源/提示相关方法的占位实现(当前仅打日志);未识别的方法统一返回 JSON-RPCmethod not found错误。而客户端的notifications/cancelled通知会被解析为中断操作:通过ActiveTurnRegistry用请求 id 找到对应 thread,再向 Codex 提交Op::Interrupt(见 message_processor.rs),这正是文档所述"stop an in-flight turn"能力在 MCP 传输上的落点。
四、模型目录:model/list
model/list返回当前 Codex 构建可用的模型目录,支持可选分页:
limit:返回数量上限,缺省由服务端决定;cursor:上一页响应中的nextCursor不透明字符串。
响应结构:
data:有序模型列表。每个模型包含:id、model、displayName、description;supportedReasoningEfforts:对象数组,每项含reasoningEffort(模型自身声明的字符串值,常见取值none|minimal|low|medium|high|xhigh)与description(面向人类的标签);defaultReasoningEffort:给 UI 的建议档位;inputModalities:模型可接受的输入类型;supportsPersonality:是否支持个性指令;isDefault:是否为多数用户的推荐模型;upgrade:可选的推荐升级模型 id;upgradeInfo:可选的升级元数据,含model(升级目标 id)、upgradeCopy(展示文案)、modelLink(升级链接)、migrationMarkdown(展示升级建议时的 Markdown)。
nextCursor:翻页游标(可选)。
app-server README 中对该方法的补充值得注意:客户端应保留supportedReasoningEfforts数组的原始顺序,而不是从档位名称自行推导顺序;还可传includeHidden: true显示hidden: true的条目。
五、协作模式:collaborationMode/list(实验性)
该端点不接受分页,一次返回全部内置协作模式预设。响应要点:
data:有序的 collaboration mode mask(叠加在基础模式之上的部分设置);- 对
reasoning_effort、developer_instructions这类三态字段:省略字段表示保持当前值,置null表示清空,设置具体值表示更新; - 内置预设不设置
model;其中 Plan 预设将reasoning_effort设为 medium,模型选择由客户端自行保持或覆盖。
与turn/start配合的规则:当collaborationMode携带settings.developer_instructions: null时,含义是"使用所选模式内置的指令",而不是清空指令。
六、事件流:codex/event通知
会话运行期间,服务端持续推送通知:
codex/event:载荷是序列化后的 Codex 事件,其形状与 core/src/protocol.rs 中的Event/EventMsg类型一致;部分通知带_meta.requestId,用于与发起它的请求做关联;fuzzyFileSearch/sessionUpdated、fuzzyFileSearch/sessionCompleted:遗留模糊搜索流的进度通知。
客户端应渲染这些事件,并在出现审批请求时将其呈现给用户(见下节)。
实现层面,outgoing_message.rs 的send_event_as_notification把事件包进 params,并在OutgoingNotificationMeta中附加 MCP 规范允许_meta字段:requestId(可选)与threadId(可选)。后者存在的动机是:同一 MCP 连接上可能多路复用多个线程,threadId让客户端能把事件路由到正确的会话。同文件的单元测试(如test_send_event_as_notification_with_meta_and_thread_id)固化了线上的精确形状,包括"jsonrpc":"2.0"、_meta.requestId以及msg.type: "session_configured"等字段。
七、工具调用:codex与codex-reply
MCP 工具面由tools/list暴露两个工具,参数结构在 codex_tool_config.rs 中定义,并有逐字段固化的 JSON Schema 测试(verify_codex_tool_json_schema、verify_codex_tool_reply_json_schema)作为"可执行文档":
codex(启动新会话)参数(kebab-case,deny_unknown_fields):
| 字段 | 说明 |
|---|---|
prompt | 必填,初始用户提示词 |
model | 可选,覆盖模型名(如gpt-5.2、gpt-5.2-codex) |
cwd | 可选,会话工作目录;相对路径按服务进程 cwd 解析 |
approval-policy | 可选枚举:untrusted/on-request/never |
sandbox | 可选枚举:read-only/workspace-write/danger-full-access |
config | 可选对象,逐项覆盖CODEX_HOME/config.toml中的配置 |
base-instructions | 可选,替换默认指令集 |
developer-instructions | 可选,以 developer 角色注入的指令 |
compact-prompt | 可选,压缩会话时使用的提示词 |
codex-reply(继续既有会话)参数:
| 字段 | 说明 |
|---|---|
threadId | 会话线程 id(逻辑上必填;字段本身保留可选以兼容老客户端) |
conversationId | 已废弃,为向后兼容仍接受 |
prompt | 必填,下一轮用户提示词 |
get_thread_id的解析顺序是:优先threadId,缺失时回退conversationId,两者皆无则报错。
7.1 响应形状:content 与 structuredContent 双轨
两个工具返回标准 MCPCallToolResult。为兼容偏好structuredContent的客户端,Codex 会把内容块在structuredContent中镜像一份,并附带threadId。文档给出的示例:
{ "content": [{ "type": "text", "text": "Hello from Codex" }], "structuredContent": { "threadId": "019bbed6-1e9e-7f31-984c-a05b65045719", "content": "Hello from Codex" } }工具定义中声明的outputSchema恰为{ threadId: string, content: string }且两者均 required,与该示例严格一致。另外注意历史线形兼容细节:outgoing_message.rs 在序列化响应时会移除 rmcp 新增的resultType字段,以保持老客户端认识的历史线形({ "content": [...], "isError": false }),该行为有专门的回归测试锁定。
7.2 调用执行链路
tools/call的处理在 message_processor.rs:
- 按工具名路由到
codex(handle_tool_call_codex)或codex-reply(handle_tool_call_codex_session_reply); codex分支把参数反序列化为CodexToolCallParam,经into_config生成有效Config(其中approval_policy、sandbox枚举通过From实现映射到核心协议类型,config字段经json_to_toml转换后作为 CLI 覆盖参与配置分层),随后 spawn 独立异步任务执行会话,避免阻塞消息处理主循环;codex-reply分支先校验会话存在性(不存在则返回带threadId的错误CallToolResult),同样在独立任务中继续会话;- 配置解析失败、缺
prompt等错误都以工具错误结果(文本 content)形式返回,而非 JSON-RPC 协议错误。
八、审批:服务端到客户端的反向请求
当 Codex 需要批准应用变更或执行命令时,服务端向客户端发起 JSON-RPC请求(方向与工具调用相反),文档列出的两个请求:
applyPatchApproval { conversationId, callId, fileChanges, reason?, grantRoot? }execCommandApproval { conversationId, callId, approvalId?, command, cwd, reason? }
客户端对每个请求必须回复{ decision: "allow" | "deny" }。
这两个 RPC 名可以在 app-server 协议 schema 中确认(见 ServerRequest.json)。而在 MCP Server 的当前 Rust 实现中,审批是通过 MCP 规范的elicitation/create请求承载的,参数中带codex_elicitation字段区分类型:
- 命令审批(exec_approval.rs):
codex_elicitation: "exec-approval",附带codex_command(命令 token 数组)、codex_cwd、codex_parsed_cmd(解析后的命令结构)、codex_call_id、codex_event_id等关联字段;提示语形如 "Allow Codex to run\cmd`in`cwd`?"; - 补丁审批(patch_approval.rs):
codex_elicitation: "patch-approval",附带codex_changes(文件 → 变更的映射)、可选codex_reason与codex_grant_root。
客户端响应体统一为{ decision },其中decision是ReviewDecision(allow/deny 及理由)。两条关键实现细节体现了防御性设计:
- 响应在独立 tokio 任务中等待,不会阻塞主 agent 循环;
- 客户端响应反序列化失败、或 oneshot 通道异常时,实现会保守地以
denied("approval request failed")提交决策——即"解析失败即拒绝",审批权永远偏向安全侧。
决策最终通过Op::ExecApproval/Op::PatchApproval提交回 Codex 线程,把客户端的人类决策接回引擎主循环。
九、Auth 辅助端点
文档将账号相关的完整请求/响应形状与流程示例委托给 app-server README 的 "Auth endpoints (v2)" 一节,即 codex-rs/app-server/README.md。MCP 侧对应的方法面是account/read、account/login/start、account/login/cancel、account/logout、account/rateLimits/read。集成登录流程时应以该节为准。
十、v1 遗留兼容方法
为存量 app 客户端,服务端仍接受一个窄化的 v1 兼容面:
getConversationSummarygetAuthStatusgitDiffToRemotefuzzyFileSearch、fuzzyFileSearch/sessionStart、fuzzyFileSearch/sessionUpdate、fuzzyFileSearch/sessionStop
这些方法与事件流中的fuzzyFileSearch/sessionUpdated、fuzzyFileSearch/sessionCompleted通知共同构成遗留模糊搜索流程。新集成不应依赖它们。
十一、兼容性与稳定性边界
接口处于实验阶段:方法名、字段与事件形状都可能演进。要获得权威 schema,应直接查阅:
- 类型定义:app-server-protocol/src/protocol 下的
common、v1、v2文件(v2 进一步拆分为 account.rs、model.rs、thread.rs、turn.rs、collaboration_mode.rs、config.rs、notification.rs 等模块); - 服务端接线:app-server/ 目录;
- MCP Server 实现细节与回归测试:mcp-server/src 及 mcp-server/tests(其中
codex_tool.rs套件配合 mock 模型服务器做端到端验证)。
十二、集成者清单(Checklist)
- 以
codex mcp-server启动服务,通过 stdio 接入 MCP 客户端,先完成initialize握手,重复初始化会被拒绝; - 新集成一律走 v2 的
thread/*与turn/*方法;仅当必须兼容旧客户端时才使用getConversationSummary等 v1 方法; - 持续消费
codex/event通知渲染进度,用_meta.requestId/_meta.threadId把事件归属到具体请求与线程; - 实现
elicitation/create(exec-approval / patch-approval)的应答逻辑,响应体为{ decision };在无法解析客户端响应时按实现约定视为 deny; - 用
model/list拉模型目录(保留supportedReasoningEfforts顺序、用nextCursor翻页),用collaborationMode/list拉协作模式预设(三态字段:省略/null/具体值各有语义); - 用
codex/codex-reply工具调用会话时,按 kebab-case 参数表传参,并预期content与structuredContent双份输出(含threadId); - 因接口实验性,锁定协议版本:以所使用 Codex 构建对应的
app-server-protocol源文件为准,不要跨版本假设字段稳定。
【免费下载链接】openinterpreterA coding agent for open models like Kimi K3 and GLM 5.3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考