Skip to main content

rmcp/handler/
server.rs

1// Sampling/Roots/Logging are SEP-2577-deprecated; internal references are expected.
2#![expect(deprecated)]
3use std::{borrow::Cow, sync::Arc};
4
5use crate::{
6    error::ErrorData as McpError,
7    model::*,
8    service::{
9        MaybeSendFuture, NotificationContext, RequestContext, RoleServer, Service, ServiceRole,
10        SubscriptionContext, negotiate_protocol_version, uses_legacy_lifecycle,
11    },
12};
13
14pub mod common;
15pub mod prompt;
16mod resource;
17pub mod router;
18pub mod tool;
19pub mod tool_name_validation;
20pub mod wrapper;
21
22/// SEP-2663: gate `tasks/*` methods on the client's declared tasks-extension
23/// capability.
24///
25/// - If the server does not advertise the tasks extension, the methods are
26///   simply unimplemented: `-32601` Method not found.
27/// - If the server advertises it but the client did not declare it (either in
28///   the request's `_meta` per-request capabilities or, for session-mode
29///   peers, at `initialize` time), the spec requires `-32021` Missing
30///   Required Client Capability with the required capability in `data`.
31fn validate_tasks_capability<M: ConstString, H: ServerHandler>(
32    handler: &H,
33    context: &RequestContext<RoleServer>,
34) -> Result<(), McpError> {
35    if !handler.get_info().capabilities.supports_tasks() {
36        return Err(McpError::method_not_found::<M>());
37    }
38    let client_declared = context
39        .client_capabilities()
40        .is_some_and(|caps| caps.supports_tasks());
41    if client_declared {
42        Ok(())
43    } else {
44        Err(McpError::missing_required_client_capability(
45            ClientCapabilities::builder().enable_tasks().build(),
46        ))
47    }
48}
49
50impl<H: ServerHandler> Service<RoleServer> for H {
51    async fn handle_request(
52        &self,
53        request: <RoleServer as ServiceRole>::PeerReq,
54        context: RequestContext<RoleServer>,
55    ) -> Result<<RoleServer as ServiceRole>::Resp, McpError> {
56        // `context` is moved into the dispatch below, so read the negotiated version first.
57        let protocol_version = context.protocol_version();
58        // ISO `YYYY-MM-DD` versions compare lexically the same as chronologically.
59        let is_2026_07_28_or_later = protocol_version
60            .as_ref()
61            .is_some_and(|v| v.as_str() >= ProtocolVersion::V_2026_07_28.as_str());
62        let requested_version = context.meta.protocol_version();
63        let uses_inline_negotiation = !matches!(&request, ClientRequest::InitializeRequest(_));
64        if uses_inline_negotiation && let Some(requested_version) = requested_version.as_ref() {
65            let supported_versions = self.supported_protocol_versions();
66            if !supported_versions.contains(requested_version) {
67                return Err(McpError::unsupported_protocol_version(
68                    requested_version.clone(),
69                    &supported_versions,
70                ));
71            }
72        }
73        // Self-contained metadata is required only when the request itself uses
74        // the inline lifecycle: a discover opener, a session that started without
75        // `initialize`, or a request that declares 2026-07-28+ in its own _meta.
76        // Sessions that negotiated via `initialize` (or `serve_directly`) keep the
77        // session model and may omit per-request metadata.
78        let requires_request_metadata = uses_inline_negotiation
79            && (matches!(&request, ClientRequest::DiscoverRequest(_))
80                || context.peer.request_metadata_required()
81                || requested_version.as_ref().is_some_and(|version| {
82                    version.as_str() >= ProtocolVersion::V_2026_07_28.as_str()
83                }));
84        if requires_request_metadata {
85            // Inline lifecycle requests are defined by the 2026-07-28 protocol.
86            // Validate that lifecycle contract even when a request selects an
87            // older application protocol version.
88            let missing = context
89                .meta
90                .missing_required_keys(&ProtocolVersion::V_2026_07_28);
91            if !missing.is_empty() {
92                return Err(McpError::invalid_params(
93                    format!(
94                        "request _meta is missing or has malformed required fields: {}",
95                        missing.join(", ")
96                    ),
97                    None,
98                ));
99            }
100        }
101        let legacy_request =
102            uses_legacy_lifecycle(protocol_version.as_ref(), requires_request_metadata);
103        let result = match request {
104            ClientRequest::InitializeRequest(request) => self
105                .initialize(request.params, context)
106                .await
107                .map(ServerResult::InitializeResult),
108            ClientRequest::DiscoverRequest(_request) => self
109                .discover(context)
110                .await
111                .map(ServerResult::DiscoverResult),
112            ClientRequest::PingRequest(_request) => {
113                if !legacy_request {
114                    Err(McpError::method_not_found::<PingRequestMethod>())
115                } else {
116                    self.ping(context).await.map(ServerResult::empty)
117                }
118            }
119            ClientRequest::CompleteRequest(request) => self
120                .complete(request.params, context)
121                .await
122                .map(ServerResult::CompleteResult),
123            ClientRequest::SetLevelRequest(request) => self
124                .set_level(request.params, context)
125                .await
126                .map(ServerResult::empty),
127            ClientRequest::GetPromptRequest(request) => self
128                .get_prompt(request.params, context)
129                .await
130                .map(ServerResult::from),
131            ClientRequest::ListPromptsRequest(request) => self
132                .list_prompts(request.params, context)
133                .await
134                .map(ServerResult::ListPromptsResult),
135            ClientRequest::ListResourcesRequest(request) => self
136                .list_resources(request.params, context)
137                .await
138                .map(ServerResult::ListResourcesResult),
139            ClientRequest::ListResourceTemplatesRequest(request) => self
140                .list_resource_templates(request.params, context)
141                .await
142                .map(ServerResult::ListResourceTemplatesResult),
143            ClientRequest::ReadResourceRequest(request) => self
144                .read_resource(request.params, context)
145                .await
146                .map(ServerResult::from),
147            ClientRequest::SubscriptionsListenRequest(request) => {
148                if legacy_request {
149                    Err(McpError::method_not_found::<SubscriptionsListenRequestMethod>())
150                } else {
151                    let requested = request.params.notifications;
152                    let Some(candidate) = self.accepted_subscription_filter(&requested) else {
153                        return Err(
154                            McpError::method_not_found::<SubscriptionsListenRequestMethod>(),
155                        );
156                    };
157                    let server_info = self.get_info();
158                    let advertised = requested.supported_by(&server_info.capabilities);
159                    let handler_accepted = requested.intersection(&candidate);
160                    let accepted = handler_accepted.intersection(&advertised);
161                    if accepted != handler_accepted {
162                        tracing::debug!(
163                            requested_resource_count = requested
164                                .resource_subscriptions
165                                .as_ref()
166                                .map_or(0, Vec::len),
167                            accepted_resource_count =
168                                accepted.resource_subscriptions.as_ref().map_or(0, Vec::len),
169                            "subscription filter reduced to advertised server capabilities"
170                        );
171                    }
172                    let server_implementation = server_info.server_info;
173                    let subscription_id = context.id.clone();
174                    let subscription =
175                        SubscriptionContext::establish(context, requested, accepted).await?;
176                    // The 2026-07-28 schema defines a final result for graceful
177                    // server teardown; explicit stdio cancellation remains a notification.
178                    self.listen(subscription).await.map(|()| {
179                        let mut result = SubscriptionsListenResult::complete(subscription_id);
180                        result.meta.set_server_info(server_implementation);
181                        ServerResult::SubscriptionsListenResult(result)
182                    })
183                }
184            }
185            ClientRequest::SubscribeRequest(request) => {
186                if !legacy_request {
187                    Err(McpError::method_not_found::<SubscribeRequestMethod>())
188                } else {
189                    self.subscribe(request.params, context)
190                        .await
191                        .map(ServerResult::empty)
192                }
193            }
194            ClientRequest::UnsubscribeRequest(request) => {
195                if !legacy_request {
196                    Err(McpError::method_not_found::<UnsubscribeRequestMethod>())
197                } else {
198                    self.unsubscribe(request.params, context)
199                        .await
200                        .map(ServerResult::empty)
201                }
202            }
203            ClientRequest::CallToolRequest(request) => {
204                let client_declared_tasks = context
205                    .client_capabilities()
206                    .is_some_and(|caps| caps.supports_tasks());
207                let response = self.call_tool(request.params, context).await?;
208                // SEP-2663: the server MUST NOT return CreateTaskResult unless
209                // the request declared the tasks extension capability. Guard
210                // against handlers that fail to check before materializing a
211                // task; such clients cannot parse a task handle.
212                if matches!(response, CallToolResponse::Task(_)) && !client_declared_tasks {
213                    return Err(McpError::missing_required_client_capability(
214                        ClientCapabilities::builder().enable_tasks().build(),
215                    ));
216                }
217                Ok(ServerResult::from(response))
218            }
219            ClientRequest::ListToolsRequest(request) => self
220                .list_tools(request.params, context)
221                .await
222                .map(ServerResult::ListToolsResult),
223            ClientRequest::CustomRequest(request) => self
224                .on_custom_request(request, context)
225                .await
226                .map(ServerResult::CustomResult),
227            ClientRequest::GetTaskRequest(request) => {
228                validate_tasks_capability::<GetTaskMethod, _>(self, &context)?;
229                self.get_task(request.params, context)
230                    .await
231                    .map(ServerResult::GetTaskResult)
232            }
233            ClientRequest::UpdateTaskRequest(request) => {
234                validate_tasks_capability::<UpdateTaskMethod, _>(self, &context)?;
235                self.update_task(request.params, context)
236                    .await
237                    .map(ServerResult::task_ack)
238            }
239            ClientRequest::CancelTaskRequest(request) => {
240                validate_tasks_capability::<CancelTaskMethod, _>(self, &context)?;
241                self.cancel_task(request.params, context)
242                    .await
243                    .map(ServerResult::task_ack)
244            }
245        };
246        let result = result.and_then(|mut result| {
247            if matches!(result, ServerResult::InputRequiredResult(_)) && !is_2026_07_28_or_later {
248                Err(McpError::invalid_request(
249                    "InputRequiredResult requires negotiated protocol version 2026-07-28 or newer",
250                    None,
251                ))
252            } else {
253                // 2026-07-28 requires caching hints on cacheable results; older
254                // peers keep the legacy shape without `resultType: "complete"`.
255                if is_2026_07_28_or_later {
256                    result.fill_missing_cache_hints();
257                } else {
258                    result.strip_result_type_for_legacy_peer();
259                }
260                Ok(result)
261            }
262        });
263
264        // Peers on 2026-07-28+ get the standard INVALID_PARAMS code for
265        // resource-not-found; older peers keep RESOURCE_NOT_FOUND.
266        result.map_err(|mut error| {
267            if is_2026_07_28_or_later && error.code == ErrorCode::RESOURCE_NOT_FOUND {
268                error.code = ErrorCode::INVALID_PARAMS;
269            }
270            error
271        })
272    }
273
274    async fn handle_notification(
275        &self,
276        notification: <RoleServer as ServiceRole>::PeerNot,
277        context: NotificationContext<RoleServer>,
278    ) -> Result<(), McpError> {
279        match notification {
280            ClientNotification::CancelledNotification(notification) => {
281                self.on_cancelled(notification.params, context).await
282            }
283            ClientNotification::ProgressNotification(notification) => {
284                self.on_progress(notification.params, context).await
285            }
286            ClientNotification::InitializedNotification(_notification) => {
287                self.on_initialized(context).await
288            }
289            ClientNotification::RootsListChangedNotification(_notification) => {
290                self.on_roots_list_changed(context).await
291            }
292            ClientNotification::CustomNotification(notification) => {
293                self.on_custom_notification(notification, context).await
294            }
295        };
296        Ok(())
297    }
298
299    fn get_info(&self) -> <RoleServer as ServiceRole>::Info {
300        self.get_info()
301    }
302
303    fn supported_protocol_versions(&self) -> Cow<'static, [ProtocolVersion]> {
304        ServerHandler::supported_protocol_versions(self)
305    }
306}
307
308macro_rules! server_handler_methods {
309    () => {
310        fn ping(
311            &self,
312            context: RequestContext<RoleServer>,
313        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
314            std::future::ready(Ok(()))
315        }
316        // handle requests
317        fn initialize(
318            &self,
319            request: InitializeRequestParams,
320            context: RequestContext<RoleServer>,
321        ) -> impl Future<Output = Result<InitializeResult, McpError>> + MaybeSendFuture + '_ {
322            context.peer.set_peer_info(request.clone());
323            std::future::ready(self.negotiate_initialize(&request))
324        }
325        /// Build the `initialize` response for `request`, negotiating the
326        /// protocol version against [`Self::supported_protocol_versions`].
327        ///
328        /// This is the whole body of the default [`Self::initialize`] minus its
329        /// `set_peer_info` side effect, so a server that overrides `initialize`
330        /// to add its own can call this instead of restating the negotiation
331        /// rule:
332        ///
333        /// ```
334        /// use rmcp::{
335        ///     ErrorData as McpError, RoleServer, ServerHandler,
336        ///     model::{InitializeRequestParams, InitializeResult, ServerConfig},
337        ///     service::RequestContext,
338        /// };
339        ///
340        /// struct MyServer;
341        ///
342        /// impl ServerHandler for MyServer {
343        ///     fn get_info(&self) -> ServerConfig {
344        ///         ServerConfig::default()
345        ///     }
346        ///
347        ///     async fn initialize(
348        ///         &self,
349        ///         request: InitializeRequestParams,
350        ///         context: RequestContext<RoleServer>,
351        ///     ) -> Result<InitializeResult, McpError> {
352        ///         // ... record telemetry, register the peer, etc.
353        ///         context.peer.set_peer_info(request.clone());
354        ///         self.negotiate_initialize(&request)
355        ///     }
356        /// }
357        /// ```
358        ///
359        /// # Errors
360        ///
361        /// Returns [`ErrorCode::UNSUPPORTED_PROTOCOL_VERSION`] when this server
362        /// supports no version that still has an `initialize` handshake.
363        ///
364        /// [`ErrorCode::UNSUPPORTED_PROTOCOL_VERSION`]: crate::model::ErrorCode::UNSUPPORTED_PROTOCOL_VERSION
365        fn negotiate_initialize(
366            &self,
367            request: &InitializeRequestParams,
368        ) -> Result<InitializeResult, McpError> {
369            let mut info = self.get_info();
370            info.protocol_version = negotiate_protocol_version(
371                &request.protocol_version,
372                std::mem::take(&mut info.protocol_version),
373                &self.supported_protocol_versions(),
374            )?;
375            Ok(info)
376        }
377        /// Return the protocol versions supported by this server.
378        ///
379        /// Defaults to every version this SDK knows. Override it to narrow the
380        /// set to the revisions the server actually implements: the returned
381        /// list is advertised by [`Self::discover`], bounds what `initialize`
382        /// negotiation may agree to, and is what per-request versions are
383        /// validated against.
384        ///
385        /// To support everything up to some ceiling, use
386        /// [`ProtocolVersion::known_up_to`] rather than filtering
387        /// [`ProtocolVersion::KNOWN_VERSIONS`] by hand.
388        fn supported_protocol_versions(&self) -> Cow<'static, [ProtocolVersion]> {
389            Cow::Borrowed(ProtocolVersion::KNOWN_VERSIONS)
390        }
391        /// Return this server's discovery information.
392        fn discover(
393            &self,
394            context: RequestContext<RoleServer>,
395        ) -> impl Future<Output = Result<DiscoverResult, McpError>> + MaybeSendFuture + '_ {
396            std::future::ready(Ok(DiscoverResult::from_server_info(
397                self.supported_protocol_versions().into_owned(),
398                self.get_info(),
399            )))
400        }
401        fn complete(
402            &self,
403            request: CompleteRequestParams,
404            context: RequestContext<RoleServer>,
405        ) -> impl Future<Output = Result<CompleteResult, McpError>> + MaybeSendFuture + '_ {
406            std::future::ready(Ok(CompleteResult::default()))
407        }
408        fn set_level(
409            &self,
410            request: SetLevelRequestParams,
411            context: RequestContext<RoleServer>,
412        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
413            std::future::ready(Err(McpError::method_not_found::<SetLevelRequestMethod>()))
414        }
415        fn get_prompt(
416            &self,
417            request: GetPromptRequestParams,
418            context: RequestContext<RoleServer>,
419        ) -> impl Future<Output = Result<GetPromptResponse, McpError>> + MaybeSendFuture + '_ {
420            std::future::ready(Err(McpError::method_not_found::<GetPromptRequestMethod>()))
421        }
422        fn list_prompts(
423            &self,
424            request: Option<PaginatedRequestParams>,
425            context: RequestContext<RoleServer>,
426        ) -> impl Future<Output = Result<ListPromptsResult, McpError>> + MaybeSendFuture + '_ {
427            std::future::ready(Ok(ListPromptsResult::default()))
428        }
429        fn list_resources(
430            &self,
431            request: Option<PaginatedRequestParams>,
432            context: RequestContext<RoleServer>,
433        ) -> impl Future<Output = Result<ListResourcesResult, McpError>> + MaybeSendFuture + '_ {
434            std::future::ready(Ok(ListResourcesResult::default()))
435        }
436        fn list_resource_templates(
437            &self,
438            request: Option<PaginatedRequestParams>,
439            context: RequestContext<RoleServer>,
440        ) -> impl Future<Output = Result<ListResourceTemplatesResult, McpError>>
441               + MaybeSendFuture
442               + '_ {
443            std::future::ready(Ok(ListResourceTemplatesResult::default()))
444        }
445        fn read_resource(
446            &self,
447            request: ReadResourceRequestParams,
448            context: RequestContext<RoleServer>,
449        ) -> impl Future<Output = Result<ReadResourceResponse, McpError>> + MaybeSendFuture + '_ {
450            std::future::ready(Err(
451                McpError::method_not_found::<ReadResourceRequestMethod>(),
452            ))
453        }
454        /// Return the subset of a requested notification filter this server accepts.
455        ///
456        /// Returning `None` leaves `subscriptions/listen` unimplemented. The SDK
457        /// intersects the returned filter with both `requested` and the notification
458        /// capabilities advertised by [`Self::get_info`] before acknowledging it.
459        /// Categories that were not requested or advertised are always removed.
460        fn accepted_subscription_filter(
461            &self,
462            requested: &SubscriptionFilter,
463        ) -> Option<SubscriptionFilter> {
464            None
465        }
466        /// Run one established subscription until it is cancelled or closed gracefully.
467        ///
468        /// The SDK sends the acknowledgment before invoking this method. Returning
469        /// `Ok(())` sends the final [`SubscriptionsListenResult`] defined by the
470        /// 2026-07-28 schema, marking graceful server teardown. Explicit
471        /// stdio cancellation uses `notifications/cancelled` instead.
472        fn listen(
473            &self,
474            context: SubscriptionContext,
475        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
476            async move {
477                context.cancelled().await;
478                Ok(())
479            }
480        }
481        #[deprecated(
482            note = "resources/subscribe is legacy-only; implement accepted_subscription_filter and listen for protocol version 2026-07-28"
483        )]
484        fn subscribe(
485            &self,
486            request: SubscribeRequestParams,
487            context: RequestContext<RoleServer>,
488        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
489            std::future::ready(Err(McpError::method_not_found::<SubscribeRequestMethod>()))
490        }
491        #[deprecated(
492            note = "resources/unsubscribe is legacy-only; subscriptions/listen is cancelled through its request lifecycle"
493        )]
494        fn unsubscribe(
495            &self,
496            request: UnsubscribeRequestParams,
497            context: RequestContext<RoleServer>,
498        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
499            std::future::ready(Err(
500                McpError::method_not_found::<UnsubscribeRequestMethod>(),
501            ))
502        }
503        /// Handle a `tools/call` request from a client.
504        ///
505        /// # Choosing a return value
506        ///
507        /// MCP distinguishes two failure modes; the API forces you to pick
508        /// the right one explicitly because they reach the caller's UI very
509        /// differently:
510        ///
511        /// - `Ok(`[`CallToolResult::error`]`(...))` — the tool ran (or tried
512        ///   to) and produced a failure the caller should see. The
513        ///   `content` you supply is rendered in the caller's MCP client,
514        ///   so the user gets your message. **This is the right return
515        ///   value for almost every "the tool didn't work" path** — empty
516        ///   results, validation failures the user can fix, downstream
517        ///   service unavailability, etc.
518        ///
519        /// - `Err(`[`McpError`]`)` — a JSON-RPC protocol error. Use this
520        ///   only when the request itself is unroutable: unknown tool
521        ///   ([`ErrorCode::METHOD_NOT_FOUND`]), malformed request shape that
522        ///   cannot be treated as a valid `tools/call`, or a server-internal
523        ///   failure that means the server cannot serve any request right now
524        ///   ([`ErrorCode::INTERNAL_ERROR`], `-32603`). MCP clients
525        ///   typically render protocol errors opaquely; **the caller will
526        ///   not see your message** — they see something like "Tool result
527        ///   missing due to internal error". If you want the caller to read
528        ///   your error, use `Ok(CallToolResult::error(...))`.
529        ///
530        /// See [`CallToolResult::error`] for a worked example.
531        fn call_tool(
532            &self,
533            request: CallToolRequestParams,
534            context: RequestContext<RoleServer>,
535        ) -> impl Future<Output = Result<CallToolResponse, McpError>> + MaybeSendFuture + '_ {
536            std::future::ready(Err(McpError::method_not_found::<CallToolRequestMethod>()))
537        }
538        fn list_tools(
539            &self,
540            request: Option<PaginatedRequestParams>,
541            context: RequestContext<RoleServer>,
542        ) -> impl Future<Output = Result<ListToolsResult, McpError>> + MaybeSendFuture + '_ {
543            std::future::ready(Ok(ListToolsResult::default()))
544        }
545        /// Get a tool definition by name.
546        ///
547        /// The default implementation returns `None`, which bypasses validation.
548        /// When using `#[tool_handler]`, this method is automatically implemented.
549        fn get_tool(&self, _name: &str) -> Option<Tool> {
550            None
551        }
552        fn on_custom_request(
553            &self,
554            request: CustomRequest,
555            context: RequestContext<RoleServer>,
556        ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
557            let CustomRequest { method, .. } = request;
558            let _ = context;
559            std::future::ready(Err(McpError::new(
560                ErrorCode::METHOD_NOT_FOUND,
561                method,
562                None,
563            )))
564        }
565
566        fn on_cancelled(
567            &self,
568            notification: CancelledNotificationParam,
569            context: NotificationContext<RoleServer>,
570        ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
571            std::future::ready(())
572        }
573        fn on_progress(
574            &self,
575            notification: ProgressNotificationParam,
576            context: NotificationContext<RoleServer>,
577        ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
578            std::future::ready(())
579        }
580        fn on_initialized(
581            &self,
582            context: NotificationContext<RoleServer>,
583        ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
584            tracing::info!("client initialized");
585            std::future::ready(())
586        }
587        fn on_roots_list_changed(
588            &self,
589            context: NotificationContext<RoleServer>,
590        ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
591            std::future::ready(())
592        }
593        fn on_custom_notification(
594            &self,
595            notification: CustomNotification,
596            context: NotificationContext<RoleServer>,
597        ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
598            let _ = (notification, context);
599            std::future::ready(())
600        }
601
602        fn get_info(&self) -> ServerConfig {
603            ServerConfig::default()
604        }
605
606        /// SEP-2663 `tasks/get`: return the current [`DetailedTask`] state.
607        fn get_task(
608            &self,
609            request: GetTaskParams,
610            context: RequestContext<RoleServer>,
611        ) -> impl Future<Output = Result<GetTaskResult, McpError>> + MaybeSendFuture + '_ {
612            let _ = (request, context);
613            std::future::ready(Err(McpError::method_not_found::<GetTaskMethod>()))
614        }
615
616        /// SEP-2663 `tasks/update`: accept responses to outstanding in-task
617        /// input requests. Returns an empty acknowledgement on success.
618        fn update_task(
619            &self,
620            request: UpdateTaskParams,
621            context: RequestContext<RoleServer>,
622        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
623            let _ = (request, context);
624            std::future::ready(Err(McpError::method_not_found::<UpdateTaskMethod>()))
625        }
626
627        /// SEP-2663 `tasks/cancel`: cooperative cancellation. Returns an empty
628        /// acknowledgement; the task's observable status may lag.
629        fn cancel_task(
630            &self,
631            request: CancelTaskParams,
632            context: RequestContext<RoleServer>,
633        ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
634            let _ = (request, context);
635            std::future::ready(Err(McpError::method_not_found::<CancelTaskMethod>()))
636        }
637    };
638}
639
640#[allow(unused_variables)]
641#[cfg(not(feature = "local"))]
642pub trait ServerHandler: Sized + Send + Sync + 'static {
643    server_handler_methods!();
644}
645
646#[allow(unused_variables)]
647#[cfg(feature = "local")]
648pub trait ServerHandler: Sized + 'static {
649    server_handler_methods!();
650}
651
652macro_rules! impl_server_handler_for_wrapper {
653    ($wrapper:ident) => {
654        impl<T: ServerHandler> ServerHandler for $wrapper<T> {
655            fn ping(
656                &self,
657                context: RequestContext<RoleServer>,
658            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
659                (**self).ping(context)
660            }
661
662            fn initialize(
663                &self,
664                request: InitializeRequestParams,
665                context: RequestContext<RoleServer>,
666            ) -> impl Future<Output = Result<InitializeResult, McpError>> + MaybeSendFuture + '_ {
667                (**self).initialize(request, context)
668            }
669
670            fn negotiate_initialize(
671                &self,
672                request: &InitializeRequestParams,
673            ) -> Result<InitializeResult, McpError> {
674                (**self).negotiate_initialize(request)
675            }
676
677            fn supported_protocol_versions(&self) -> Cow<'static, [ProtocolVersion]> {
678                (**self).supported_protocol_versions()
679            }
680
681            fn discover(
682                &self,
683                context: RequestContext<RoleServer>,
684            ) -> impl Future<Output = Result<DiscoverResult, McpError>> + MaybeSendFuture + '_ {
685                (**self).discover(context)
686            }
687
688            fn complete(
689                &self,
690                request: CompleteRequestParams,
691                context: RequestContext<RoleServer>,
692            ) -> impl Future<Output = Result<CompleteResult, McpError>> + MaybeSendFuture + '_ {
693                (**self).complete(request, context)
694            }
695
696            fn set_level(
697                &self,
698                request: SetLevelRequestParams,
699                context: RequestContext<RoleServer>,
700            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
701                (**self).set_level(request, context)
702            }
703
704            fn get_prompt(
705                &self,
706                request: GetPromptRequestParams,
707                context: RequestContext<RoleServer>,
708            ) -> impl Future<Output = Result<GetPromptResponse, McpError>> + MaybeSendFuture + '_ {
709                (**self).get_prompt(request, context)
710            }
711
712            fn list_prompts(
713                &self,
714                request: Option<PaginatedRequestParams>,
715                context: RequestContext<RoleServer>,
716            ) -> impl Future<Output = Result<ListPromptsResult, McpError>> + MaybeSendFuture + '_ {
717                (**self).list_prompts(request, context)
718            }
719
720            fn list_resources(
721                &self,
722                request: Option<PaginatedRequestParams>,
723                context: RequestContext<RoleServer>,
724            ) -> impl Future<Output = Result<ListResourcesResult, McpError>> + MaybeSendFuture + '_ {
725                (**self).list_resources(request, context)
726            }
727
728            fn list_resource_templates(
729                &self,
730                request: Option<PaginatedRequestParams>,
731                context: RequestContext<RoleServer>,
732            ) -> impl Future<Output = Result<ListResourceTemplatesResult, McpError>> + MaybeSendFuture + '_
733            {
734                (**self).list_resource_templates(request, context)
735            }
736
737            fn read_resource(
738                &self,
739                request: ReadResourceRequestParams,
740                context: RequestContext<RoleServer>,
741            ) -> impl Future<Output = Result<ReadResourceResponse, McpError>> + MaybeSendFuture + '_ {
742                (**self).read_resource(request, context)
743            }
744
745            fn accepted_subscription_filter(
746                &self,
747                requested: &SubscriptionFilter,
748            ) -> Option<SubscriptionFilter> {
749                (**self).accepted_subscription_filter(requested)
750            }
751
752            fn listen(
753                &self,
754                context: SubscriptionContext,
755            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
756                (**self).listen(context)
757            }
758
759            fn subscribe(
760                &self,
761                request: SubscribeRequestParams,
762                context: RequestContext<RoleServer>,
763            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
764                (**self).subscribe(request, context)
765            }
766
767            fn unsubscribe(
768                &self,
769                request: UnsubscribeRequestParams,
770                context: RequestContext<RoleServer>,
771            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
772                (**self).unsubscribe(request, context)
773            }
774
775            fn call_tool(
776                &self,
777                request: CallToolRequestParams,
778                context: RequestContext<RoleServer>,
779            ) -> impl Future<Output = Result<CallToolResponse, McpError>> + MaybeSendFuture + '_ {
780                (**self).call_tool(request, context)
781            }
782
783            fn list_tools(
784                &self,
785                request: Option<PaginatedRequestParams>,
786                context: RequestContext<RoleServer>,
787            ) -> impl Future<Output = Result<ListToolsResult, McpError>> + MaybeSendFuture + '_ {
788                (**self).list_tools(request, context)
789            }
790
791            fn get_tool(&self, name: &str) -> Option<Tool> {
792                (**self).get_tool(name)
793            }
794
795            fn on_custom_request(
796                &self,
797                request: CustomRequest,
798                context: RequestContext<RoleServer>,
799            ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
800                (**self).on_custom_request(request, context)
801            }
802
803            fn on_cancelled(
804                &self,
805                notification: CancelledNotificationParam,
806                context: NotificationContext<RoleServer>,
807            ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
808                (**self).on_cancelled(notification, context)
809            }
810
811            fn on_progress(
812                &self,
813                notification: ProgressNotificationParam,
814                context: NotificationContext<RoleServer>,
815            ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
816                (**self).on_progress(notification, context)
817            }
818
819            fn on_initialized(
820                &self,
821                context: NotificationContext<RoleServer>,
822            ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
823                (**self).on_initialized(context)
824            }
825
826            fn on_roots_list_changed(
827                &self,
828                context: NotificationContext<RoleServer>,
829            ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
830                (**self).on_roots_list_changed(context)
831            }
832
833            fn on_custom_notification(
834                &self,
835                notification: CustomNotification,
836                context: NotificationContext<RoleServer>,
837            ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
838                (**self).on_custom_notification(notification, context)
839            }
840
841            fn get_info(&self) -> ServerConfig {
842                (**self).get_info()
843            }
844
845            fn get_task(
846                &self,
847                request: GetTaskParams,
848                context: RequestContext<RoleServer>,
849            ) -> impl Future<Output = Result<GetTaskResult, McpError>> + MaybeSendFuture + '_ {
850                (**self).get_task(request, context)
851            }
852
853            fn update_task(
854                &self,
855                request: UpdateTaskParams,
856                context: RequestContext<RoleServer>,
857            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
858                (**self).update_task(request, context)
859            }
860
861            fn cancel_task(
862                &self,
863                request: CancelTaskParams,
864                context: RequestContext<RoleServer>,
865            ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
866                (**self).cancel_task(request, context)
867            }
868        }
869    };
870}
871
872impl_server_handler_for_wrapper!(Box);
873impl_server_handler_for_wrapper!(Arc);