影响范围
MCP / skills / plugins
当前行为
使用 chat/completions 类型的中转(wire_api 转 Chat Completions)时,Codex 客户端发出的 tool_search 工具在转发层被静默丢弃。模型侧完全看不到这个工具,因此无法检索出任何 mcp__* 工具,表现为「所有 MCP 工具都拿不到」。
同一轮抓包对比(Reqable,同一请求链,02:17:51):
| 方向 |
格式 |
tools 数量 |
| Codex -> 本地转发 127.0.0.1:57321 |
Responses |
10(含 tool_search) |
| 转发 -> 上游 |
Chat Completions |
13(tool_search 消失,apply_patch 拆成 5 个) |
Codex 发出的 10 个工具:exec_command、write_stdin、list_mcp_resources、list_mcp_resource_templates、read_mcp_resource、request_user_input、custom:apply_patch、view_image、tool_search、web_search。
tool_search 的定义中写明:
For MCP tool discovery, always use tool_search instead of list_mcp_resources
并点名了已就绪的 MCP 来源,说明 server 已经连接成功、工具已经在池子里,只是走延迟加载路径暴露。
同时已排除:上游 API 层(每次 200,只是少收了工具)、MCP server 未启动(Codex 桌面日志中 mcp_server_startup_status_updated 为 status=ready)、模型目录声明不支持(model catalog 中 mcp 零命中)、Codex 安装包被改(Store 签名与 Authenticode 均有效)。
根因
crates/codex-plus-core/src/protocol_proxy.rs
responses_tools_to_chat_tools 的 match(约 :3297)只处理 function / custom / web_search / local_shell / computer_use / namespace,tool_search 落入约 :3328 的 _ => {} 分支被静默丢弃,没有任何日志。
build_codex_tool_context 的 match(约 :3229)同样未收录 tool_search,因此即使模型调用回来也无法正确还原。
- 全仓库检索
tool_search / tool_search_call / tool_search_output 零命中(排除 target),说明不是转换写错,而是这个类型从未被支持,双向都断。
附带的独立问题:crates/codex-plus-core/src/relay_config.rs 的 preserve_live_app_settings(约 :1716)保留键列表不含 mcp_servers。每次重写 ~/.codex/config.toml 时,MCP 条目会被逐次删除,用户侧表现为 server 一个个消失。
预期行为
type: "tool_search" 应透传为 Chat Completions 可用的 function 工具,名字保持 tool_search,input 为必填字符串。
tool_search_call / tool_search_output 应在 item 转换分派中被识别并映射,execution: "client" 语义保持不变(转发层只做搬运,检索本身由 Codex 客户端执行)。
- 检索命中后下一轮暴露的
mcp__<server>__<tool> 走既有 function 分支即可,无需额外处理。
- 重写
config.toml 时保留 mcp_servers 段。
复现步骤
-
Codex++ 1.3.0,provider 配置为 chat/completions 中转。
-
~/.codex/config.toml 中配置至少一个 MCP server,例如:
[mcp_servers.context7]
url = "https://mcp.context7.com/mcp"
-
新建会话,抓包观察请求的 tools 数组。
-
结果:Codex 侧存在 tool_search,转发到上游后消失;模型无法列出或调用任何 mcp__* 工具。
日志 / 配置片段
Codex -> 57321 : 10 tools, 含 {"type":"tool_search","execution":"client",...}
relay -> upstream : 13 tools, 无 tool_search
Codex++ 版本
1.3.0
系统
Windows
提交前确认
影响范围
MCP / skills / plugins
当前行为
使用 chat/completions 类型的中转(wire_api 转 Chat Completions)时,Codex 客户端发出的
tool_search工具在转发层被静默丢弃。模型侧完全看不到这个工具,因此无法检索出任何mcp__*工具,表现为「所有 MCP 工具都拿不到」。同一轮抓包对比(Reqable,同一请求链,02:17:51):
tool_search)tool_search消失,apply_patch拆成 5 个)Codex 发出的 10 个工具:
exec_command、write_stdin、list_mcp_resources、list_mcp_resource_templates、read_mcp_resource、request_user_input、custom:apply_patch、view_image、tool_search、web_search。tool_search的定义中写明:并点名了已就绪的 MCP 来源,说明 server 已经连接成功、工具已经在池子里,只是走延迟加载路径暴露。
同时已排除:上游 API 层(每次 200,只是少收了工具)、MCP server 未启动(Codex 桌面日志中
mcp_server_startup_status_updated为status=ready)、模型目录声明不支持(model catalog 中mcp零命中)、Codex 安装包被改(Store 签名与 Authenticode 均有效)。根因
crates/codex-plus-core/src/protocol_proxy.rsresponses_tools_to_chat_tools的 match(约 :3297)只处理function/custom/web_search/local_shell/computer_use/namespace,tool_search落入约 :3328 的_ => {}分支被静默丢弃,没有任何日志。build_codex_tool_context的 match(约 :3229)同样未收录tool_search,因此即使模型调用回来也无法正确还原。tool_search/tool_search_call/tool_search_output零命中(排除target),说明不是转换写错,而是这个类型从未被支持,双向都断。附带的独立问题:
crates/codex-plus-core/src/relay_config.rs的preserve_live_app_settings(约 :1716)保留键列表不含mcp_servers。每次重写~/.codex/config.toml时,MCP 条目会被逐次删除,用户侧表现为 server 一个个消失。预期行为
type: "tool_search"应透传为 Chat Completions 可用的 function 工具,名字保持tool_search,input为必填字符串。tool_search_call/tool_search_output应在 item 转换分派中被识别并映射,execution: "client"语义保持不变(转发层只做搬运,检索本身由 Codex 客户端执行)。mcp__<server>__<tool>走既有function分支即可,无需额外处理。config.toml时保留mcp_servers段。复现步骤
Codex++ 1.3.0,provider 配置为 chat/completions 中转。
~/.codex/config.toml中配置至少一个 MCP server,例如:新建会话,抓包观察请求的
tools数组。结果:Codex 侧存在
tool_search,转发到上游后消失;模型无法列出或调用任何mcp__*工具。日志 / 配置片段
Codex++ 版本
1.3.0
系统
Windows
提交前确认