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