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            .map_err(|err| RpcError::internal_error().with_message(format!("{err}")))?;
55
56        Ok(server_info)
57    }
58
59    /// Handles ping requests from clients.
60    ///
61    /// # Returns
62    /// By default, it returns an empty result structure
63    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
64    async fn handle_ping_request(
65        &self,
66        _: PingRequest,
67        _: &dyn McpServer,
68    ) -> std::result::Result<Result, RpcError> {
69        Ok(Result::default())
70    }
71
72    /// Handles requests to list available resources.
73    ///
74    /// Default implementation returns method not found error.
75    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
76    async fn handle_list_resources_request(
77        &self,
78        request: ListResourcesRequest,
79        runtime: &dyn McpServer,
80    ) -> std::result::Result<ListResourcesResult, RpcError> {
81        runtime.assert_server_request_capabilities(request.method())?;
82        Err(RpcError::method_not_found().with_message(format!(
83            "No handler is implemented for '{}'.",
84            request.method(),
85        )))
86    }
87
88    /// Handles requests to list resource templates.
89    ///
90    /// Default implementation returns method not found error.
91    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
92    async fn handle_list_resource_templates_request(
93        &self,
94        request: ListResourceTemplatesRequest,
95        runtime: &dyn McpServer,
96    ) -> std::result::Result<ListResourceTemplatesResult, RpcError> {
97        runtime.assert_server_request_capabilities(request.method())?;
98        Err(RpcError::method_not_found().with_message(format!(
99            "No handler is implemented for '{}'.",
100            request.method(),
101        )))
102    }
103
104    /// Handles requests to read a specific resource.
105    ///
106    /// Default implementation returns method not found error.
107    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
108    async fn handle_read_resource_request(
109        &self,
110        request: ReadResourceRequest,
111        runtime: &dyn McpServer,
112    ) -> std::result::Result<ReadResourceResult, RpcError> {
113        runtime.assert_server_request_capabilities(request.method())?;
114        Err(RpcError::method_not_found().with_message(format!(
115            "No handler is implemented for '{}'.",
116            request.method(),
117        )))
118    }
119
120    /// Handles subscription requests from clients.
121    ///
122    /// Default implementation returns method not found error.
123    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
124    async fn handle_subscribe_request(
125        &self,
126        request: SubscribeRequest,
127        runtime: &dyn McpServer,
128    ) -> std::result::Result<Result, RpcError> {
129        runtime.assert_server_request_capabilities(request.method())?;
130        Err(RpcError::method_not_found().with_message(format!(
131            "No handler is implemented for '{}'.",
132            request.method(),
133        )))
134    }
135
136    /// Handles unsubscribe requests from clients.
137    ///
138    /// Default implementation returns method not found error.
139    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
140    async fn handle_unsubscribe_request(
141        &self,
142        request: UnsubscribeRequest,
143        runtime: &dyn McpServer,
144    ) -> std::result::Result<Result, RpcError> {
145        runtime.assert_server_request_capabilities(request.method())?;
146        Err(RpcError::method_not_found().with_message(format!(
147            "No handler is implemented for '{}'.",
148            request.method(),
149        )))
150    }
151
152    /// Handles requests to list available prompts.
153    ///
154    /// Default implementation returns method not found error.
155    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
156    async fn handle_list_prompts_request(
157        &self,
158        request: ListPromptsRequest,
159        runtime: &dyn McpServer,
160    ) -> std::result::Result<ListPromptsResult, RpcError> {
161        runtime.assert_server_request_capabilities(request.method())?;
162        Err(RpcError::method_not_found().with_message(format!(
163            "No handler is implemented for '{}'.",
164            request.method(),
165        )))
166    }
167
168    /// Handles requests to get a specific prompt.
169    ///
170    /// Default implementation returns method not found error.
171    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
172    async fn handle_get_prompt_request(
173        &self,
174        request: GetPromptRequest,
175        runtime: &dyn McpServer,
176    ) -> std::result::Result<GetPromptResult, RpcError> {
177        runtime.assert_server_request_capabilities(request.method())?;
178        Err(RpcError::method_not_found().with_message(format!(
179            "No handler is implemented for '{}'.",
180            request.method(),
181        )))
182    }
183
184    /// Handles requests to list available tools.
185    ///
186    /// Default implementation returns method not found error.
187    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
188    async fn handle_list_tools_request(
189        &self,
190        request: ListToolsRequest,
191        runtime: &dyn McpServer,
192    ) -> std::result::Result<ListToolsResult, RpcError> {
193        runtime.assert_server_request_capabilities(request.method())?;
194        Err(RpcError::method_not_found().with_message(format!(
195            "No handler is implemented for '{}'.",
196            request.method(),
197        )))
198    }
199
200    /// Handles requests to call a specific tool.
201    ///
202    /// Default implementation returns an unknown tool error.
203    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
204    async fn handle_call_tool_request(
205        &self,
206        request: CallToolRequest,
207        runtime: &dyn McpServer,
208    ) -> std::result::Result<CallToolResult, CallToolError> {
209        runtime
210            .assert_server_request_capabilities(request.method())
211            .map_err(CallToolError::new)?;
212        Ok(CallToolError::unknown_tool(format!("Unknown tool: {}", request.params.name)).into())
213    }
214
215    /// Handles requests to enable or adjust logging level.
216    ///
217    /// Default implementation returns method not found error.
218    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
219    async fn handle_set_level_request(
220        &self,
221        request: SetLevelRequest,
222        runtime: &dyn McpServer,
223    ) -> std::result::Result<Result, RpcError> {
224        runtime.assert_server_request_capabilities(request.method())?;
225        Err(RpcError::method_not_found().with_message(format!(
226            "No handler is implemented for '{}'.",
227            request.method(),
228        )))
229    }
230
231    /// Handles completion requests from clients.
232    ///
233    /// Default implementation returns method not found error.
234    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
235    async fn handle_complete_request(
236        &self,
237        request: CompleteRequest,
238        runtime: &dyn McpServer,
239    ) -> std::result::Result<CompleteResult, RpcError> {
240        runtime.assert_server_request_capabilities(request.method())?;
241        Err(RpcError::method_not_found().with_message(format!(
242            "No handler is implemented for '{}'.",
243            request.method(),
244        )))
245    }
246
247    /// Handles custom requests not defined in the standard protocol.
248    ///
249    /// Default implementation returns method not found error.
250    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
251    async fn handle_custom_request(
252        &self,
253        request: Value,
254        runtime: &dyn McpServer,
255    ) -> std::result::Result<Value, RpcError> {
256        Err(RpcError::method_not_found()
257            .with_message("No handler is implemented for custom requests.".to_string()))
258    }
259
260    // Notification Handlers
261
262    /// Handles initialized notifications from clients.
263    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
264    async fn handle_initialized_notification(
265        &self,
266        notification: InitializedNotification,
267        runtime: &dyn McpServer,
268    ) -> std::result::Result<(), RpcError> {
269        Ok(())
270    }
271
272    /// Handles cancelled operation notifications.
273    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
274    async fn handle_cancelled_notification(
275        &self,
276        notification: CancelledNotification,
277        runtime: &dyn McpServer,
278    ) -> std::result::Result<(), RpcError> {
279        Ok(())
280    }
281
282    /// Handles progress update notifications.
283    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
284    async fn handle_progress_notification(
285        &self,
286        notification: ProgressNotification,
287        runtime: &dyn McpServer,
288    ) -> std::result::Result<(), RpcError> {
289        Ok(())
290    }
291
292    /// Handles notifications received from the client indicating that the list of roots has changed
293    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
294    async fn handle_roots_list_changed_notification(
295        &self,
296        notification: RootsListChangedNotification,
297        runtime: &dyn McpServer,
298    ) -> std::result::Result<(), RpcError> {
299        Ok(())
300    }
301
302    /// Handles custom notifications not defined in the standard protocol.
303    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
304    async fn handle_custom_notification(
305        &self,
306        notification: Value,
307    ) -> std::result::Result<(), RpcError> {
308        Ok(())
309    }
310
311    // Error Handler
312
313    /// Handles server errors that occur during operation.
314    ///
315    /// # Arguments
316    /// * `error` - The error that occurred
317    /// * `runtime` - Reference to the MCP server runtime
318    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
319    async fn handle_error(
320        &self,
321        error: RpcError,
322        runtime: &dyn McpServer,
323    ) -> std::result::Result<(), RpcError> {
324        Ok(())
325    }
326
327    /// Called when the server has successfully started.
328    ///
329    /// Sends a "Server started successfully" message to stderr.
330    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
331    async fn on_server_started(&self, runtime: &dyn McpServer) {
332        let _ = runtime
333            .stderr_message("Server started successfully".into())
334            .await;
335    }
336}