1#![expect(deprecated)]
3use std::sync::Arc;
4
5use crate::{
6 error::ErrorData as McpError,
7 model::{TaskSupport, *},
8 service::{
9 MaybeSendFuture, NotificationContext, RequestContext, RoleServer, Service, ServiceRole,
10 },
11};
12
13pub mod common;
14pub mod prompt;
15mod resource;
16pub mod router;
17pub mod tool;
18pub mod tool_name_validation;
19pub mod wrapper;
20
21impl<H: ServerHandler> Service<RoleServer> for H {
22 async fn handle_request(
23 &self,
24 request: <RoleServer as ServiceRole>::PeerReq,
25 context: RequestContext<RoleServer>,
26 ) -> Result<<RoleServer as ServiceRole>::Resp, McpError> {
27 let protocol_version = context.protocol_version();
29 let result = match request {
30 ClientRequest::InitializeRequest(request) => self
31 .initialize(request.params, context)
32 .await
33 .map(ServerResult::InitializeResult),
34 ClientRequest::PingRequest(_request) => {
35 self.ping(context).await.map(ServerResult::empty)
36 }
37 ClientRequest::CompleteRequest(request) => self
38 .complete(request.params, context)
39 .await
40 .map(ServerResult::CompleteResult),
41 ClientRequest::SetLevelRequest(request) => self
42 .set_level(request.params, context)
43 .await
44 .map(ServerResult::empty),
45 ClientRequest::GetPromptRequest(request) => self
46 .get_prompt(request.params, context)
47 .await
48 .map(ServerResult::GetPromptResult),
49 ClientRequest::ListPromptsRequest(request) => self
50 .list_prompts(request.params, context)
51 .await
52 .map(ServerResult::ListPromptsResult),
53 ClientRequest::ListResourcesRequest(request) => self
54 .list_resources(request.params, context)
55 .await
56 .map(ServerResult::ListResourcesResult),
57 ClientRequest::ListResourceTemplatesRequest(request) => self
58 .list_resource_templates(request.params, context)
59 .await
60 .map(ServerResult::ListResourceTemplatesResult),
61 ClientRequest::ReadResourceRequest(request) => self
62 .read_resource(request.params, context)
63 .await
64 .map(ServerResult::ReadResourceResult),
65 ClientRequest::SubscribeRequest(request) => self
66 .subscribe(request.params, context)
67 .await
68 .map(ServerResult::empty),
69 ClientRequest::UnsubscribeRequest(request) => self
70 .unsubscribe(request.params, context)
71 .await
72 .map(ServerResult::empty),
73 ClientRequest::CallToolRequest(request) => {
74 let is_task = request.params.task.is_some();
75
76 if let Some(tool) = self.get_tool(&request.params.name) {
78 match (tool.task_support(), is_task) {
79 (TaskSupport::Required, false) => {
82 return Err(McpError::new(
83 ErrorCode::METHOD_NOT_FOUND,
84 "Tool requires task-based invocation",
85 None,
86 ));
87 }
88 (TaskSupport::Forbidden, true) => {
90 return Err(McpError::invalid_params(
91 "Tool does not support task-based invocation",
92 None,
93 ));
94 }
95 _ => {}
96 }
97 }
98
99 if is_task {
100 tracing::info!("Enqueueing task for tool call: {}", request.params.name);
101 self.enqueue_task(request.params, context.clone())
102 .await
103 .map(ServerResult::CreateTaskResult)
104 } else {
105 self.call_tool(request.params, context)
106 .await
107 .map(ServerResult::CallToolResult)
108 }
109 }
110 ClientRequest::ListToolsRequest(request) => self
111 .list_tools(request.params, context)
112 .await
113 .map(ServerResult::ListToolsResult),
114 ClientRequest::CustomRequest(request) => self
115 .on_custom_request(request, context)
116 .await
117 .map(ServerResult::CustomResult),
118 ClientRequest::ListTasksRequest(request) => self
119 .list_tasks(request.params, context)
120 .await
121 .map(ServerResult::ListTasksResult),
122 ClientRequest::GetTaskRequest(request) => self
123 .get_task_info(request.params, context)
124 .await
125 .map(ServerResult::GetTaskResult),
126 ClientRequest::GetTaskPayloadRequest(request) => self
127 .get_task_result(request.params, context)
128 .await
129 .map(ServerResult::GetTaskPayloadResult),
130 ClientRequest::CancelTaskRequest(request) => self
131 .cancel_task(request.params, context)
132 .await
133 .map(ServerResult::CancelTaskResult),
134 };
135 let use_invalid_params =
139 protocol_version.is_some_and(|v| v.as_str() >= ProtocolVersion::V_2026_07_28.as_str());
140 result.map_err(|mut error| {
141 if use_invalid_params && error.code == ErrorCode::RESOURCE_NOT_FOUND {
142 error.code = ErrorCode::INVALID_PARAMS;
143 }
144 error
145 })
146 }
147
148 async fn handle_notification(
149 &self,
150 notification: <RoleServer as ServiceRole>::PeerNot,
151 context: NotificationContext<RoleServer>,
152 ) -> Result<(), McpError> {
153 match notification {
154 ClientNotification::CancelledNotification(notification) => {
155 self.on_cancelled(notification.params, context).await
156 }
157 ClientNotification::ProgressNotification(notification) => {
158 self.on_progress(notification.params, context).await
159 }
160 ClientNotification::InitializedNotification(_notification) => {
161 self.on_initialized(context).await
162 }
163 ClientNotification::RootsListChangedNotification(_notification) => {
164 self.on_roots_list_changed(context).await
165 }
166 ClientNotification::TaskStatusNotification(notification) => {
167 self.on_task_status(notification.params, context).await
168 }
169 ClientNotification::CustomNotification(notification) => {
170 self.on_custom_notification(notification, context).await
171 }
172 };
173 Ok(())
174 }
175
176 fn get_info(&self) -> <RoleServer as ServiceRole>::Info {
177 self.get_info()
178 }
179}
180
181macro_rules! server_handler_methods {
182 () => {
183 fn enqueue_task(
184 &self,
185 _request: CallToolRequestParams,
186 _context: RequestContext<RoleServer>,
187 ) -> impl Future<Output = Result<CreateTaskResult, McpError>> + MaybeSendFuture + '_ {
188 std::future::ready(Err(McpError::internal_error(
189 "Task processing not implemented".to_string(),
190 None,
191 )))
192 }
193 fn ping(
194 &self,
195 context: RequestContext<RoleServer>,
196 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
197 std::future::ready(Ok(()))
198 }
199 fn initialize(
201 &self,
202 request: InitializeRequestParams,
203 context: RequestContext<RoleServer>,
204 ) -> impl Future<Output = Result<InitializeResult, McpError>> + MaybeSendFuture + '_ {
205 context.peer.set_peer_info(request);
206 std::future::ready(Ok(self.get_info()))
207 }
208 fn complete(
209 &self,
210 request: CompleteRequestParams,
211 context: RequestContext<RoleServer>,
212 ) -> impl Future<Output = Result<CompleteResult, McpError>> + MaybeSendFuture + '_ {
213 std::future::ready(Ok(CompleteResult::default()))
214 }
215 fn set_level(
216 &self,
217 request: SetLevelRequestParams,
218 context: RequestContext<RoleServer>,
219 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
220 std::future::ready(Err(McpError::method_not_found::<SetLevelRequestMethod>()))
221 }
222 fn get_prompt(
223 &self,
224 request: GetPromptRequestParams,
225 context: RequestContext<RoleServer>,
226 ) -> impl Future<Output = Result<GetPromptResult, McpError>> + MaybeSendFuture + '_ {
227 std::future::ready(Err(McpError::method_not_found::<GetPromptRequestMethod>()))
228 }
229 fn list_prompts(
230 &self,
231 request: Option<PaginatedRequestParams>,
232 context: RequestContext<RoleServer>,
233 ) -> impl Future<Output = Result<ListPromptsResult, McpError>> + MaybeSendFuture + '_ {
234 std::future::ready(Ok(ListPromptsResult::default()))
235 }
236 fn list_resources(
237 &self,
238 request: Option<PaginatedRequestParams>,
239 context: RequestContext<RoleServer>,
240 ) -> impl Future<Output = Result<ListResourcesResult, McpError>> + MaybeSendFuture + '_ {
241 std::future::ready(Ok(ListResourcesResult::default()))
242 }
243 fn list_resource_templates(
244 &self,
245 request: Option<PaginatedRequestParams>,
246 context: RequestContext<RoleServer>,
247 ) -> impl Future<Output = Result<ListResourceTemplatesResult, McpError>>
248 + MaybeSendFuture
249 + '_ {
250 std::future::ready(Ok(ListResourceTemplatesResult::default()))
251 }
252 fn read_resource(
253 &self,
254 request: ReadResourceRequestParams,
255 context: RequestContext<RoleServer>,
256 ) -> impl Future<Output = Result<ReadResourceResult, McpError>> + MaybeSendFuture + '_ {
257 std::future::ready(Err(
258 McpError::method_not_found::<ReadResourceRequestMethod>(),
259 ))
260 }
261 fn subscribe(
262 &self,
263 request: SubscribeRequestParams,
264 context: RequestContext<RoleServer>,
265 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
266 std::future::ready(Err(McpError::method_not_found::<SubscribeRequestMethod>()))
267 }
268 fn unsubscribe(
269 &self,
270 request: UnsubscribeRequestParams,
271 context: RequestContext<RoleServer>,
272 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
273 std::future::ready(Err(
274 McpError::method_not_found::<UnsubscribeRequestMethod>(),
275 ))
276 }
277 fn call_tool(
306 &self,
307 request: CallToolRequestParams,
308 context: RequestContext<RoleServer>,
309 ) -> impl Future<Output = Result<CallToolResult, McpError>> + MaybeSendFuture + '_ {
310 std::future::ready(Err(McpError::method_not_found::<CallToolRequestMethod>()))
311 }
312 fn list_tools(
313 &self,
314 request: Option<PaginatedRequestParams>,
315 context: RequestContext<RoleServer>,
316 ) -> impl Future<Output = Result<ListToolsResult, McpError>> + MaybeSendFuture + '_ {
317 std::future::ready(Ok(ListToolsResult::default()))
318 }
319 fn get_tool(&self, _name: &str) -> Option<Tool> {
324 None
325 }
326 fn on_custom_request(
327 &self,
328 request: CustomRequest,
329 context: RequestContext<RoleServer>,
330 ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
331 let CustomRequest { method, .. } = request;
332 let _ = context;
333 std::future::ready(Err(McpError::new(
334 ErrorCode::METHOD_NOT_FOUND,
335 method,
336 None,
337 )))
338 }
339
340 fn on_cancelled(
341 &self,
342 notification: CancelledNotificationParam,
343 context: NotificationContext<RoleServer>,
344 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
345 std::future::ready(())
346 }
347 fn on_progress(
348 &self,
349 notification: ProgressNotificationParam,
350 context: NotificationContext<RoleServer>,
351 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
352 std::future::ready(())
353 }
354 fn on_initialized(
355 &self,
356 context: NotificationContext<RoleServer>,
357 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
358 tracing::info!("client initialized");
359 std::future::ready(())
360 }
361 fn on_roots_list_changed(
362 &self,
363 context: NotificationContext<RoleServer>,
364 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
365 std::future::ready(())
366 }
367 fn on_task_status(
368 &self,
369 params: TaskStatusNotificationParam,
370 context: NotificationContext<RoleServer>,
371 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
372 std::future::ready(())
373 }
374 fn on_custom_notification(
375 &self,
376 notification: CustomNotification,
377 context: NotificationContext<RoleServer>,
378 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
379 let _ = (notification, context);
380 std::future::ready(())
381 }
382
383 fn get_info(&self) -> ServerInfo {
384 ServerInfo::default()
385 }
386
387 fn list_tasks(
388 &self,
389 request: Option<PaginatedRequestParams>,
390 context: RequestContext<RoleServer>,
391 ) -> impl Future<Output = Result<ListTasksResult, McpError>> + MaybeSendFuture + '_ {
392 std::future::ready(Err(McpError::method_not_found::<ListTasksMethod>()))
393 }
394
395 fn get_task_info(
396 &self,
397 request: GetTaskParams,
398 context: RequestContext<RoleServer>,
399 ) -> impl Future<Output = Result<GetTaskResult, McpError>> + MaybeSendFuture + '_ {
400 let _ = (request, context);
401 std::future::ready(Err(McpError::method_not_found::<GetTaskMethod>()))
402 }
403
404 fn get_task_result(
405 &self,
406 request: GetTaskPayloadParams,
407 context: RequestContext<RoleServer>,
408 ) -> impl Future<Output = Result<GetTaskPayloadResult, McpError>> + MaybeSendFuture + '_ {
409 let _ = (request, context);
410 std::future::ready(Err(McpError::method_not_found::<GetTaskPayloadMethod>()))
411 }
412
413 fn cancel_task(
414 &self,
415 request: CancelTaskParams,
416 context: RequestContext<RoleServer>,
417 ) -> impl Future<Output = Result<CancelTaskResult, McpError>> + MaybeSendFuture + '_ {
418 let _ = (request, context);
419 std::future::ready(Err(McpError::method_not_found::<CancelTaskMethod>()))
420 }
421 };
422}
423
424#[allow(unused_variables)]
425#[cfg(not(feature = "local"))]
426pub trait ServerHandler: Sized + Send + Sync + 'static {
427 server_handler_methods!();
428}
429
430#[allow(unused_variables)]
431#[cfg(feature = "local")]
432pub trait ServerHandler: Sized + 'static {
433 server_handler_methods!();
434}
435
436macro_rules! impl_server_handler_for_wrapper {
437 ($wrapper:ident) => {
438 impl<T: ServerHandler> ServerHandler for $wrapper<T> {
439 fn enqueue_task(
440 &self,
441 request: CallToolRequestParams,
442 context: RequestContext<RoleServer>,
443 ) -> impl Future<Output = Result<CreateTaskResult, McpError>> + MaybeSendFuture + '_ {
444 (**self).enqueue_task(request, context)
445 }
446
447 fn ping(
448 &self,
449 context: RequestContext<RoleServer>,
450 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
451 (**self).ping(context)
452 }
453
454 fn initialize(
455 &self,
456 request: InitializeRequestParams,
457 context: RequestContext<RoleServer>,
458 ) -> impl Future<Output = Result<InitializeResult, McpError>> + MaybeSendFuture + '_ {
459 (**self).initialize(request, context)
460 }
461
462 fn complete(
463 &self,
464 request: CompleteRequestParams,
465 context: RequestContext<RoleServer>,
466 ) -> impl Future<Output = Result<CompleteResult, McpError>> + MaybeSendFuture + '_ {
467 (**self).complete(request, context)
468 }
469
470 fn set_level(
471 &self,
472 request: SetLevelRequestParams,
473 context: RequestContext<RoleServer>,
474 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
475 (**self).set_level(request, context)
476 }
477
478 fn get_prompt(
479 &self,
480 request: GetPromptRequestParams,
481 context: RequestContext<RoleServer>,
482 ) -> impl Future<Output = Result<GetPromptResult, McpError>> + MaybeSendFuture + '_ {
483 (**self).get_prompt(request, context)
484 }
485
486 fn list_prompts(
487 &self,
488 request: Option<PaginatedRequestParams>,
489 context: RequestContext<RoleServer>,
490 ) -> impl Future<Output = Result<ListPromptsResult, McpError>> + MaybeSendFuture + '_ {
491 (**self).list_prompts(request, context)
492 }
493
494 fn list_resources(
495 &self,
496 request: Option<PaginatedRequestParams>,
497 context: RequestContext<RoleServer>,
498 ) -> impl Future<Output = Result<ListResourcesResult, McpError>> + MaybeSendFuture + '_ {
499 (**self).list_resources(request, context)
500 }
501
502 fn list_resource_templates(
503 &self,
504 request: Option<PaginatedRequestParams>,
505 context: RequestContext<RoleServer>,
506 ) -> impl Future<Output = Result<ListResourceTemplatesResult, McpError>> + MaybeSendFuture + '_
507 {
508 (**self).list_resource_templates(request, context)
509 }
510
511 fn read_resource(
512 &self,
513 request: ReadResourceRequestParams,
514 context: RequestContext<RoleServer>,
515 ) -> impl Future<Output = Result<ReadResourceResult, McpError>> + MaybeSendFuture + '_ {
516 (**self).read_resource(request, context)
517 }
518
519 fn subscribe(
520 &self,
521 request: SubscribeRequestParams,
522 context: RequestContext<RoleServer>,
523 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
524 (**self).subscribe(request, context)
525 }
526
527 fn unsubscribe(
528 &self,
529 request: UnsubscribeRequestParams,
530 context: RequestContext<RoleServer>,
531 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
532 (**self).unsubscribe(request, context)
533 }
534
535 fn call_tool(
536 &self,
537 request: CallToolRequestParams,
538 context: RequestContext<RoleServer>,
539 ) -> impl Future<Output = Result<CallToolResult, McpError>> + MaybeSendFuture + '_ {
540 (**self).call_tool(request, context)
541 }
542
543 fn list_tools(
544 &self,
545 request: Option<PaginatedRequestParams>,
546 context: RequestContext<RoleServer>,
547 ) -> impl Future<Output = Result<ListToolsResult, McpError>> + MaybeSendFuture + '_ {
548 (**self).list_tools(request, context)
549 }
550
551 fn get_tool(&self, name: &str) -> Option<Tool> {
552 (**self).get_tool(name)
553 }
554
555 fn on_custom_request(
556 &self,
557 request: CustomRequest,
558 context: RequestContext<RoleServer>,
559 ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
560 (**self).on_custom_request(request, context)
561 }
562
563 fn on_cancelled(
564 &self,
565 notification: CancelledNotificationParam,
566 context: NotificationContext<RoleServer>,
567 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
568 (**self).on_cancelled(notification, context)
569 }
570
571 fn on_progress(
572 &self,
573 notification: ProgressNotificationParam,
574 context: NotificationContext<RoleServer>,
575 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
576 (**self).on_progress(notification, context)
577 }
578
579 fn on_initialized(
580 &self,
581 context: NotificationContext<RoleServer>,
582 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
583 (**self).on_initialized(context)
584 }
585
586 fn on_roots_list_changed(
587 &self,
588 context: NotificationContext<RoleServer>,
589 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
590 (**self).on_roots_list_changed(context)
591 }
592
593 fn on_task_status(
594 &self,
595 params: TaskStatusNotificationParam,
596 context: NotificationContext<RoleServer>,
597 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
598 (**self).on_task_status(params, context)
599 }
600
601 fn on_custom_notification(
602 &self,
603 notification: CustomNotification,
604 context: NotificationContext<RoleServer>,
605 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
606 (**self).on_custom_notification(notification, context)
607 }
608
609 fn get_info(&self) -> ServerInfo {
610 (**self).get_info()
611 }
612
613 fn list_tasks(
614 &self,
615 request: Option<PaginatedRequestParams>,
616 context: RequestContext<RoleServer>,
617 ) -> impl Future<Output = Result<ListTasksResult, McpError>> + MaybeSendFuture + '_ {
618 (**self).list_tasks(request, context)
619 }
620
621 fn get_task_info(
622 &self,
623 request: GetTaskParams,
624 context: RequestContext<RoleServer>,
625 ) -> impl Future<Output = Result<GetTaskResult, McpError>> + MaybeSendFuture + '_ {
626 (**self).get_task_info(request, context)
627 }
628
629 fn get_task_result(
630 &self,
631 request: GetTaskPayloadParams,
632 context: RequestContext<RoleServer>,
633 ) -> impl Future<Output = Result<GetTaskPayloadResult, McpError>> + MaybeSendFuture + '_ {
634 (**self).get_task_result(request, context)
635 }
636
637 fn cancel_task(
638 &self,
639 request: CancelTaskParams,
640 context: RequestContext<RoleServer>,
641 ) -> impl Future<Output = Result<CancelTaskResult, McpError>> + MaybeSendFuture + '_ {
642 (**self).cancel_task(request, context)
643 }
644 }
645 };
646}
647
648impl_server_handler_for_wrapper!(Box);
649impl_server_handler_for_wrapper!(Arc);