shareAI-lab/learn-claude-code · error · ValueError
MCP tool name is longer than 64 characters: {prefixed}
Error message
MCP tool name is longer than 64 characters: {prefixed} What it means
When building the unified tool catalog, each MCP tool becomes 'mcp__<server>__<tool>' (both parts normalized). The model's tool-name limit is 64 characters, so a prefixed name longer than that raises ValueError at catalog-build time — better than shipping a tool the model can never call.
Source
Thrown at s14_mcp_plugin/code.py:331
def assemble_tool_pool() -> tuple[list[dict], dict[str, callable]]:
"""Combine built-in tools with every connected server tool."""
global mcp_tool_policies
tools = list(BUILTIN_TOOLS)
handlers = dict(BUILTIN_HANDLERS)
policies: dict[str, str] = {}
origins = {
tool["name"]: f"built-in tool {tool['name']!r}"
for tool in tools
}
for server_name, server in mcp_clients.items():
safe_server = normalize_mcp_name(server_name)
for tool_def in server.tools:
raw_name = tool_def["name"]
safe_tool = normalize_mcp_name(raw_name)
prefixed = f"mcp__{safe_server}__{safe_tool}"
if len(prefixed) > 64:
raise ValueError(f"MCP tool name is longer than 64 characters: {prefixed}")
origin = f"MCP tool {server_name!r}/{raw_name!r}"
if prefixed in origins:
raise ValueError(
"MCP tool name collision after normalization: "
f"{prefixed!r} maps both {origins[prefixed]} and {origin}"
)
schema = tool_def.get("inputSchema", {})
if not isinstance(schema, dict) or schema.get("type", "object") != "object":
raise ValueError(f"Invalid input schema for {origin}")
origins[prefixed] = origin
tools.append({
"name": prefixed,
"description": tool_def.get("description", ""),
"input_schema": schema,
})
handlers[prefixed] = (
lambda *, client=server, tool=raw_name, **kwargs:
client.call_tool(tool, kwargs)View on GitHub (pinned to 985456f4ad)
Solutions
- Shorten the server name in its MCPClient('name') constructor (biggest lever, it appears once per tool).
- Rename the offending tool(s) to concise verbs.
- Budget: total = 6 + len(server) + 2 + len(tool); keep server+tool under ~56 chars.
Example fix
// before
server = MCPClient('internal-documentation-platform')
// tool 'search_across_all_versions' -> prefixed 60+? over 64 -> ValueError
// after
server = MCPClient('docops') // 'mcp__docops__search_across_all_versions' fits Defensive patterns
Strategy: validation
Validate before calling
def prefixed_name_len(server: str, tool: str) -> int:
return len(f'mcp__{server}__{tool}')
def fits_model_limit(server: str, tool: str) -> bool:
return prefixed_name_len(server, tool) <= 64 Prevention
- Keep MCP server names short (<= 20 chars) — they tax every tool name.
- Name tools with concise verbs; budget 6 + server + 2 + tool <= 64.
- Add a CI check that builds the catalog against the real config to catch long names early.
When it happens
Trigger: A server named 'internal-documentation-platform' with a tool named 'search_across_all_versions' produces a >64-char prefixed name; long hyphenated server names from config; verbose auto-generated tool names.
Common situations: Real-world MCP server names (often domain-like) combined with descriptive tool verbs; mirrors of external APIs with long method names.
Related errors
- Every MCP tool needs a non-empty name
- Duplicate MCP tool name on server {self.name!r}
- Missing MCP handlers: {', '.join(missing)}
- Invalid input schema for {origin}
- Every MCP tool needs a non-empty name
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/37e8cac0ecfe8b2c.
Report an issue: GitHub.