Skip to content

fix: sanitize MCP tool names for LLM function-calling compatibility#93

Open
SBALAVIGNESH123 wants to merge 1 commit into
cloudshipai:mainfrom
SBALAVIGNESH123:fix/issue-42-mcp-tool-name-sanitization
Open

fix: sanitize MCP tool names for LLM function-calling compatibility#93
SBALAVIGNESH123 wants to merge 1 commit into
cloudshipai:mainfrom
SBALAVIGNESH123:fix/issue-42-mcp-tool-name-sanitization

Conversation

@SBALAVIGNESH123
Copy link
Copy Markdown

Hey, I ran into the issue described in #42 where MCP tools with hyphens in their names crash during GenKit execution. Dug into it and found that the root cause is pretty straightforward — LLMs like Gemini and OpenAI enforce a strict regex for function names (only alphanumeric and underscores allowed), so when they see a tool like __resolve-library-id they silently call it back as __resolve_library_id. GenKit then can't find it in its registry and throws a fatal error.

The fix introduces a SanitizedMCPTool wrapper that sits at the MCP discovery boundary and normalizes tool names before they ever reach GenKit. It implements the full ai.Tool interface (all 6 methods) and delegates execution to the original tool unchanged, so the actual tool behavior is completely unaffected. I also added a centralized SanitizeToolName function since I noticed the same normalization logic was copy-pasted across several files.

One thing I caught during testing — there was a second failure mode where the tool assignment filter in the execution engine compares DB-stored names against runtime tool names. Since the DB might store the original hyphenated name but the runtime now reports the sanitized name, tools would silently get filtered out. Fixed that by registering both the original and sanitized versions in the lookup map.

Both code paths are covered (the pooled createServerClient path and the legacy connectToMCPServer fallback). I wrote 13 test cases covering name sanitization, full interface delegation, the restart name consistency, nil safety, and the assignment filter matching scenario. All existing tests pass with zero regressions.

Fixes cloudshipai#42. LLMs like Gemini and OpenAI enforce [a-zA-Z0-9_]+ for tool
names and silently normalize hyphens to underscores. When the LLM calls
back with the normalized name, GenKit fails to resolve it against the
original MCP-provided name.

- Add SanitizeToolName() for centralized name sanitization
- Add SanitizedMCPTool decorator implementing full ai.Tool interface
- Cover both createServerClient and connectToMCPServer code paths
- Fix assignment filter to match both original and sanitized names
- Add comprehensive test suite (13 test cases)
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