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}