-
Notifications
You must be signed in to change notification settings - Fork 3
plat 519
| Field | Value |
|---|---|
| State | fixed on main |
| Priority | P1 |
| Product | integrations |
| Area | mcp |
| Summary | . Fixed on main: every MCP tool is offered as <alias>__<tool> (mcpagent 69ba72f, pinned in the builder), not deployed, not verified live on a server. |
State: fixed on main (2026-10-06): every MCP tool is offered as <alias>__<tool> (mcpagent 69ba72f, builder pin bumped in the same commit as this ticket update). Not deployed, not verified live on a server. The earlier stopgap (mcpagent b619356) stays as a safety net. P1.
Found: 2026-10-05, Excellence, Code project linkedscrapper: "Failed to finalize agent definition: finalize immutable agent definition: register direct tool "delete_function": tool name "delete_function" is already registered by MCP server "ue03d5aec…__neon_46fb2cad6010"". A Neon MCP connection on that project exposes a tool named delete_function; the platform has its own delete_function (Crew/Code functions, crew_functions.go). mcpagent's registerDirectTool (agent/agent.go) rejected any direct tool whose name an MCP server already used, and that failed the whole agent, so the chat could not start at all. Any connected server with a tool named like one of ours does the same.
Stopgap (owner decision, option 3): the platform tool is used and the MCP tool of that name is hidden, with a [TOOL_SHADOW] warning in the log (canonicalToolRegistry.removeMCP). The chat starts; that one MCP tool is not callable. One test pins it (agent/tool_registry_uniqueness_test.go).
Real fix (owner decision 2026-10-06: prefix EVERY MCP tool, not only on a clash) — built: in the platform's own agent loop every MCP tool is registered and offered as <alias>__<tool>; platform (direct/virtual) tools keep their names. Claude Code's own mcp__server__tool names for its plugins are not ours and are untouched.
-
Alias rule (
agent/tool_name.goin mcpagent): the connection's server name with the personal-store prefixu<32 hex>__and a trailing_<8+ hex>connection id removed, lowercased, sanitized to[a-z0-9_-](no__inside), at most 24 characters,mcpif empty. When two connections in one agent would share an alias, each gets_<first 4 chars of its connection id>(or of a hash of the server name when it has no id), 8 hash characters if even that collides. Soue03d5aec…__neon_46fb2cad6010→neonalone, orneon_46fbbeside a second Neon. A tool name that sanitizing changed gets a 6-char hash suffix; a name over 64 characters is cut and ends in an 8-char hash of the real server + tool. All names match^[a-zA-Z0-9_-]{1,64}$. -
Routing back to the real server + tool:
NewAgentConnectionWithSessionbuilds the visible names and a visible → real map (Agent.mcpToolRealNames);toolToServeris keyed by the visible name. The sequential loop (conversation.go), the parallel runner (parallel_tool_execution.go) and the broken-pipe retry (error_handler.go) call the server with the real name (realMCPToolName, which replacedactualMCPToolName). The canonical registry records the real name per MCP tool (MCPToolName). Two connections of the same server used to lose the second one's tools as "duplicates"; now both are callable. -
Unchanged: saved
server:toolselections andselected_toolsfiltering (matched on the real name); the shared code-execution registry (codeexec/registry.go, fed real names); the CLI bridgeexecutor/handlers.go($MCP_MCP/<server>/<tool>with real names, no change needed); the mcpbridge native tool list (it never carries MCP tools). -
Code execution / CLI agents (judgment call): the tool index in the system prompt still lists each server's real tool names under its
$MCP_MCP/<server>/{tool}route, so bridge paths do not change.search_toolsreturns the prefixed name.get_api_specaccepts the prefixed name, or a real name when only one server has it and no platform tool takes it, or a real name plusserver_name; the bare name of a clashing platform tool stays the platform tool. Specs always show the real route. The spec cache key now includesserver_name. One line inguidance/templates/system/mcp-bridge.mdsays search returns<connection>__<tool>and the returned route is called as given. -
Stopgap:
[TOOL_SHADOW]/removeMCPstays as a safety net; it can now only fire for a platform tool named exactly like a prefixed MCP tool. - Guidance scan: no guidance template or mcpagent prompt hard-codes MCP tool names; nothing else to rename.
Verified: by test, not live on a server. mcpagent agent/mcp_tool_prefix_e2e_test.go starts two real stdio MCP servers (the test binary itself, named like two Neon connections of one person, both with delete_function) plus a platform delete_function, and drives one turn through the real agent loop and the real OpenAI adapter against a local OpenAI-compatible endpoint, sequential and parallel: all three calls run, each reaches its own server with the real tool name, every offered name is valid; get_api_spec by prefixed name, by real name + server_name, and by bare name (platform tool) gives the right route. agent/tool_name_test.go pins the alias and 64-character rules. The stopgap test still passes. The builder builds with the new pin. Builder cmd/server, pkg/orchestrator and pkg/agentwrapper with the 69ba72f pin: 16 failures, all also failing with the 78db549 pin (pre-existing); one more (TestVaultChatCreatesMissingUserWorkspaceBeforeCLILaunch) failed once in the full run and passes alone 3/3 (flaky, not from this change).
Left: deploy (owner's go), then confirm live: linkedscrapper on Excellence starts and its Neon tools answer as neon__…, and the person with two Neon connections sees both (neon_xxxx__…).
Impact scan (2026-10-06, read-only, all servers): nothing saved depends on bare MCP tool names.
- Local: only legacy
gmail/google_sheets(dormant workflows) and the built-inworkspace_*categories; one plan step textgmail.send_email(dormant instagram workflow). - Confida: Linear, Notion, Resend; filters only
server:*; no plan, skill or note names a tool. The bridge URL$MCP_MCP/Linear/list_issuesappears only in CLI session transcripts. - Excellence: personal connections Neon (x3, two for one user: identical tool names), Context7, DeepWiki; no saved text names their tools.
- RTS: Notion, Jam, an official Notion connection; one narrow filter
Notion:notion-fetch/Notion:notion-searchonrtsprreviweer, stored asserver:tool, unaffected.
Tests at the pin bump: the mcpagent registry tests pass; 8 builder tests in cmd/server and pkg/orchestrator fail with both the old and the new pin (pre-existing, e.g. PLAT-537); none fails only with the new pin.
PLAT-519, P1. Fixed on main: every MCP tool is offered as <alias>__<tool> (mcpagent 69ba72f, pinned in the builder), not deployed, not verified live on a server.
Auto-synced from docs/ on main. Edit there, not here.