feat(mcp): adopt mcp__server__tool naming convention

Port from anomalyco/opencode#33533. Native MCP tools now register as
mcp__<server>__<tool> (double-underscore delimiter) instead of
mcp_<server>_<tool>, aligning with the convention used by Claude Code,
Codex, and OpenCode.

The double-underscore delimiter disambiguates the server/tool boundary
even when either component contains underscores (the single-underscore
form was ambiguous, which is why is_mcp_tool_parallel_safe already had to
track provenance in a side-map). It also unifies native registration with
the Anthropic-OAuth wire form (_MCP_TOOL_PREFIX = 'mcp__'), so the
single->double promotion that path performed is now a no-op for native
tools while still handling legacy replayed names.

- tools/mcp_tool.py: add MCP_TOOL_NAME_PREFIX + mcp_prefixed_tool_name()
  helper; route _convert_mcp_schema, utility schemas, refresh stale-set,
  and the parallel-safe prefix gate through it
- agent/transports/codex_event_projector.py: mirror convention in the
  deterministic call_id input for MCP server-executed tool calls
- tests: update produced-name assertions to the new convention
This commit is contained in:
teknium1 2026-06-25 17:08:44 -07:00 committed by Teknium
parent 5986cdd380
commit e01f58ff1f
5 changed files with 171 additions and 152 deletions

View file

@ -133,9 +133,9 @@ class TestValidateToolset:
def test_mcp_alias_uses_live_registry(self, monkeypatch):
reg = ToolRegistry()
reg.register(
name="mcp_dynserver_ping",
name="mcp__dynserver__ping",
toolset="mcp-dynserver",
schema=_make_schema("mcp_dynserver_ping", "Ping"),
schema=_make_schema("mcp__dynserver__ping", "Ping"),
handler=_dummy_handler,
)
reg.register_toolset_alias("dynserver", "mcp-dynserver")
@ -144,7 +144,7 @@ class TestValidateToolset:
assert validate_toolset("dynserver") is True
assert validate_toolset("mcp-dynserver") is True
assert "mcp_dynserver_ping" in resolve_toolset("dynserver")
assert "mcp__dynserver__ping" in resolve_toolset("dynserver")
class TestGetToolsetInfo: