rust_mcp_sdk/mcp_handlers/
mcp_server_handler.rs

1use crate::schema::{schema_utils::CallToolError, *};
2use async_trait::async_trait;
3use serde_json::Value;
4use std::sync::Arc;
5
6use crate::{mcp_traits::mcp_server::McpServer, utils::enforce_compatible_protocol_version};
7
8/// Defines the `ServerHandler` trait for handling Model Context Protocol (MCP) operations on a server.
9/// This trait provides default implementations for request and notification handlers in an MCP server,
10/// allowing developers to override methods for custom behavior.
11#[allow(unused)]
12#[async_trait]
13pub trait ServerHandler: Send + Sync + 'static {
14    /// Invoked when the server finishes initialization and receives an `initialized_notification` from the client.
15    ///
16    /// The `runtime` parameter provides access to the server's runtime environment, allowing
17    /// interaction with the server's capabilities.
18    /// The default implementation does nothing.
19    async fn on_initialized(&self, runtime: Arc<dyn McpServer>) {}
20
21    /// Handles the InitializeRequest from a client.
22    ///
23    /// # Arguments
24    /// * `initialize_request` - The initialization request containing client parameters
25    /// * `runtime` - Reference to the MCP server runtime
26    ///
27    /// # Returns
28    /// Returns the server info as InitializeResult on success or a JSON-RPC error on failure
29    /// Do not override this unless the standard initialization process doesn't work for you or you need to modify it.
30    async fn handle_initialize_request(
31        &self,
32        initialize_request: InitializeRequest,
33        runtime: Arc<dyn McpServer>,
34    ) -> std::result::Result<InitializeResult, RpcError> {
35        let mut server_info = runtime.server_info().to_owned();
36        // Provide compatibility for clients using older MCP protocol versions.
37
38        if let Some(updated_protocol_version) = enforce_compatible_protocol_version(
39            &initialize_request.params.protocol_version,
40            &server_info.protocol_version,
41        )
42        .map_err(|err| {
43            tracing::error!(
44                "Incompatible protocol version : client: {} server: {}",
45                &initialize_request.params.protocol_version,
46                &server_info.protocol_version
47            );
48            RpcError::internal_error().with_message(err.to_string())
49        })? {
50            server_info.protocol_version = updated_protocol_version;
51        }
52
53        runtime
54            .set_client_details(initialize_request.params.clone())
55            .await
56            .map_err(|err| RpcError::internal_error().with_message(format!("{err}")))?;
57
58        Ok(server_info)
59    }
60
61    /// Handles ping requests from clients.
62    ///
63    /// # Returns
64    /// By default, it returns an empty result structure
65    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
66    async fn handle_ping_request(
67        &self,
68        _: PingRequest,
69        _: Arc<dyn McpServer>,
70    ) -> std::result::Result<Result, RpcError> {
71        Ok(Result::default())
72    }
73
74    /// Handles requests to list available resources.
75    ///
76    /// Default implementation returns method not found error.
77    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
78    async fn handle_list_resources_request(
79        &self,
80        request: ListResourcesRequest,
81        runtime: Arc<dyn McpServer>,
82    ) -> std::result::Result<ListResourcesResult, RpcError> {
83        runtime.assert_server_request_capabilities(request.method())?;
84        Err(RpcError::method_not_found().with_message(format!(
85            "No handler is implemented for '{}'.",
86            request.method(),
87        )))
88    }
89
90    /// Handles requests to list resource templates.
91    ///
92    /// Default implementation returns method not found error.
93    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
94    async fn handle_list_resource_templates_request(
95        &self,
96        request: ListResourceTemplatesRequest,
97        runtime: Arc<dyn McpServer>,
98    ) -> std::result::Result<ListResourceTemplatesResult, RpcError> {
99        runtime.assert_server_request_capabilities(request.method())?;
100        Err(RpcError::method_not_found().with_message(format!(
101            "No handler is implemented for '{}'.",
102            request.method(),
103        )))
104    }
105
106    /// Handles requests to read a specific resource.
107    ///
108    /// Default implementation returns method not found error.
109    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
110    async fn handle_read_resource_request(
111        &self,
112        request: ReadResourceRequest,
113        runtime: Arc<dyn McpServer>,
114    ) -> std::result::Result<ReadResourceResult, RpcError> {
115        runtime.assert_server_request_capabilities(request.method())?;
116        Err(RpcError::method_not_found().with_message(format!(
117            "No handler is implemented for '{}'.",
118            request.method(),
119        )))
120    }
121
122    /// Handles subscription requests from clients.
123    ///
124    /// Default implementation returns method not found error.
125    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
126    async fn handle_subscribe_request(
127        &self,
128        request: SubscribeRequest,
129        runtime: Arc<dyn McpServer>,
130    ) -> std::result::Result<Result, RpcError> {
131        runtime.assert_server_request_capabilities(request.method())?;
132        Err(RpcError::method_not_found().with_message(format!(
133            "No handler is implemented for '{}'.",
134            request.method(),
135        )))
136    }
137
138    /// Handles unsubscribe requests from clients.
139    ///
140    /// Default implementation returns method not found error.
141    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
142    async fn handle_unsubscribe_request(
143        &self,
144        request: UnsubscribeRequest,
145        runtime: Arc<dyn McpServer>,
146    ) -> std::result::Result<Result, RpcError> {
147        runtime.assert_server_request_capabilities(request.method())?;
148        Err(RpcError::method_not_found().with_message(format!(
149            "No handler is implemented for '{}'.",
150            request.method(),
151        )))
152    }
153
154    /// Handles requests to list available prompts.
155    ///
156    /// Default implementation returns method not found error.
157    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
158    async fn handle_list_prompts_request(
159        &self,
160        request: ListPromptsRequest,
161        runtime: Arc<dyn McpServer>,
162    ) -> std::result::Result<ListPromptsResult, RpcError> {
163        runtime.assert_server_request_capabilities(request.method())?;
164        Err(RpcError::method_not_found().with_message(format!(
165            "No handler is implemented for '{}'.",
166            request.method(),
167        )))
168    }
169
170    /// Handles requests to get a specific prompt.
171    ///
172    /// Default implementation returns method not found error.
173    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
174    async fn handle_get_prompt_request(
175        &self,
176        request: GetPromptRequest,
177        runtime: Arc<dyn McpServer>,
178    ) -> std::result::Result<GetPromptResult, RpcError> {
179        runtime.assert_server_request_capabilities(request.method())?;
180        Err(RpcError::method_not_found().with_message(format!(
181            "No handler is implemented for '{}'.",
182            request.method(),
183        )))
184    }
185
186    /// Handles requests to list available tools.
187    ///
188    /// Default implementation returns method not found error.
189    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
190    async fn handle_list_tools_request(
191        &self,
192        request: ListToolsRequest,
193        runtime: Arc<dyn McpServer>,
194    ) -> std::result::Result<ListToolsResult, RpcError> {
195        runtime.assert_server_request_capabilities(request.method())?;
196        Err(RpcError::method_not_found().with_message(format!(
197            "No handler is implemented for '{}'.",
198            request.method(),
199        )))
200    }
201
202    /// Handles requests to call a specific tool.
203    ///
204    /// Default implementation returns an unknown tool error.
205    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
206    async fn handle_call_tool_request(
207        &self,
208        request: CallToolRequest,
209        runtime: Arc<dyn McpServer>,
210    ) -> std::result::Result<CallToolResult, CallToolError> {
211        runtime
212            .assert_server_request_capabilities(request.method())
213            .map_err(CallToolError::new)?;
214        Ok(CallToolError::unknown_tool(format!("Unknown tool: {}", request.params.name)).into())
215    }
216
217    /// Handles requests to enable or adjust logging level.
218    ///
219    /// Default implementation returns method not found error.
220    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
221    async fn handle_set_level_request(
222        &self,
223        request: SetLevelRequest,
224        runtime: Arc<dyn McpServer>,
225    ) -> std::result::Result<Result, RpcError> {
226        runtime.assert_server_request_capabilities(request.method())?;
227        Err(RpcError::method_not_found().with_message(format!(
228            "No handler is implemented for '{}'.",
229            request.method(),
230        )))
231    }
232
233    /// Handles completion requests from clients.
234    ///
235    /// Default implementation returns method not found error.
236    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
237    async fn handle_complete_request(
238        &self,
239        request: CompleteRequest,
240        runtime: Arc<dyn McpServer>,
241    ) -> std::result::Result<CompleteResult, RpcError> {
242        runtime.assert_server_request_capabilities(request.method())?;
243        Err(RpcError::method_not_found().with_message(format!(
244            "No handler is implemented for '{}'.",
245            request.method(),
246        )))
247    }
248
249    /// Handles custom requests not defined in the standard protocol.
250    ///
251    /// Default implementation returns method not found error.
252    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
253    async fn handle_custom_request(
254        &self,
255        request: Value,
256        runtime: Arc<dyn McpServer>,
257    ) -> std::result::Result<Value, RpcError> {
258        Err(RpcError::method_not_found()
259            .with_message("No handler is implemented for custom requests.".to_string()))
260    }
261
262    // Notification Handlers
263
264    /// Handles initialized notifications from clients.
265    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
266    async fn handle_initialized_notification(
267        &self,
268        notification: InitializedNotification,
269        runtime: Arc<dyn McpServer>,
270    ) -> std::result::Result<(), RpcError> {
271        Ok(())
272    }
273
274    /// Handles cancelled operation notifications.
275    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
276    async fn handle_cancelled_notification(
277        &self,
278        notification: CancelledNotification,
279        runtime: Arc<dyn McpServer>,
280    ) -> std::result::Result<(), RpcError> {
281        Ok(())
282    }
283
284    /// Handles progress update notifications.
285    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
286    async fn handle_progress_notification(
287        &self,
288        notification: ProgressNotification,
289        runtime: Arc<dyn McpServer>,
290    ) -> std::result::Result<(), RpcError> {
291        Ok(())
292    }
293
294    /// Handles notifications received from the client indicating that the list of roots has changed
295    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
296    async fn handle_roots_list_changed_notification(
297        &self,
298        notification: RootsListChangedNotification,
299        runtime: Arc<dyn McpServer>,
300    ) -> std::result::Result<(), RpcError> {
301        Ok(())
302    }
303
304    /// Handles custom notifications not defined in the standard protocol.
305    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
306    async fn handle_custom_notification(
307        &self,
308        notification: Value,
309    ) -> std::result::Result<(), RpcError> {
310        Ok(())
311    }
312
313    // Error Handler
314
315    /// Handles server errors that occur during operation.
316    ///
317    /// # Arguments
318    /// * `error` - The error that occurred
319    /// * `runtime` - Reference to the MCP server runtime
320    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
321    async fn handle_error(
322        &self,
323        error: &RpcError,
324        runtime: Arc<dyn McpServer>,
325    ) -> std::result::Result<(), RpcError> {
326        Ok(())
327    }
328}