Skip to main content

rust_mcp_sdk/mcp_handlers/
mcp_server_handler.rs

1use crate::{
2    mcp_server::server_runtime::ServerRuntimeInternalHandler,
3    mcp_traits::{McpServerHandler, ToMcpServerHandler},
4    schema::{
5        schema_utils::{CallToolError, CustomNotification, CustomRequest},
6        *,
7    },
8    task_store::ServerTaskCreator,
9};
10use crate::{mcp_traits::McpServer, utils::enforce_compatible_protocol_version};
11use async_trait::async_trait;
12use std::sync::Arc;
13
14/// The `ServerHandler` trait defines how a server handles Model Context Protocol (MCP) operations.
15/// It provides default implementations for request , notification and error handlers, and must be extended or
16/// overridden by developers to customize server behavior.
17#[allow(unused)]
18#[async_trait]
19pub trait ServerHandler: Send + Sync + 'static {
20    /// Invoked when the server finishes initialization and receives an `initialized_notification` from the client.
21    ///
22    /// The `runtime` parameter provides access to the server's runtime environment, allowing
23    /// interaction with the server's capabilities.
24    /// The default implementation does nothing.
25    async fn on_initialized(&self, runtime: Arc<dyn McpServer>) {}
26
27    /// Handles the InitializeRequest from a client.
28    ///
29    /// # Arguments
30    /// * `initialize_request` - The initialization request containing client parameters
31    /// * `runtime` - Reference to the MCP server runtime
32    ///
33    /// # Returns
34    /// Returns the server info as InitializeResult on success or a JSON-RPC error on failure
35    /// Do not override this unless the standard initialization process doesn't work for you or you need to modify it.
36    async fn handle_initialize_request(
37        &self,
38        params: InitializeRequestParams,
39        runtime: Arc<dyn McpServer>,
40    ) -> std::result::Result<InitializeResult, RpcError> {
41        let mut server_info = runtime.server_info().to_owned();
42        // Provide compatibility for clients using older MCP protocol versions.
43
44        if let Some(updated_protocol_version) = enforce_compatible_protocol_version(
45            &params.protocol_version,
46            &server_info.protocol_version,
47        )
48        .map_err(|err| {
49            tracing::error!(
50                "Incompatible protocol version : client: {} server: {}",
51                &params.protocol_version,
52                &server_info.protocol_version
53            );
54            RpcError::internal_error().with_message(err.to_string())
55        })? {
56            server_info.protocol_version = updated_protocol_version;
57        }
58
59        runtime
60            .set_client_details(params)
61            .await
62            .map_err(|err| RpcError::internal_error().with_message(format!("{err}")))?;
63
64        Ok(server_info)
65    }
66
67    /// Handles ping requests from clients.
68    ///
69    /// # Returns
70    /// By default, it returns an empty result structure
71    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
72    async fn handle_ping_request(
73        &self,
74        _params: Option<RequestParams>,
75        _runtime: Arc<dyn McpServer>,
76    ) -> std::result::Result<Result, RpcError> {
77        Ok(Result::default())
78    }
79
80    /// Handles requests to list available resources.
81    ///
82    /// Default implementation returns method not found error.
83    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
84    async fn handle_list_resources_request(
85        &self,
86        params: Option<PaginatedRequestParams>,
87        runtime: Arc<dyn McpServer>,
88    ) -> std::result::Result<ListResourcesResult, RpcError> {
89        Err(RpcError::method_not_found().with_message(format!(
90            "No handler is implemented for '{}'.",
91            &ListResourcesRequest::method_value(),
92        )))
93    }
94
95    /// Handles requests to list resource templates.
96    ///
97    /// Default implementation returns method not found error.
98    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
99    async fn handle_list_resource_templates_request(
100        &self,
101        params: Option<PaginatedRequestParams>,
102        runtime: Arc<dyn McpServer>,
103    ) -> std::result::Result<ListResourceTemplatesResult, RpcError> {
104        Err(RpcError::method_not_found().with_message(format!(
105            "No handler is implemented for '{}'.",
106            &ListResourceTemplatesRequest::method_value(),
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        params: ReadResourceRequestParams,
117        runtime: Arc<dyn McpServer>,
118    ) -> std::result::Result<ReadResourceResult, RpcError> {
119        Err(RpcError::method_not_found().with_message(format!(
120            "No handler is implemented for '{}'.",
121            &ReadResourceRequest::method_value(),
122        )))
123    }
124
125    /// Handles subscription requests from clients.
126    ///
127    /// Default implementation returns method not found error.
128    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
129    async fn handle_subscribe_request(
130        &self,
131        params: SubscribeRequestParams,
132        runtime: Arc<dyn McpServer>,
133    ) -> std::result::Result<Result, RpcError> {
134        Err(RpcError::method_not_found().with_message(format!(
135            "No handler is implemented for '{}'.",
136            &SubscribeRequest::method_value(),
137        )))
138    }
139
140    /// Handles unsubscribe requests from clients.
141    ///
142    /// Default implementation returns method not found error.
143    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
144    async fn handle_unsubscribe_request(
145        &self,
146        params: UnsubscribeRequestParams,
147        runtime: Arc<dyn McpServer>,
148    ) -> std::result::Result<Result, RpcError> {
149        Err(RpcError::method_not_found().with_message(format!(
150            "No handler is implemented for '{}'.",
151            &UnsubscribeRequest::method_value(),
152        )))
153    }
154
155    /// Handles requests to list available prompts.
156    ///
157    /// Default implementation returns method not found error.
158    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
159    async fn handle_list_prompts_request(
160        &self,
161        params: Option<PaginatedRequestParams>,
162        runtime: Arc<dyn McpServer>,
163    ) -> std::result::Result<ListPromptsResult, RpcError> {
164        Err(RpcError::method_not_found().with_message(format!(
165            "No handler is implemented for '{}'.",
166            &ListPromptsRequest::method_value(),
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        params: GetPromptRequestParams,
177        runtime: Arc<dyn McpServer>,
178    ) -> std::result::Result<GetPromptResult, RpcError> {
179        Err(RpcError::method_not_found().with_message(format!(
180            "No handler is implemented for '{}'.",
181            &GetPromptRequest::method_value(),
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        params: Option<PaginatedRequestParams>,
192        runtime: Arc<dyn McpServer>,
193    ) -> std::result::Result<ListToolsResult, RpcError> {
194        Err(RpcError::method_not_found().with_message(format!(
195            "No handler is implemented for '{}'.",
196            &ListToolsRequest::method_value(),
197        )))
198    }
199
200    /// Handles requests to call a task-augmented tool.
201    /// you need to returns a CreateTaskResult containing task data.
202    /// The actual operation result becomes available later
203    /// through tasks/result after the task completes.
204    async fn handle_task_augmented_tool_call(
205        &self,
206        params: CallToolRequestParams,
207        task_creator: ServerTaskCreator,
208        runtime: Arc<dyn McpServer>,
209    ) -> std::result::Result<CreateTaskResult, CallToolError> {
210        if !runtime.capabilities().can_run_task_augmented_tools() {
211            return Err(CallToolError::unsupported_task_augmented_tool_call());
212        }
213        Err(CallToolError::from_message(
214            "No handler is implemented for 'task augmented tool call'.",
215        ))
216    }
217
218    /// Handles requests to call a specific tool.
219    ///
220    /// Default implementation returns an unknown tool error.
221    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
222    async fn handle_call_tool_request(
223        &self,
224        params: CallToolRequestParams,
225        runtime: Arc<dyn McpServer>,
226    ) -> std::result::Result<CallToolResult, CallToolError> {
227        Ok(CallToolError::unknown_tool(format!("Unknown tool: {}", params.name)).into())
228    }
229
230    /// Handles requests to enable or adjust logging level.
231    ///
232    /// Default implementation returns method not found error.
233    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
234    async fn handle_set_level_request(
235        &self,
236        params: SetLevelRequestParams,
237        runtime: Arc<dyn McpServer>,
238    ) -> std::result::Result<Result, RpcError> {
239        Err(RpcError::method_not_found().with_message(format!(
240            "No handler is implemented for '{}'.",
241            &SetLevelRequest::method_value(),
242        )))
243    }
244
245    /// Handles completion requests from clients.
246    ///
247    /// Default implementation returns method not found error.
248    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
249    async fn handle_complete_request(
250        &self,
251        params: CompleteRequestParams,
252        runtime: Arc<dyn McpServer>,
253    ) -> std::result::Result<CompleteResult, RpcError> {
254        Err(RpcError::method_not_found().with_message(format!(
255            "No handler is implemented for '{}'.",
256            &CompleteRequest::method_value(),
257        )))
258    }
259
260    /// Handles a request to retrieve the state of a task.
261    async fn handle_get_task_request(
262        &self,
263        params: GetTaskParams,
264        runtime: Arc<dyn McpServer>,
265    ) -> std::result::Result<GetTaskResult, RpcError> {
266        Err(RpcError::method_not_found().with_message(format!(
267            "No handler is implemented for '{}'.",
268            &GetTaskRequest::method_value(),
269        )))
270    }
271
272    /// Handles a request to retrieve the result of a completed task.
273    async fn handle_get_task_payload_request(
274        &self,
275        params: GetTaskPayloadParams,
276        runtime: Arc<dyn McpServer>,
277    ) -> std::result::Result<GetTaskPayloadResult, RpcError> {
278        Err(RpcError::method_not_found().with_message(format!(
279            "No handler is implemented for '{}'.",
280            &GetTaskPayloadRequest::method_value(),
281        )))
282    }
283
284    /// Handles a request to cancel a task.
285    async fn handle_cancel_task_request(
286        &self,
287        params: CancelTaskParams,
288        runtime: Arc<dyn McpServer>,
289    ) -> std::result::Result<CancelTaskResult, RpcError> {
290        Err(RpcError::method_not_found().with_message(format!(
291            "No handler is implemented for '{}'.",
292            &CancelTaskRequest::method_value(),
293        )))
294    }
295
296    /// Handles a request to retrieve a list of tasks.
297    async fn handle_list_task_request(
298        &self,
299        params: Option<PaginatedRequestParams>,
300        runtime: Arc<dyn McpServer>,
301    ) -> std::result::Result<ListTasksResult, RpcError> {
302        Err(RpcError::method_not_found().with_message(format!(
303            "No handler is implemented for '{}'.",
304            &ListTasksRequest::method_value(),
305        )))
306    }
307
308    /// Handles custom requests not defined in the standard protocol.
309    ///
310    /// Default implementation returns method not found error.
311    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
312    async fn handle_custom_request(
313        &self,
314        request: CustomRequest,
315        runtime: Arc<dyn McpServer>,
316    ) -> std::result::Result<GenericResult, RpcError> {
317        Err(RpcError::method_not_found()
318            .with_message("No handler is implemented for custom requests.".to_string()))
319    }
320
321    // Notification Handlers
322
323    /// Handles initialized notifications from clients.
324    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
325    async fn handle_initialized_notification(
326        &self,
327        params: Option<NotificationParams>,
328        runtime: Arc<dyn McpServer>,
329    ) -> std::result::Result<(), RpcError> {
330        Ok(())
331    }
332
333    /// Handles cancelled operation notifications.
334    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
335    async fn handle_cancelled_notification(
336        &self,
337        params: CancelledNotificationParams,
338        runtime: Arc<dyn McpServer>,
339    ) -> std::result::Result<(), RpcError> {
340        Ok(())
341    }
342
343    /// Handles progress update notifications.
344    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
345    async fn handle_progress_notification(
346        &self,
347        params: ProgressNotificationParams,
348        runtime: Arc<dyn McpServer>,
349    ) -> std::result::Result<(), RpcError> {
350        Ok(())
351    }
352
353    /// Handles notifications received from the client indicating that the list of roots has changed
354    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
355    async fn handle_roots_list_changed_notification(
356        &self,
357        params: Option<NotificationParams>,
358        runtime: Arc<dyn McpServer>,
359    ) -> std::result::Result<(), RpcError> {
360        Ok(())
361    }
362
363    ///handles a notification from the receiver to the requestor, informing them that a task's status has changed.
364    async fn handle_task_status_notification(
365        &self,
366        params: TaskStatusNotificationParams,
367        runtime: Arc<dyn McpServer>,
368    ) -> std::result::Result<(), RpcError> {
369        Ok(())
370    }
371
372    /// Handles custom notifications not defined in the standard protocol.
373    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
374    async fn handle_custom_notification(
375        &self,
376        notification: CustomNotification,
377    ) -> std::result::Result<(), RpcError> {
378        Ok(())
379    }
380
381    // Error Handler
382
383    /// Handles server errors that occur during operation.
384    ///
385    /// # Arguments
386    /// * `error` - The error that occurred
387    /// * `runtime` - Reference to the MCP server runtime
388    /// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
389    async fn handle_error(
390        &self,
391        error: &RpcError,
392        runtime: Arc<dyn McpServer>,
393    ) -> std::result::Result<(), RpcError> {
394        Ok(())
395    }
396}
397
398impl<T: ServerHandler + 'static> ToMcpServerHandler for T {
399    fn to_mcp_server_handler(self) -> Arc<dyn McpServerHandler + 'static> {
400        Arc::new(ServerRuntimeInternalHandler::new(Box::new(self)))
401    }
402}