Skip to content

fix(runtime): canonicalize Codex-mangled MCP tool names before gate checks - #99

Merged
fusengine merged 2 commits into
mainfrom
fix/mcp-tool-name-canonicalization
Aug 12, 2026
Merged

fix(runtime): canonicalize Codex-mangled MCP tool names before gate checks#99
fusengine merged 2 commits into
mainfrom
fix/mcp-tool-name-canonicalization

Conversation

@fusengine

Copy link
Copy Markdown
Owner

Summary

  • Codex CLI globally rewrites - to _ on the qualified MCP tool identifier before it reaches any hook (sanitize_responses_api_tool_name(), Normalize MCP tool names to code-mode safe form openai/codex#14605). This harness compared against the hyphenated form everywhere, so on Codex only: the design gate's SHOT_TOOLS.has() always missed (stuck at phase 1), classifyExplore never credited research-expert (APEX freshness gate), and the doc-cache gate never fired.
  • New canonicalizeMcpToolName(id, tool) (src/runtime/mcp-tool-name.ts) — pure function, id !== "codex" short-circuits first, two closed null-prototype tables (Object.create(null)), server-scoped TOOL_ALIASES to avoid corrupting segments that already contain a legitimate underscore. Wired into 5 ingestion paths: normalize.ts, adapters/codex/index.ts, doc-cache-gate.ts, cache-doc.ts (+ dispatch-aipilot.ts to propagate id).
  • Bumps 0.1.89 -> 0.1.90, CHANGELOG updated.

Test plan

  • bunx tsc --noEmit — exit 0
  • bun test — 1106 pass / 1 skip / 0 fail, 196 files
  • bun run build — exit 0, 97 files (validated pre-commit by the implementing session)
  • Non-regression: 660-line before/after characterization (15 harness ids × 44 tools) — 12 lines changed, all id: "codex", zero regression outside Codex
  • 2 independent challenger reviews (CONFIRMED), 2 sniper passes
  • Live-verified on Codex 0.147: real design-expert subagent session reaches screenshotsCount: 5, phase 1, identity phase completed

https://claude.ai/code/session_01VV766SFwq62DoXAkFs4Xbc

…hecks

Codex CLI globally rewrites `-` to `_` on the qualified MCP tool
identifier before it reaches any hook (sanitize_responses_api_tool_name(),
openai/codex#14605 — Code Mode exposes tools as TypeScript identifiers,
where `-` is illegal). This harness compared against the hyphenated form
everywhere, so on Codex: SHOT_TOOLS.has() always missed (design pipeline
stuck at phase 1), classifyExplore never credited research-expert (APEX
freshness gate), and the doc-cache gate never fired.

canonicalizeMcpToolName(id, tool) is a pure function, id !== "codex"
short-circuits first, two closed null-prototype tables
(Object.create(null)) with server-scoped TOOL_ALIASES to avoid corrupting
segments that already contain a legitimate underscore. Wired into the 5
ingestion paths: normalize.ts, adapters/codex/index.ts, doc-cache-gate.ts,
cache-doc.ts (+ dispatch-aipilot.ts to propagate id).

Verified: tsc --noEmit clean, 1106/1107 tests pass (1 skip), 660-line
before/after characterization (15 harness ids x 44 tools) shows 12 lines
changed, all id:"codex", zero regression outside Codex. Confirmed live on
Codex 0.147: a real design-expert subagent session now reaches
screenshotsCount:5 and completes the identity phase.

Claude-Session: https://claude.ai/code/session_01VV766SFwq62DoXAkFs4Xbc
@fusengine
fusengine merged commit 741a711 into main Aug 12, 2026
1 check passed
@fusengine
fusengine deleted the fix/mcp-tool-name-canonicalization branch August 12, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant