rust_mcp_sdk/mcp_handlers/
mcp_server_handler.rs

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