Skip to main content

mcp_utils/client/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum McpError {
5    /// Tool not found in the registry
6    #[error("Tool not found: {0}")]
7    ToolNotFound(String),
8    /// The tool is model-visible and cannot be called through the deferred route.
9    #[error("Tool '{tool_name}' is exposed directly; call '{direct_name}' instead")]
10    DirectToolRequiresDirectRoute { tool_name: String, direct_name: String },
11    /// Invalid tool name format (should be `server__tool`)
12    #[error("Invalid tool name format: {0}")]
13    InvalidToolNameFormat(String),
14    /// MCP server not found
15    #[error("Server not found: {0}")]
16    ServerNotFound(String),
17    /// Failed to execute tool on MCP server
18    #[error("Failed to execute tool {tool_name} on server {server_name}: {error}")]
19    ToolExecutionFailed { tool_name: String, server_name: String, error: String },
20    /// Tool execution returned an error
21    #[error("Tool execution failed: {0}")]
22    ToolExecutionError(String),
23    /// Tool discovery failed
24    #[error("Tool discovery failed: {0}")]
25    ToolDiscoveryFailed(String),
26    /// Prompt not found in the registry
27    #[error("Prompt not found: {0}")]
28    PromptNotFound(String),
29    /// Prompt listing failed
30    #[error("Prompt listing failed: {0}")]
31    PromptListFailed(String),
32    /// Prompt retrieval failed
33    #[error("Prompt retrieval failed: {0}")]
34    PromptGetFailed(String),
35    /// A configured server conflicts with an Aether-owned instruction namespace.
36    #[error("MCP server name '{0}' is reserved by Aether")]
37    ReservedServerName(String),
38    /// No factory was registered for a declarative in-memory server.
39    #[error("In-memory MCP server '{server}' requires unregistered factory '{factory}'")]
40    InMemoryFactoryNotFound { server: String, factory: String },
41    /// Failed to spawn a stdio server process
42    #[error("Failed to spawn '{command}': {reason}")]
43    SpawnFailed { command: String, reason: String },
44    /// Server connection failed
45    #[error("Connection failed: {0}")]
46    ConnectionFailed(String),
47    /// Server startup failed
48    #[error("Server startup failed: {0}")]
49    ServerStartupFailed(String),
50    /// Transport error
51    #[error("Transport error: {0}")]
52    TransportError(String),
53    /// JSON serialization/deserialization error
54    #[error("JSON error: {0}")]
55    JsonError(String),
56    /// Generic error for other cases
57    #[error("{0}")]
58    Other(String),
59}
60
61impl From<serde_json::Error> for McpError {
62    fn from(error: serde_json::Error) -> Self {
63        McpError::JsonError(error.to_string())
64    }
65}
66
67impl From<std::io::Error> for McpError {
68    fn from(error: std::io::Error) -> Self {
69        McpError::TransportError(error.to_string())
70    }
71}
72
73impl From<rmcp::service::ClientInitializeError> for McpError {
74    fn from(error: rmcp::service::ClientInitializeError) -> Self {
75        McpError::ConnectionFailed(error.to_string())
76    }
77}
78
79pub type Result<T> = std::result::Result<T, McpError>;