rust_mcp_sdk/mcp_handlers/
mcp_client_handler.rs

1use crate::schema::{
2    CancelledNotification, CreateMessageRequest, CreateMessageResult, ListRootsRequest,
3    ListRootsResult, LoggingMessageNotification, PingRequest, ProgressNotification,
4    PromptListChangedNotification, ResourceListChangedNotification, ResourceUpdatedNotification,
5    Result, RpcError, ToolListChangedNotification,
6};
7#[cfg(feature = "2025_06_18")]
8use crate::schema::{ElicitRequest, ElicitResult};
9
10use async_trait::async_trait;
11use serde_json::Value;
12
13use crate::mcp_traits::mcp_client::McpClient;
14
15/// Defines the `ClientHandler` trait for handling Model Context Protocol (MCP) operations on a client.
16/// This trait provides default implementations for request and notification handlers in an MCP client,
17/// allowing developers to override methods for custom behavior.
18#[allow(unused)]
19#[async_trait]
20pub trait ClientHandler: Send + Sync + 'static {
21    //**********************//
22    //** Request Handlers **//
23    //**********************//
24    async fn handle_ping_request(
25        &self,
26        request: PingRequest,
27        runtime: &dyn McpClient,
28    ) -> std::result::Result<Result, RpcError> {
29        Ok(Result::default())
30    }
31
32    async fn handle_create_message_request(
33        &self,
34        request: CreateMessageRequest,
35        runtime: &dyn McpClient,
36    ) -> std::result::Result<CreateMessageResult, RpcError> {
37        runtime.assert_client_request_capabilities(request.method())?;
38        Err(RpcError::method_not_found().with_message(format!(
39            "No handler is implemented for '{}'.",
40            request.method(),
41        )))
42    }
43
44    async fn handle_list_roots_request(
45        &self,
46        request: ListRootsRequest,
47        runtime: &dyn McpClient,
48    ) -> std::result::Result<ListRootsResult, RpcError> {
49        runtime.assert_client_request_capabilities(request.method())?;
50        Err(RpcError::method_not_found().with_message(format!(
51            "No handler is implemented for '{}'.",
52            request.method(),
53        )))
54    }
55
56    #[cfg(feature = "2025_06_18")]
57    async fn handle_elicit_request(
58        &self,
59        request: ElicitRequest,
60        runtime: &dyn McpClient,
61    ) -> std::result::Result<ElicitResult, RpcError> {
62        runtime.assert_client_request_capabilities(request.method())?;
63        Err(RpcError::method_not_found().with_message(format!(
64            "No handler is implemented for '{}'.",
65            request.method(),
66        )))
67    }
68
69    async fn handle_custom_request(
70        &self,
71        request: Value,
72        runtime: &dyn McpClient,
73    ) -> std::result::Result<ListRootsResult, RpcError> {
74        Err(RpcError::method_not_found()
75            .with_message("No handler is implemented for custom requests.".to_string()))
76    }
77
78    //***************************//
79    //** Notification Handlers **//
80    //***************************//
81
82    async fn handle_cancelled_notification(
83        &self,
84        notification: CancelledNotification,
85        runtime: &dyn McpClient,
86    ) -> std::result::Result<(), RpcError> {
87        Ok(())
88    }
89
90    async fn handle_progress_notification(
91        &self,
92        notification: ProgressNotification,
93        runtime: &dyn McpClient,
94    ) -> std::result::Result<(), RpcError> {
95        Ok(())
96    }
97
98    async fn handle_resource_list_changed_notification(
99        &self,
100        notification: ResourceListChangedNotification,
101        runtime: &dyn McpClient,
102    ) -> std::result::Result<(), RpcError> {
103        Ok(())
104    }
105
106    async fn handle_resource_updated_notification(
107        &self,
108        notification: ResourceUpdatedNotification,
109        runtime: &dyn McpClient,
110    ) -> std::result::Result<(), RpcError> {
111        Ok(())
112    }
113
114    async fn handle_prompt_list_changed_notification(
115        &self,
116        notification: PromptListChangedNotification,
117        runtime: &dyn McpClient,
118    ) -> std::result::Result<(), RpcError> {
119        Ok(())
120    }
121
122    async fn handle_tool_list_changed_notification(
123        &self,
124        notification: ToolListChangedNotification,
125        runtime: &dyn McpClient,
126    ) -> std::result::Result<(), RpcError> {
127        Ok(())
128    }
129
130    async fn handle_logging_message_notification(
131        &self,
132        notification: LoggingMessageNotification,
133        runtime: &dyn McpClient,
134    ) -> std::result::Result<(), RpcError> {
135        Ok(())
136    }
137
138    async fn handle_custom_notification(
139        &self,
140        notification: Value,
141        runtime: &dyn McpClient,
142    ) -> std::result::Result<(), RpcError> {
143        Ok(())
144    }
145
146    //********************//
147    //** Error Handlers **//
148    //********************//
149    async fn handle_error(
150        &self,
151        error: RpcError,
152        runtime: &dyn McpClient,
153    ) -> std::result::Result<(), RpcError> {
154        Ok(())
155    }
156
157    async fn handle_process_error(
158        &self,
159        error_message: String,
160        runtime: &dyn McpClient,
161    ) -> std::result::Result<(), RpcError> {
162        if !runtime.is_shut_down().await {
163            tracing::error!("Process error: {error_message}");
164        }
165        Ok(())
166    }
167}