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