rust_mcp_sdk/mcp_handlers/
mcp_server_handler.rs

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