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