Skip to content

[BUG] MCP tool names cut at 64 chars come back full-length in API history and break the task on Bedrock / OpenAI-compatible providers #2065

Open

Description

@pdecat

Problem (one or two sentences)

When mcp--<server>--<tool> is longer than 64 characters, buildMcpToolName cuts it with a plain slice(0, 64). The model can call the complete, uncut name instead: Zoo Code still resolves and runs it, then stores that >64-char name in the API history, and every later request in the task gets rejected by the provider.

Context (who is affected and when)

Anyone with MCP tools whose mcp--<server>--<tool> name goes over 64 characters, on a provider that validates tool names found in the history: Bedrock Converse (also when reached through a LiteLLM / OpenAI-compatible proxy) and Azure OpenAI both reject them. Once it happens the task is stuck as is, since every retry replays the same history (see the workaround below).

Reproduction steps

  1. Add an MCP server named e.g. company-gateway-tools (21 chars) that exposes a tool named confluence-confluence_get_space_page_tree (41 chars). The full name mcp--company-gateway-tools--confluence-confluence_get_space_page_tree is 69 chars, so the tool is declared as mcp--company-gateway-tools--confluence-confluence_get_space_page.
  2. Use the LiteLLM provider, pointed at a LiteLLM proxy serving Claude Haiku 5.5 from Bedrock, and run a task that ends up using that tool.
  3. The model calls the tool, the call succeeds.
  4. The next request fails with the error below, and so does every retry.

Expected result

The tool name written to the API history is the one declared to the model, so it stays within the provider's limit and the task keeps working.

Actual result

400 ... Value at 'messages.190.member.content.1.member.toolUse.name' failed to satisfy constraint: Member must have length less than or equal to 64 on every request after the call.

Variations tried (optional)

Bedrock reports a single validation error, on the history entry only: the tool definitions sent in the same request pass, which they always do since buildMcpToolName caps them at 64. So the >64-char name can only come from the model's own tool call, which is kept verbatim (name: toolCall.name in NativeToolCallParser.parseDynamicMcpTool, then name: mcpBlock.name in Task.ts), while parseMcpToolName happily resolves the uncut name to the right server and tool.

Same request shape sent straight to a LiteLLM proxy on /v1/chat/completions, with a 71-char tool name present only in the history:

  • Bedrock Converse (Claude Haiku 5.5): 400 toolUse.name ... Member must have length less than or equal to 64
  • Azure OpenAI (gpt-5-mini): 400 Invalid 'messages[1].tool_calls[0].function.name': string too long. Expected a string with maximum length 64
  • Anthropic Messages API (/v1/messages): 200

Workaround: rename the MCP server so every mcp--<server>--<tool> fits in 64 characters. Renaming alone does not unblock a task that already has the long name in its history: condense the context (tool blocks are turned into text for the summary and the history restarts from it) or start a new task.

Code (at 8018cba):

  • cut:
    export function buildMcpToolName(serverName: string, toolName: string): string {
    const sanitizedServer = sanitizeMcpName(serverName)
    const sanitizedTool = sanitizeMcpName(toolName)
    // Build the full name: mcp--{server}--{tool}
    const fullName = `${MCP_TOOL_PREFIX}${MCP_TOOL_SEPARATOR}${sanitizedServer}${MCP_TOOL_SEPARATOR}${sanitizedTool}`
    // Truncate if necessary (max 64 chars for Gemini)
    if (fullName.length > 64) {
    return fullName.slice(0, 64)
  • model-returned name kept:
  • written to history:
    name: mcpBlock.name, // Original dynamic name

Possible fix, two parts: write the history entry under the declared name (e.g. rebuild it with buildMcpToolName(serverName, toolName) from what parseMcpToolName returned) so a long name can never reach the history, and replace the plain cut with a hash suffix so the declared name no longer looks like a word cut in half that the model wants to complete. The hash suffix was tried in Roo Code: RooCodeInc/Roo-Code#10770 (from RooCodeInc/Roo-Code#10766), closed without merge when the fuzzy-matching rewrite landed, and that rewrite kept the cut.

App Version

v3.88.0

API Provider (optional)

LiteLLM

Model Used (optional)

Claude Haiku 5.5 (Amazon Bedrock, through a LiteLLM proxy)

Relevant logs or errors (optional)

LiteLLM streaming error: 400 litellm.BadRequestError: BedrockException - {"message":"1 validation error detected: Value at 'messages.190.member.content.1.member.toolUse.name' failed to satisfy constraint: Member must have length less than or equal to 64"}

Activity

  1. PierrunoYT commented on Oct 20, 2026

    @PierrunoYT
    Contributor

    Working on this!

  2. added a commit that references this issue on Oct 25, 2026
    76be781
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions