Skip to content

fix(mcp): with_prefix names the tool <prefix>__<tool> - #323

Merged
yuanhao merged 2 commits into
mainfrom
fix/mcp-prefix
Oct 16, 2026
Merged

yuanhao merged 2 commits into
mainfrom
fix/mcp-prefix

Conversation

@yuanhao

@yuanhao yuanhao commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Bug

McpToolAdapter::with_prefix and from_client_with_prefix stored the prefix, but name() and label() returned the server's raw tool name, and nothing else read the prefix. Two MCP servers offering the same tool, or a server tool named like a built-in (bash, read_file), therefore still gave the agent duplicate tool names. yoagent doesn't de-duplicate with_tools, so a real provider rejects the request. A caller using the prefix to avoid this was silently unprotected.

Reported by the yobuild session, from the review of yologdev/yobuild#11. yobuild now uses from_client and refuses duplicate names itself, so it does not depend on this fix.

Fix

  • The name is computed once, at construction: the server's name, or <prefix>__<tool> with a prefix. This is the same form as the OpenAPI adapter's with_name_prefix and what the field's doc comment already described.
  • name() and label() return it. execute still calls the server with its own tool name.
  • The docs note that provider limits on tool names apply to the prefixed name: letters, digits, _ and -, and 64 characters on most providers.

Tests

  • New: two servers both offering search become docs__search and web__search. A call through web__search reaches that server as tools/call with name: "search", and an unprefixed adapter keeps search. The test fails with the fix reverted.
  • Locally: cargo test --all-features, clippy -D warnings with all features and on wasm32 (decision), rustdoc, fmt.

CHANGELOG: Unreleased.

🤖 Generated with Claude Code

https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG

yuanhao and others added 2 commits October 16, 2026 20:24
McpToolAdapter::with_prefix / from_client_with_prefix stored the prefix
but name() and label() returned the server's raw tool name, so two MCP
servers offering the same tool (or a server tool named like a built-in)
gave the agent duplicate tool names, which a provider rejects. The name is
now computed once at construction, as the OpenAPI adapter's
with_name_prefix does (`prefix__tool`); execute still calls the server with
its own name. Test: two servers both offering `search`, called through the
prefixed name; it fails without the fix.

Reported by the yobuild session (found in yologdev/yobuild#11's review).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
…ests

- Docs: the MCP guide shows how to prefix a server's tools (the
  with_mcp_server_* helpers add none) and that with_tools replaces the
  list; tools.md notes the agent's own tools are not de-duplicated; the
  pointer is OpenApiConfig::with_name_prefix (not the adapter); provider
  name limits are hedged and the prefix is not validated.
- Tests: the client's call timeout is carried onto prefixed adapters
  (fails without it); a second prefix replaces the first; the other
  server gets no tools/call; tests/mcp_prefix_agent_test.rs runs two
  prefixed servers through an Agent: the model's `web__search` reaches
  only the web server, as `search`, and ToolExecutionStart names
  `web__search`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
@yuanhao
yuanhao merged commit 75b92f3 into main Oct 16, 2026
16 checks passed
@yuanhao
yuanhao deleted the fix/mcp-prefix branch October 16, 2026 21:19
@yuanhao yuanhao mentioned this pull request Oct 16, 2026
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