{"record":{"id":"72b9ba92b62cf7af","repo":"shareAI-lab/learn-claude-code","slug":"mcp-tool-name-is-longer-than-64-characters-prefi-72b9ba","errorCode":null,"errorMessage":"MCP tool name is longer than 64 characters: {prefixed}","messagePattern":"MCP tool name is longer than 64 characters: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"s15_integrated_harness/code.py","lineNumber":2552,"sourceCode":"            f\"Discovered {len(mcp_client.tools)} tools: {', '.join(tool_names)}\")\n\n\ndef assemble_tool_pool() -> tuple[list[dict], dict]:\n    \"\"\"Merge builtin tools + all MCP tools into one pool.\"\"\"\n    global mcp_tool_policies\n    tools = list(BUILTIN_TOOLS)\n    handlers = dict(BUILTIN_HANDLERS)\n    policies: dict[str, str] = {}\n    origins = {tool[\"name\"]: f\"built-in tool {tool['name']!r}\"\n               for tool in tools}\n    for server_name, mcp_client in mcp_clients.items():\n        safe_server = normalize_mcp_name(server_name)\n        for tool_def in mcp_client.tools:\n            raw_name = tool_def[\"name\"]\n            safe_tool = normalize_mcp_name(raw_name)\n            prefixed = f\"mcp__{safe_server}__{safe_tool}\"\n            if len(prefixed) > 64:\n                raise ValueError(\n                    f\"MCP tool name is longer than 64 characters: {prefixed}\"\n                )\n            origin = f\"MCP tool {server_name!r}/{raw_name!r}\"\n            if prefixed in origins:\n                raise ValueError(\n                    \"MCP tool name collision after normalization: \"\n                    f\"{prefixed!r} maps both {origins[prefixed]} and {origin}\"\n                )\n            schema = tool_def.get(\"inputSchema\", {})\n            if not isinstance(schema, dict) or schema.get(\"type\", \"object\") != \"object\":\n                raise ValueError(f\"Invalid input schema for {origin}\")\n            origins[prefixed] = origin\n            tools.append({\n                \"name\": prefixed,\n                \"description\": tool_def.get(\"description\", \"\"),\n                \"input_schema\": schema,\n            })\n            handlers[prefixed] = (","sourceCodeStart":2534,"sourceCodeEnd":2570,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/s15_integrated_harness/code.py#L2534-L2570","documentation":"When the host harness merges MCP client tools into its tool table it prefixes each name as mcp__<server>__<tool> and enforces a 64-character limit matching the model's tool-name alphabet. A longer name is rejected with ValueError at wiring time because the upstream model API would reject or truncate it later.","triggerScenarios":"Registering a server with a long name (e.g. 'internal-documentation-services') plus a long tool name (e.g. 'search_across_all_namespaces') so that 5 + len(server) + 2 + len(tool) > 64. Note normalization can grow names: each disallowed character becomes '_' (1:1), but names near the limit tip over once prefixed.","commonSituations":"Connecting enterprise MCP servers whose names mirror hostnames or service FQDNs. Teams renaming tools descriptively (verb_object_qualifier) over time until the budget is exceeded.","solutions":["Shorten the server alias used as the dict key when registering mcp_clients (e.g. 'docs' instead of 'documentation-service-prod')","Shorten the tool name in the MCP server's tool_defs","Compute the prefixed length in a pre-flight check before starting the harness"],"exampleFix":"# before\nmcp_clients = {\n    \"internal_documentation_services\": docs_client,  # tool 'search_all_namespaces' -> 5+29+2+20 = too long\n}\n\n# after\nmcp_clients = {\n    \"docs\": docs_client,  # mcp__docs__search_all_namespaces fits in 64\n}","handlingStrategy":"validation","validationCode":"def fits_tool_name_budget(server: str, tool: str) -> bool:\n    return len(f\"mcp__{server}__{tool}\") <= 64\n\nfor server_name, client in mcp_clients.items():\n    for tool in client.tools:\n        assert fits_tool_name_budget(server_name, tool), f\"{server_name}/{tool} too long\"","typeGuard":"def is_within_mcp_name_limit(server: str, tool: str) -> bool:\n    return isinstance(server, str) and isinstance(tool, str) and len(f\"mcp__{server}__{tool}\") <= 64","tryCatchPattern":"try:\n    harness = build_harness(mcp_clients)\nexcept ValueError as exc:\n    if \"longer than 64 characters\" in str(exc):\n        # shorten the server alias or tool name, then rebuild\n        raise SystemExit(str(exc)) from exc\n    raise","preventionTips":["Use short server aliases (<15 chars) as dict keys","Pre-flight check all prefixed lengths before startup","Watch growth when renaming tools descriptively"],"tags":["mcp","validation","naming","limits"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}