rust_mcp_sdk/mcp_handlers/
mcp_server_handler.rs

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