fix(mcplocal): serve OpenAI-safe tool names on the wire #124
Reference in New Issue
Block a user
Delete Branch "fix/wire-safe-tool-names"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
chat.ad.itaz.eu (LibreChat + deepseek-v4-flash) intermittently returned "This tool's MCP server is temporarily unavailable" for
fetch_content/web_url_readwhile every backend was healthy.Root cause (confirmed via LibreChat logs + the mcpd
AuditEventtable): the proxy serves slash-namespaced tool names (websearch/fetch_content), which are invalid OpenAI-style function names. LibreChat forwards them verbatim to the LLM; the model intermittently emits only the tail (fetch_content), LibreChat's registry lookup fails locally, and the call never reaches mcplocal. Claude Code and the pi extension only dodge this because they sanitize names client-side.Fix
WireNameCodecat the HTTP boundary (both/mcpand/projects/:name/mcp):tools/listresponses rewritten to wire-safe names (/→_), exact-match reverse map, deterministic_2suffix on collisiontools/callnames mapped back to the canonical presented name before routingbegin_session) keep workingserver/toolnamesClaude Code wire names change from
all/websearch/fetch_contenttoall_websearch_fetch_content— which is exactly what Claude Code already displayed after its own sanitization, so nothing changes shape there.Not in scope (follow-ups)
serverInstructionsin kubernetes-deployment mentionsearxng/web_url_readin prose — worth aligning after this deploysTests
tests/wire-names.test.ts— 13 unit tests (sanitize, round-trip, collision, passthrough, no-mutation)tests/mcp-endpoint-wire-names.test.ts— end-to-end over the real Streamable HTTP transport: listswebsearch_fetch_content, routes the call back aswebsearch/fetch_content🤖 Generated with Claude Code
https://claude.ai/code/session_01JaFvfHrQyUKCGv6o3N2Wir