diff --git a/crates/rmcp/src/handler/server.rs b/crates/rmcp/src/handler/server.rs index 7f21f8d63..8673a8bfd 100644 --- a/crates/rmcp/src/handler/server.rs +++ b/crates/rmcp/src/handler/server.rs @@ -4,8 +4,7 @@ use crate::{ error::ErrorData as McpError, model::{TaskSupport, *}, service::{ - MaybeSend, MaybeSendFuture, NotificationContext, RequestContext, RoleServer, Service, - ServiceRole, + MaybeSendFuture, NotificationContext, RequestContext, RoleServer, Service, ServiceRole, }, }; @@ -161,214 +160,226 @@ impl Service for H { } } -#[allow(unused_variables)] -#[allow( - private_bounds, - reason = "MaybeSend is a sealed conditional Send + Sync alias" -)] -pub trait ServerHandler: Sized + MaybeSend + 'static { - fn enqueue_task( - &self, - _request: CallToolRequestParams, - _context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::internal_error( - "Task processing not implemented".to_string(), - None, - ))) - } - fn ping( - &self, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Ok(())) - } - // handle requests - fn initialize( - &self, - request: InitializeRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - if context.peer.peer_info().is_none() { - context.peer.set_peer_info(request); +macro_rules! server_handler_methods { + () => { + fn enqueue_task( + &self, + _request: CallToolRequestParams, + _context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err(McpError::internal_error( + "Task processing not implemented".to_string(), + None, + ))) + } + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Ok(())) + } + // handle requests + fn initialize( + &self, + request: InitializeRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + if context.peer.peer_info().is_none() { + context.peer.set_peer_info(request); + } + std::future::ready(Ok(self.get_info())) + } + fn complete( + &self, + request: CompleteRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Ok(CompleteResult::default())) + } + fn set_level( + &self, + request: SetLevelRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err(McpError::method_not_found::())) + } + fn get_prompt( + &self, + request: GetPromptRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err(McpError::method_not_found::())) + } + fn list_prompts( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Ok(ListPromptsResult::default())) + } + fn list_resources( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Ok(ListResourcesResult::default())) + } + fn list_resource_templates( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + + MaybeSendFuture + + '_ { + std::future::ready(Ok(ListResourceTemplatesResult::default())) + } + fn read_resource( + &self, + request: ReadResourceRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err( + McpError::method_not_found::(), + )) + } + fn subscribe( + &self, + request: SubscribeRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err(McpError::method_not_found::())) + } + fn unsubscribe( + &self, + request: UnsubscribeRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err( + McpError::method_not_found::(), + )) + } + fn call_tool( + &self, + request: CallToolRequestParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err(McpError::method_not_found::())) + } + fn list_tools( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Ok(ListToolsResult::default())) + } + /// Get a tool definition by name. + /// + /// The default implementation returns `None`, which bypasses validation. + /// When using `#[tool_handler]`, this method is automatically implemented. + fn get_tool(&self, _name: &str) -> Option { + None + } + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + let CustomRequest { method, .. } = request; + let _ = context; + std::future::ready(Err(McpError::new( + ErrorCode::METHOD_NOT_FOUND, + method, + None, + ))) } - std::future::ready(Ok(self.get_info())) - } - fn complete( - &self, - request: CompleteRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Ok(CompleteResult::default())) - } - fn set_level( - &self, - request: SetLevelRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::method_not_found::())) - } - fn get_prompt( - &self, - request: GetPromptRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::method_not_found::())) - } - fn list_prompts( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Ok(ListPromptsResult::default())) - } - fn list_resources( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Ok(ListResourcesResult::default())) - } - fn list_resource_templates( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ - { - std::future::ready(Ok(ListResourceTemplatesResult::default())) - } - fn read_resource( - &self, - request: ReadResourceRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err( - McpError::method_not_found::(), - )) - } - fn subscribe( - &self, - request: SubscribeRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::method_not_found::())) - } - fn unsubscribe( - &self, - request: UnsubscribeRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::method_not_found::())) - } - fn call_tool( - &self, - request: CallToolRequestParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::method_not_found::())) - } - fn list_tools( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Ok(ListToolsResult::default())) - } - /// Get a tool definition by name. - /// - /// The default implementation returns `None`, which bypasses validation. - /// When using `#[tool_handler]`, this method is automatically implemented. - fn get_tool(&self, _name: &str) -> Option { - None - } - fn on_custom_request( - &self, - request: CustomRequest, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - let CustomRequest { method, .. } = request; - let _ = context; - std::future::ready(Err(McpError::new( - ErrorCode::METHOD_NOT_FOUND, - method, - None, - ))) - } - fn on_cancelled( - &self, - notification: CancelledNotificationParam, - context: NotificationContext, - ) -> impl Future + MaybeSendFuture + '_ { - std::future::ready(()) - } - fn on_progress( - &self, - notification: ProgressNotificationParam, - context: NotificationContext, - ) -> impl Future + MaybeSendFuture + '_ { - std::future::ready(()) - } - fn on_initialized( - &self, - context: NotificationContext, - ) -> impl Future + MaybeSendFuture + '_ { - tracing::info!("client initialized"); - std::future::ready(()) - } - fn on_roots_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + MaybeSendFuture + '_ { - std::future::ready(()) - } - fn on_custom_notification( - &self, - notification: CustomNotification, - context: NotificationContext, - ) -> impl Future + MaybeSendFuture + '_ { - let _ = (notification, context); - std::future::ready(()) - } + fn on_cancelled( + &self, + notification: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + MaybeSendFuture + '_ { + std::future::ready(()) + } + fn on_progress( + &self, + notification: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + MaybeSendFuture + '_ { + std::future::ready(()) + } + fn on_initialized( + &self, + context: NotificationContext, + ) -> impl Future + MaybeSendFuture + '_ { + tracing::info!("client initialized"); + std::future::ready(()) + } + fn on_roots_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + MaybeSendFuture + '_ { + std::future::ready(()) + } + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + MaybeSendFuture + '_ { + let _ = (notification, context); + std::future::ready(()) + } - fn get_info(&self) -> ServerInfo { - ServerInfo::default() - } + fn get_info(&self) -> ServerInfo { + ServerInfo::default() + } - fn list_tasks( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - std::future::ready(Err(McpError::method_not_found::())) - } + fn list_tasks( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + std::future::ready(Err(McpError::method_not_found::())) + } - fn get_task_info( - &self, - request: GetTaskInfoParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - let _ = (request, context); - std::future::ready(Err(McpError::method_not_found::())) - } + fn get_task_info( + &self, + request: GetTaskInfoParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + let _ = (request, context); + std::future::ready(Err(McpError::method_not_found::())) + } - fn get_task_result( - &self, - request: GetTaskResultParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - let _ = (request, context); - std::future::ready(Err(McpError::method_not_found::())) - } + fn get_task_result( + &self, + request: GetTaskResultParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + let _ = (request, context); + std::future::ready(Err(McpError::method_not_found::())) + } - fn cancel_task( - &self, - request: CancelTaskParams, - context: RequestContext, - ) -> impl Future> + MaybeSendFuture + '_ { - let _ = (request, context); - std::future::ready(Err(McpError::method_not_found::())) - } + fn cancel_task( + &self, + request: CancelTaskParams, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_ { + let _ = (request, context); + std::future::ready(Err(McpError::method_not_found::())) + } + }; +} + +#[allow(unused_variables)] +#[cfg(not(feature = "local"))] +pub trait ServerHandler: Sized + Send + Sync + 'static { + server_handler_methods!(); +} + +#[allow(unused_variables)] +#[cfg(feature = "local")] +pub trait ServerHandler: Sized + 'static { + server_handler_methods!(); } macro_rules! impl_server_handler_for_wrapper { diff --git a/crates/rmcp/src/service.rs b/crates/rmcp/src/service.rs index be9b461ab..95188cb96 100644 --- a/crates/rmcp/src/service.rs +++ b/crates/rmcp/src/service.rs @@ -128,11 +128,23 @@ pub type RxJsonRpcMessage = JsonRpcMessage< ::PeerNot, >; -#[allow( - private_bounds, - reason = "MaybeSend is a sealed conditional Send + Sync alias" -)] -pub trait Service: MaybeSend + 'static { +#[cfg(not(feature = "local"))] +pub trait Service: Send + Sync + 'static { + fn handle_request( + &self, + request: R::PeerReq, + context: RequestContext, + ) -> impl Future> + MaybeSendFuture + '_; + fn handle_notification( + &self, + notification: R::PeerNot, + context: NotificationContext, + ) -> impl Future> + MaybeSendFuture + '_; + fn get_info(&self) -> R::Info; +} + +#[cfg(feature = "local")] +pub trait Service: 'static { fn handle_request( &self, request: R::PeerReq, @@ -197,11 +209,23 @@ impl Service for Box> { } } -#[allow( - private_bounds, - reason = "MaybeSend is a sealed conditional Send + Sync alias" -)] -pub trait DynService: MaybeSend { +#[cfg(not(feature = "local"))] +pub trait DynService: Send + Sync { + fn handle_request( + &self, + request: R::PeerReq, + context: RequestContext, + ) -> MaybeBoxFuture<'_, Result>; + fn handle_notification( + &self, + notification: R::PeerNot, + context: NotificationContext, + ) -> MaybeBoxFuture<'_, Result<(), McpError>>; + fn get_info(&self) -> R::Info; +} + +#[cfg(feature = "local")] +pub trait DynService { fn handle_request( &self, request: R::PeerReq,