Kuberwastaken/claurst · error

rmcp list_tools failed

Error message

rmcp list_tools failed: {}

What it means

Raised in `RmcpClientBackend::list_tools` when the underlying rmcp peer's `list_all_tools()` future fails. The rmcp peer round-trips a `tools/list` JSON-RPC request to the MCP server; any failure — transport error, JSON-RPC error response from the server, timeout, or a closed session — is surfaced here with a uniform `rmcp list_tools failed: <cause>` message. The original rmcp error is preserved after the colon.

Solutions

  1. Read the inner error: 'method not found' means the server lacks tools support; 'transport closed' means reconnect.
  2. Reconnect the MCP backend (restart the session) and retry list_tools.
  3. Verify the MCP server actually implements the `tools` capability (check its docs/capabilities line at startup).
  4. If the session is stale (server restarted), recreate the client instead of reusing the old peer handle.

Example fix

// before: assuming tools always exist
let tools = backend.list_tools().await?;
// after: degrade gracefully when the server has no tools capability
let tools = match backend.list_tools().await {
    Ok(t) => t,
    Err(e) if e.to_string().contains("method not found") => Vec::new(),
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Validate before calling

fn server_supports_tools(init_caps: &ServerCapabilities) -> bool {
    init_caps.tools.is_some()
}

Try / catch

match backend.list_tools().await {
    Ok(tools) => tools,
    Err(e) if e.to_string().contains("method not found") => Vec::new(),
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling `McpClientBackend::list_tools` on an rmcp backend when the server rejects `tools/list`: server does not support the tools capability, session was closed/restarted, transport send/receive failed, or the server returned a JSON-RPC error (e.g. -32601 method not found).

Common situations: MCP server that implements only prompts/resources but not tools; server restarted between connect and list; legacy SSE endpoint stale after reconnect; server-side timeout on a very large tool listing; user runs an /mcp tools command against a misconfigured server.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/f2c6ca2b4eb1be8f. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/mcp/src/rmcp_backend.rs:508

    Ok(())
}

#[async_trait]
impl McpClientBackend for RmcpClientBackend {
    fn kind(&self) -> McpBackendKind {
        McpBackendKind::Rmcp
    }

    fn snapshot(&self) -> McpClientSnapshot {
        self.snapshot.clone()
    }

    async fn list_tools(&self) -> anyhow::Result<Vec<McpTool>> {
        let tools = self
            .peer
            .list_all_tools()
            .await
            .map_err(|e| anyhow::anyhow!("rmcp list_tools failed: {}", e))?;
        Ok(tools.into_iter().map(convert_tool).collect())
    }

    async fn call_tool(
        &self,
        name: &str,
        arguments: Option<Value>,
    ) -> anyhow::Result<CallToolResult> {
        let mut params = rmcp_model::CallToolRequestParams::new(name.to_string());
        if let Some(arguments) = arguments {
            params = params.with_arguments(json_value_to_object(arguments)?);
        }
        let result = self
            .peer
            .call_tool(params)
            .await
            .map_err(|e| anyhow::anyhow!("rmcp call_tool '{}' failed: {}", name, e))?;
        Ok(convert_call_tool_result(result))

View on GitHub (pinned to b0637c97ec)