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

  1. Check the "Connected servers" list in the message — the server you need isn't connected; fix its config and reconnect
  2. Use the correct `<server>_<tool>` prefix exactly as the connected server is named
  3. Refresh the tool list after (re)connecting servers so stale tool names aren't invoked
  4. 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

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


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)