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