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