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。