Kuberwastaken/claurst · error · anyhow::Error
No MCP server found for tool
Error message
No MCP server found for tool '{}'. Connected servers: [{}] What it means
The MCP aggregator exposes tools under a `<server_name>_<tool_name>` prefix. When call_prefixed_tool (or similar) receives a prefixed name whose prefix matches no connected server, it throws this error listing the currently connected servers.
Solutions
- Check the "Connected servers" list in the message — the server you need isn't connected; fix its config and reconnect
- Use the correct `<server>_<tool>` prefix exactly as the connected server is named
- Refresh the tool list after (re)connecting servers so stale tool names aren't invoked
- Watch for ambiguous prefix collisions: the first matching server prefix wins, so avoid server names that are prefixes of each other
Example fix
// before
call("filesytem_read_file", ...) // typo'd server name
// after
call("filesystem_read_file", ...) Defensive patterns
Strategy: validation
Validate before calling
fn server_for_tool<'a>(clients: &'a HashMap<String, McpClient>, tool: &str) -> Option<&'a String> {
clients.keys().find(|s| tool.starts_with(&format!("{s}_")))
} Try / catch
match call_prefixed_tool(prefixed, args).await {
Err(e) if e.to_string().starts_with("No MCP server found for tool") => {
refresh_tool_registry().await; // reconnect and rebuild tool list
}
r => r?,
} Prevention
- Rebuild cached tool lists whenever servers connect/disconnect
- Avoid server names that are prefixes of one another
- Validate tool names against the live registry before dispatch
When it happens
Trigger: Invoking a tool whose prefix doesn't match any entry in self.clients: server disconnected, tool name referenced with the wrong server prefix, or a cached/stale tool name after the server list changed.
Common situations: MCP server failed to connect at startup so its tools are gone but cached UI still lists them; renamed server in config without updating tool references; nested underscores confusing which part is the prefix; connecting a server that exposes tools with the same prefix.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Bridge session registration failed: authentication error
- failed to resolve legacy SSE endpoint
- Failed to store MCP token for
- invalid legacy SSE base URL
- legacy SSE endpoint event did not include a POST endpoint
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/df33a588faebcbe6.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/mcp/src/lib.rs:1049
}
defs
}
/// Execute a tool call, routing to the correct server.
/// Tool name format: `<server_name>_<tool_name>`.
pub async fn call_tool(
&self,
prefixed_name: &str,
arguments: Option<Value>,
) -> anyhow::Result<CallToolResult> {
// Find the server name by matching prefix
for (server_name, client) in &self.clients {
let prefix = format!("{}_", server_name);
if let Some(tool_name) = prefixed_name.strip_prefix(&prefix) {
return client.call_tool(tool_name, arguments).await;
}
}
Err(anyhow::anyhow!(
"No MCP server found for tool '{}'. Connected servers: [{}]",
prefixed_name,
self.clients.keys().cloned().collect::<Vec<_>>().join(", ")
))
}
/// Number of connected servers.
pub fn server_count(&self) -> usize {
self.clients.len()
}
/// Get server instructions (from initialize response).
pub fn server_instructions(&self) -> Vec<(String, String)> {
self.clients
.iter()
.filter_map(|(name, client)| {
client.instructions.as_ref().map(|instr| (name.clone(), instr.clone()))
})
View on GitHub (pinned to b0637c97ec)