MCP 接进来:模型看见翻译过的名字
外部 server 的工具要先过一层翻译才进模型眼睛。skill 目录常在,缺 MCP 时另问人。
- 连接集整份发布,已有 binding 继续拿自己那份连接runtime.rs L246
- 各家 tools/list 汇成一张表,再交给命名翻译tool_catalog.rs L153
- 给命名空间加上历史前缀 mcp__tools.rs L228
- 非法字符洗成下划线,只留字母数字和下划线mcp/mod.rs L477
- 完全相同的原始身份丢掉一份tools.rs L134
- 清洗后命名空间撞车,末尾加 12 位 SHA-1tools.rs L166
- 清洗后工具名撞车,同样加 12 位哈希tools.rs L193
- 合起来超过 128 字节就截断再哈希,协议调用仍走原名tools.rs L226
你把 codex mcp-server 写进 Cursor 的 MCP 配置。Cursor 当 client,Codex 当 server。若这一次 tools/list 把内部 GitHub 工具一并交出去,IDE 调一次就摸到内部能力。权限边界从「调一次 Codex」扩成「直接调内部工具」。
crate 拆成两套。mcp-server 从 stdin 读行,一行一条 JSON。initialize 只打开 tools。tools/list 写死两个名字:codex 和 codex-reply。codex 会 start_thread,nested thread 再起自己的 McpRuntime。codex-mcp 管连接集,外部 server 的工具另做一份目录。
出处:codex-rs/mcp-server/src/lib.rs 第 131 至 152 行;codex-rs/mcp-server/src/codex_tool_runner.rs 第 66 至 90 行;codex-rs/codex-mcp/src/runtime.rs 第 88 至 98 行
同一份 JSON-RPC 线协议,处理器不是同一个。早期资料常把它们画成同一个 runtime 的两张脸。当前源码里它们甚至不共享 MessageProcessor。
出处:codex-rs/mcp-server/src/message_processor.rs 第 274 至 277 行;codex-rs/mcp-server/src/message_processor.rs 第 336 至 348 行
对外承诺和对内能力分开,是网关的通用形状。换语言也是两个函数:hosted 返回 run / continue,external 返回 mcp__*。IDE 只看见入口,会话里才看见外部店。
两家店都报 search,前缀还能分开。一家叫 basic-server,一家叫 basic_server,连字符洗成下划线之后,命名空间会撞。模型看见两个同名工具,下一次调用就不知道进哪家店。API 还有字节上限。
server 接进来,先把各家 tools/list 汇成一张表,再走 normalize_tools_for_model_with_prefix。顺序是固定的四步。
1. 给命名空间加上 mcp__ 前缀。
2. 非法字符洗成下划线,只留字母、数字和 _。
3. 完全相同的原始身份丢掉一份。清洗后命名空间或工具名还撞,就在末尾加 12 位 SHA-1。
4. 合起来超过 128 字节,截断再哈希。原始 server_name 和 tool.name 留在 ToolInfo 上,协议调用走原名。
出处:codex-rs/codex-mcp/src/tools.rs 第 105 至 117 行;codex-rs/codex-mcp/src/tools.rs 第 134 至 137 行;codex-rs/codex-mcp/src/tools.rs 第 166 至 194 行;codex-rs/codex-mcp/src/tools.rs 第 226 至 227 行;codex-rs/codex-mcp/src/mcp/mod.rs 第 477 至 485 行
给模型看的名字和协议上的名字本来就是两层。一层给人读、给 API 用,一层用来寻址。哈希消歧是撞名问题的通用答法。上限数字会变,这层翻译不会变。
若按 MCP 存活过滤目录,冷启动那几秒模型会以为 skill 不存在,下一轮又突然出现。说明书整份灌进每一轮,上下文也会被吃光。
点名记号是 $。目录只看 enabled 和 prompt_visible。用户点了名,或者任务和描述对得上,这一轮才读 SKILL.md 正文。Guardian 评审会话直接返回空注入,父 transcript 里的 $skill 不能再触发新说明书。
出处:codex-rs/skills/src/mentions.rs 第 41 行;codex-rs/ext/skills/src/catalog.rs 第 261 至 263 行;codex-rs/core/src/session/turn.rs 第 766 至 770 行;codex-rs/core/src/session/turn.rs 第 808 至 817 行
缺 MCP 时另问人。first-party 且功能开关开,才弹出 Install MCP servers。审批是 Never 就静默跳过。用户选 Continue anyway,目录还在,对应工具可能仍不可用。
出处:codex-rs/core/src/mcp_skill_dependencies.rs 第 47 至 60 行;codex-rs/core/src/mcp_skill_dependencies.rs 第 268 至 270 行
发现和就绪是两件事。索引先给,全文按需再给,缺依赖问人,不要把条目从目录里抹掉。装不装是配置变更,列不列是发现。
DSH:只桥 tools,一条插件对一台 server
DSH 的 MCP 客户端把范围写死:连一台外部 server,工具注册到 ctx.tools,公开名是 mcp__<serverName>__<rawName>。干净情况原样拼接。字符或长度被改过,就在末尾加 12 位 SHA-256。上限 64 字符。卸载就断连、注销、放命名空间。
出处:packages/mcp/mcp-client/src/index.ts 第 1 至 14 行;packages/mcp/mcp-client/src/tools.ts 第 96 至 102 行
没有 elicitation,也不把自己交出去当 MCP server。外部工具失败仍按普通 tool 失败处理。哈希长度碰巧也是 12,算法和拼接规则不同。
已核对源码 · 2026-08-22 · DSH · MCP 与扩展Claude Code:skill 是一等 tool
Claude Code 给模型一个 Skill tool。模型 call 才拿正文。注释写明同一时间只跑一个 skill,因为 tool 会把命令展开成整份 prompt。
出处:restored-src/src/tools/SkillTool/SkillTool.ts 第 331 至 344 行
MCP 上的 prompt 要标成 loadedFrom === 'mcp' 且 type === 'prompt',才进发现列表。方向相反:Codex 是 skill 需要 MCP,Claude Code 是 MCP 贡献 skill。触发器也不同。Codex 扫 $name,命中就注入 <skill>,不经过一次 tool call。
出处:restored-src/src/tools/SkillTool/SkillTool.ts 第 81 至 94 行
清洗之后谁还认得这家店
basic-server 报 lookup,basic_server 报 query。写出模型看见的两个命名空间,并说明调回去时凭什么还能进对的店。
再问一问:把审批改成 Never,打 $deploy 的时候,skill 目录还在不在。观察点在 is_model_visible 和 should_install_mcp_dependencies。