1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
use crate::{
mcp_server::server_runtime::ServerRuntimeInternalHandler,
mcp_traits::{McpServerHandler, ToMcpServerHandler},
schema::{
schema_utils::{CallToolError, CustomNotification, CustomRequest},
*,
},
task_store::ServerTaskCreator,
};
use crate::{mcp_traits::McpServer, utils::enforce_compatible_protocol_version};
use async_trait::async_trait;
use std::sync::Arc;
/// The `ServerHandler` trait defines how a server handles Model Context Protocol (MCP) operations.
/// It provides default implementations for request , notification and error handlers, and must be extended or
/// overridden by developers to customize server behavior.
#[allow(unused)]
#[async_trait]
pub trait ServerHandler: Send + Sync + 'static {
/// Invoked when the server finishes initialization and receives an `initialized_notification` from the client.
///
/// The `runtime` parameter provides access to the server's runtime environment, allowing
/// interaction with the server's capabilities.
/// The default implementation does nothing.
async fn on_initialized(&self, runtime: Arc<dyn McpServer>) {}
/// Handles the InitializeRequest from a client.
///
/// # Arguments
/// * `initialize_request` - The initialization request containing client parameters
/// * `runtime` - Reference to the MCP server runtime
///
/// # Returns
/// Returns the server info as InitializeResult on success or a JSON-RPC error on failure
/// Do not override this unless the standard initialization process doesn't work for you or you need to modify it.
async fn handle_initialize_request(
&self,
params: InitializeRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<InitializeResult, RpcError> {
let mut server_info = runtime.server_info().to_owned();
// Provide compatibility for clients using older MCP protocol versions.
if let Some(updated_protocol_version) = enforce_compatible_protocol_version(
¶ms.protocol_version,
&server_info.protocol_version,
)
.map_err(|err| {
tracing::error!(
"Incompatible protocol version : client: {} server: {}",
¶ms.protocol_version,
&server_info.protocol_version
);
RpcError::internal_error().with_message(err.to_string())
})? {
server_info.protocol_version = updated_protocol_version;
}
runtime
.set_client_details(params)
.await
.map_err(|err| RpcError::internal_error().with_message(format!("{err}")))?;
Ok(server_info)
}
/// Handles ping requests from clients.
///
/// # Returns
/// By default, it returns an empty result structure
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_ping_request(
&self,
_params: Option<RequestParams>,
_runtime: Arc<dyn McpServer>,
) -> std::result::Result<Result, RpcError> {
Ok(Result::default())
}
/// Handles requests to list available resources.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_list_resources_request(
&self,
params: Option<PaginatedRequestParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<ListResourcesResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&ListResourcesRequest::method_value(),
)))
}
/// Handles requests to list resource templates.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_list_resource_templates_request(
&self,
params: Option<PaginatedRequestParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<ListResourceTemplatesResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&ListResourceTemplatesRequest::method_value(),
)))
}
/// Handles requests to read a specific resource.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_read_resource_request(
&self,
params: ReadResourceRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<ReadResourceResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&ReadResourceRequest::method_value(),
)))
}
/// Handles subscription requests from clients.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_subscribe_request(
&self,
params: SubscribeRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<Result, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&SubscribeRequest::method_value(),
)))
}
/// Handles unsubscribe requests from clients.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_unsubscribe_request(
&self,
params: UnsubscribeRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<Result, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&UnsubscribeRequest::method_value(),
)))
}
/// Handles requests to list available prompts.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_list_prompts_request(
&self,
params: Option<PaginatedRequestParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<ListPromptsResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&ListPromptsRequest::method_value(),
)))
}
/// Handles requests to get a specific prompt.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_get_prompt_request(
&self,
params: GetPromptRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<GetPromptResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&GetPromptRequest::method_value(),
)))
}
/// Handles requests to list available tools.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_list_tools_request(
&self,
params: Option<PaginatedRequestParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<ListToolsResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&ListToolsRequest::method_value(),
)))
}
/// Handles requests to call a task-augmented tool.
/// you need to returns a CreateTaskResult containing task data.
/// The actual operation result becomes available later
/// through tasks/result after the task completes.
async fn handle_task_augmented_tool_call(
&self,
params: CallToolRequestParams,
task_creator: ServerTaskCreator,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<CreateTaskResult, CallToolError> {
if !runtime.capabilities().can_run_task_augmented_tools() {
return Err(CallToolError::unsupported_task_augmented_tool_call());
}
Err(CallToolError::from_message(
"No handler is implemented for 'task augmented tool call'.",
))
}
/// Handles requests to call a specific tool.
///
/// Default implementation returns an unknown tool error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_call_tool_request(
&self,
params: CallToolRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<CallToolResult, CallToolError> {
Ok(CallToolError::unknown_tool(format!("Unknown tool: {}", params.name)).into())
}
/// Handles requests to enable or adjust logging level.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_set_level_request(
&self,
params: SetLevelRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<Result, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&SetLevelRequest::method_value(),
)))
}
/// Handles completion requests from clients.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_complete_request(
&self,
params: CompleteRequestParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<CompleteResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&CompleteRequest::method_value(),
)))
}
/// Handles a request to retrieve the state of a task.
async fn handle_get_task_request(
&self,
params: GetTaskParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<GetTaskResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&GetTaskRequest::method_value(),
)))
}
/// Handles a request to retrieve the result of a completed task.
async fn handle_get_task_payload_request(
&self,
params: GetTaskPayloadParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<GetTaskPayloadResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&GetTaskPayloadRequest::method_value(),
)))
}
/// Handles a request to cancel a task.
async fn handle_cancel_task_request(
&self,
params: CancelTaskParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<CancelTaskResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&CancelTaskRequest::method_value(),
)))
}
/// Handles a request to retrieve a list of tasks.
async fn handle_list_task_request(
&self,
params: Option<PaginatedRequestParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<ListTasksResult, RpcError> {
Err(RpcError::method_not_found().with_message(format!(
"No handler is implemented for '{}'.",
&ListTasksRequest::method_value(),
)))
}
/// Handles custom requests not defined in the standard protocol.
///
/// Default implementation returns method not found error.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_custom_request(
&self,
request: CustomRequest,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<GenericResult, RpcError> {
Err(RpcError::method_not_found()
.with_message("No handler is implemented for custom requests.".to_string()))
}
// Notification Handlers
/// Handles initialized notifications from clients.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_initialized_notification(
&self,
params: Option<NotificationParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<(), RpcError> {
Ok(())
}
/// Handles cancelled operation notifications.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_cancelled_notification(
&self,
params: CancelledNotificationParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<(), RpcError> {
Ok(())
}
/// Handles progress update notifications.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_progress_notification(
&self,
params: ProgressNotificationParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<(), RpcError> {
Ok(())
}
/// Handles notifications received from the client indicating that the list of roots has changed
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_roots_list_changed_notification(
&self,
params: Option<NotificationParams>,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<(), RpcError> {
Ok(())
}
///handles a notification from the receiver to the requestor, informing them that a task's status has changed.
async fn handle_task_status_notification(
&self,
params: TaskStatusNotificationParams,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<(), RpcError> {
Ok(())
}
/// Handles custom notifications not defined in the standard protocol.
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_custom_notification(
&self,
notification: CustomNotification,
) -> std::result::Result<(), RpcError> {
Ok(())
}
// Error Handler
/// Handles server errors that occur during operation.
///
/// # Arguments
/// * `error` - The error that occurred
/// * `runtime` - Reference to the MCP server runtime
/// Customize this function in your specific handler to implement behavior tailored to your MCP server's capabilities and requirements.
async fn handle_error(
&self,
error: &RpcError,
runtime: Arc<dyn McpServer>,
) -> std::result::Result<(), RpcError> {
Ok(())
}
}
impl<T: ServerHandler + 'static> ToMcpServerHandler for T {
fn to_mcp_server_handler(self) -> Arc<dyn McpServerHandler + 'static> {
Arc::new(ServerRuntimeInternalHandler::new(Box::new(self)))
}
}