Hmbown/CodeWhale · error · anyhow::Error
qualified MCP tool name '{qualified_tool_name}' is ambiguous
Error message
qualified MCP tool name '{qualified_tool_name}' is ambiguous across servers: {} What it means
McpRegistry::call_qualified_tool() could not resolve the qualified name against an exact registered server, so it scanned every running server's tools for ones whose qualified name equals the request — and found two or more. Sanitization folds '-', '.', and case into '_', and the mcp__<server>__<tool> join uses '__', so different (server, tool) pairs can flatten to the same string (e.g. server 'a' tool 'b__c' vs server 'a_b' tool 'c' both yield mcp__a__b__c). The message lists the sorted server names that match; dispatch refuses to pick one because iteration order is not a choice.
Source
Thrown at crates/mcp/src/lib.rs:454
}
}
match matches.len() {
0 => {}
1 => {
let (server_name, tool_name) = &matches[0];
let client = self
.clients
.get(*server_name)
.with_context(|| format!("MCP server '{server_name}' not available"))?;
return client.call_tool(tool_name, arguments);
}
_ => {
matches.sort();
let servers: Vec<&str> = matches
.iter()
.map(|(server_name, _)| server_name.as_str())
.collect();
bail!(
"qualified MCP tool name '{qualified_tool_name}' is ambiguous across servers: \
{}",
servers.join(", ")
);
}
}
let (server_name, tool_name) = parsed?;
self.call_tool(&server_name, &tool_name, arguments)
}
/// List all resources from all running servers.
pub fn list_resources(&self) -> Result<Vec<McpResourceDescriptor>> {
let mut out = Vec::new();
for server_name in self.configs.keys() {
let Some(client) = self.clients.get(server_name) else {
continue;
};View on GitHub (pinned to 0c42157ee5)
Solutions
- Use the exact registered server name in the server segment so the exact-registration path resolves without scanning
- Prefer call_tool(server, tool, args) with explicit names when you know the target server
- Rename one of the colliding servers or tools so their qualified names no longer flatten to the same string
Example fix
// before
let v = registry.call_qualified_tool("mcp__a__b__c", args)?; // matches a/b__c and a_b/c
// after: name the server exactly
let v = registry.call_tool("a_b", "c", args)?; Defensive patterns
Strategy: validation
Validate before calling
// Prefer the unambiguous direct API when you know the server:
registry.call_tool("a_b", "c", args)?;
// If you must use qualified names, ensure the server segment exactly matches a registered name
// and the name was produced by the crate's qualify helper, not hand-built. Type guard
fn is_exact_qualified_name(name: &str, registered: &[String]) -> bool {
name.starts_with("mcp__")
&& name[5..].split_once("__").is_some_and(|(server, _)| {
registered.iter().any(|r| r == server)
})
} Try / catch
match registry.call_qualified_tool(name, args) {
Ok(v) => Ok(v),
Err(err) if err.to_string().contains("is ambiguous across servers") => {
// pick a server from the listed candidates and call it directly
let server = pick_server_from_error(&err)?;
registry.call_tool(&server, &tool, args)
}
Err(err) => Err(err),
} Prevention
- Build qualified names with the crate's formatter; never concatenate by hand
- Avoid '__' inside tool or server names so flattening cannot overlap
- Route calls through call_tool(server, tool) whenever the target server is known
When it happens
Trigger: Passing a qualified name whose server segment does not exactly match a registered server name, forcing the scan path, while two servers expose tools that flatten to that same qualified name; servers whose names contain underscores combined with tools whose names contain '__'; duplicates of the same server registered under near-identical names.
Common situations: Hand-built qualified names copied from logs; tool catalogs where generic tool names ('run', 'search') exist on several servers and the caller dropped or mistyped the server segment; name changes after sanitization rules were tightened.
Related errors
- Ambiguous MCP tool name '{prefixed_name}' matches more than
- MCP server '{}' collides with already-registered server '{ex
- missing mcp__ prefix
- app-server auth token cannot be empty
- API key contains invalid control characters
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/37bb22a2a9576561.
Report an issue: GitHub.