Kuberwastaken/claurst · error · anyhow::Error
MCP server ' ': tool ' ' call failed
Error message
MCP server '{}': tool '{}' call failed: {} What it means
McpClient::call_tool forwards a tools/call to the server backend and wraps any backend error with the server name and tool name for context. The trailing `{}` contains the underlying rmcp/transport error, so the root cause (JSON-RPC error, timeout, connection drop, tool returning is_error) is in the wrapped cause.
Solutions
- Read the wrapped cause in the message to identify the concrete failure
- Validate arguments against the tool's inputSchema (from tools/list) before calling
- Confirm the tool name exists on that server via tools/list
- Retry the call if the cause is a timeout/connection error; restart the server if it crashed
Defensive patterns
Strategy: try-catch
Try / catch
match client.call_tool(name, args).await {
Err(e) if e.to_string().contains("call failed") => {
eprintln!("tool {name} failed: {e:#}"); // inspect full cause chain
}
r => r?,
} Prevention
- Fetch tools/list and validate arguments against inputSchema before calling
- Add timeouts and one retry for transient transport causes
- Re-list tools after server restarts to avoid stale names
When it happens
Trigger: Calling call_tool(name, arguments) on a connected MCP client where the server rejects or fails the call: unknown tool on that server, invalid arguments schema, server-side exception, timeout, or connection lost mid-call.
Common situations: Wrong tool arguments not matching the server's inputSchema; tool execution crashed on the server; MCP server hung and the request timed out; connection dropped after a restart.
Related errors
- rmcp list_tools failed
- rmcp call_tool ' ' failed
- rmcp list_resources failed
- rmcp read_resource ' ' failed
- rmcp read_resource ' ' returned no contents
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/c9850fe2b7882361.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/mcp/src/lib.rs:686
/// already have env vars expanded via `expand_server_config`.
pub async fn connect_stdio(config: &McpServerConfig) -> anyhow::Result<Self> {
let backend = crate::rmcp_backend::RmcpClientBackend::connect_stdio(config).await?;
Ok(Self::from_backend(Arc::new(backend)))
}
// ---- High-level API -----------------------------------------------
pub async fn list_tools(&self) -> anyhow::Result<Vec<McpTool>> {
self.backend()?.list_tools().await
}
pub async fn call_tool(
&self,
name: &str,
arguments: Option<Value>,
) -> anyhow::Result<CallToolResult> {
self.backend()?.call_tool(name, arguments).await.map_err(|e| {
anyhow::anyhow!(
"MCP server '{}': tool '{}' call failed: {}",
self.server_name,
name,
e
)
})
}
pub async fn list_resources(&self) -> anyhow::Result<Vec<McpResource>> {
let mut resources = self.backend()?.list_resources().await?;
apply_resource_templates(&mut resources);
Ok(resources)
}
pub async fn read_resource(&self, uri: &str) -> anyhow::Result<ResourceContents> {
self.backend()?.read_resource(uri).await
}
View on GitHub (pinned to b0637c97ec)