From 101a5a646c728b746c2cbd7d8d7ccab7f6291858 Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Wed, 7 Jan 2026 15:56:51 -0600 Subject: [PATCH 1/5] Implement ServerHandler for Box and Arc where H is a ServerHandler --- crates/rmcp/src/handler/server.rs | 390 +++++++++++++++++++++++ crates/rmcp/src/handler/server/router.rs | 2 +- 2 files changed, 391 insertions(+), 1 deletion(-) diff --git a/crates/rmcp/src/handler/server.rs b/crates/rmcp/src/handler/server.rs index f10cfa7c..70549607 100644 --- a/crates/rmcp/src/handler/server.rs +++ b/crates/rmcp/src/handler/server.rs @@ -327,3 +327,393 @@ pub trait ServerHandler: Sized + Send + Sync + 'static { std::future::ready(Err(McpError::method_not_found::())) } } + +impl ServerHandler for Box { + fn enqueue_task( + &self, + request: CallToolRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).enqueue_task(request, context) + } + + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).ping(context) + } + + fn initialize( + &self, + request: InitializeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).initialize(request, context) + } + + fn complete( + &self, + request: CompleteRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).complete(request, context) + } + + fn set_level( + &self, + request: SetLevelRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).set_level(request, context) + } + + fn get_prompt( + &self, + request: GetPromptRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_prompt(request, context) + } + + fn list_prompts( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_prompts(request, context) + } + + fn list_resources( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_resources(request, context) + } + + fn list_resource_templates( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_resource_templates(request, context) + } + + fn read_resource( + &self, + request: ReadResourceRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).read_resource(request, context) + } + + fn subscribe( + &self, + request: SubscribeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).subscribe(request, context) + } + + fn unsubscribe( + &self, + request: UnsubscribeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).unsubscribe(request, context) + } + + fn call_tool( + &self, + request: CallToolRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).call_tool(request, context) + } + + fn list_tools( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_tools(request, context) + } + + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).on_custom_request(request, context) + } + + fn on_cancelled( + &self, + notification: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_cancelled(notification, context) + } + + fn on_progress( + &self, + notification: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_progress(notification, context) + } + + fn on_initialized( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_initialized(context) + } + + fn on_roots_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_roots_list_changed(context) + } + + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_custom_notification(notification, context) + } + + fn get_info(&self) -> ServerInfo { + (**self).get_info() + } + + fn list_tasks( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_tasks(request, context) + } + + fn get_task_info( + &self, + request: GetTaskInfoParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_task_info(request, context) + } + + fn get_task_result( + &self, + request: GetTaskResultParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_task_result(request, context) + } + + fn cancel_task( + &self, + request: CancelTaskParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).cancel_task(request, context) + } +} + +impl ServerHandler for std::sync::Arc { + fn enqueue_task( + &self, + request: CallToolRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).enqueue_task(request, context) + } + + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).ping(context) + } + + fn initialize( + &self, + request: InitializeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).initialize(request, context) + } + + fn complete( + &self, + request: CompleteRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).complete(request, context) + } + + fn set_level( + &self, + request: SetLevelRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).set_level(request, context) + } + + fn get_prompt( + &self, + request: GetPromptRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_prompt(request, context) + } + + fn list_prompts( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_prompts(request, context) + } + + fn list_resources( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_resources(request, context) + } + + fn list_resource_templates( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_resource_templates(request, context) + } + + fn read_resource( + &self, + request: ReadResourceRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).read_resource(request, context) + } + + fn subscribe( + &self, + request: SubscribeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).subscribe(request, context) + } + + fn unsubscribe( + &self, + request: UnsubscribeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).unsubscribe(request, context) + } + + fn call_tool( + &self, + request: CallToolRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).call_tool(request, context) + } + + fn list_tools( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_tools(request, context) + } + + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).on_custom_request(request, context) + } + + fn on_cancelled( + &self, + notification: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_cancelled(notification, context) + } + + fn on_progress( + &self, + notification: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_progress(notification, context) + } + + fn on_initialized( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_initialized(context) + } + + fn on_roots_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_roots_list_changed(context) + } + + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_custom_notification(notification, context) + } + + fn get_info(&self) -> ServerInfo { + (**self).get_info() + } + + fn list_tasks( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_tasks(request, context) + } + + fn get_task_info( + &self, + request: GetTaskInfoParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_task_info(request, context) + } + + fn get_task_result( + &self, + request: GetTaskResultParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_task_result(request, context) + } + + fn cancel_task( + &self, + request: CancelTaskParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).cancel_task(request, context) + } +} diff --git a/crates/rmcp/src/handler/server/router.rs b/crates/rmcp/src/handler/server/router.rs index 0b908081..1f34ba5b 100644 --- a/crates/rmcp/src/handler/server/router.rs +++ b/crates/rmcp/src/handler/server/router.rs @@ -133,6 +133,6 @@ where } fn get_info(&self) -> ::Info { - self.service.get_info() + ServerHandler::get_info(&self.service) } } From 6b4b5346fd2f748a460befa9f41d8695177fd759 Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Wed, 7 Jan 2026 16:08:20 -0600 Subject: [PATCH 2/5] Implement ClientHandler for Box and Arc where H is a ClientHandler --- crates/rmcp/src/handler/client.rs | 210 ++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) diff --git a/crates/rmcp/src/handler/client.rs b/crates/rmcp/src/handler/client.rs index 15b1c0c0..b9e79387 100644 --- a/crates/rmcp/src/handler/client.rs +++ b/crates/rmcp/src/handler/client.rs @@ -210,3 +210,213 @@ impl ClientHandler for ClientInfo { self.clone() } } + +impl ClientHandler for Box { + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).ping(context) + } + + fn create_message( + &self, + params: CreateMessageRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).create_message(params, context) + } + + fn list_roots( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_roots(context) + } + + fn create_elicitation( + &self, + request: CreateElicitationRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).create_elicitation(request, context) + } + + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).on_custom_request(request, context) + } + + fn on_cancelled( + &self, + params: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_cancelled(params, context) + } + + fn on_progress( + &self, + params: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_progress(params, context) + } + + fn on_logging_message( + &self, + params: LoggingMessageNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_logging_message(params, context) + } + + fn on_resource_updated( + &self, + params: ResourceUpdatedNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_resource_updated(params, context) + } + + fn on_resource_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_resource_list_changed(context) + } + + fn on_tool_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_tool_list_changed(context) + } + + fn on_prompt_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_prompt_list_changed(context) + } + + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_custom_notification(notification, context) + } + + fn get_info(&self) -> ClientInfo { + (**self).get_info() + } +} + +impl ClientHandler for std::sync::Arc { + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).ping(context) + } + + fn create_message( + &self, + params: CreateMessageRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).create_message(params, context) + } + + fn list_roots( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_roots(context) + } + + fn create_elicitation( + &self, + request: CreateElicitationRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).create_elicitation(request, context) + } + + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).on_custom_request(request, context) + } + + fn on_cancelled( + &self, + params: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_cancelled(params, context) + } + + fn on_progress( + &self, + params: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_progress(params, context) + } + + fn on_logging_message( + &self, + params: LoggingMessageNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_logging_message(params, context) + } + + fn on_resource_updated( + &self, + params: ResourceUpdatedNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_resource_updated(params, context) + } + + fn on_resource_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_resource_list_changed(context) + } + + fn on_tool_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_tool_list_changed(context) + } + + fn on_prompt_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_prompt_list_changed(context) + } + + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_custom_notification(notification, context) + } + + fn get_info(&self) -> ClientInfo { + (**self).get_info() + } +} From 6a078e6583eb666a217ef5b1465a352f44a2ba3d Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Wed, 7 Jan 2026 16:38:33 -0600 Subject: [PATCH 3/5] Test Box and Arc have blanket implementations for handler traits --- crates/rmcp/tests/test_handler_wrappers.rs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 crates/rmcp/tests/test_handler_wrappers.rs diff --git a/crates/rmcp/tests/test_handler_wrappers.rs b/crates/rmcp/tests/test_handler_wrappers.rs new file mode 100644 index 00000000..06558cdf --- /dev/null +++ b/crates/rmcp/tests/test_handler_wrappers.rs @@ -0,0 +1,29 @@ +// cargo test --test test_handler_wrappers --features "client server" + +mod common; + +use std::sync::Arc; + +use rmcp::{ClientHandler, ServerHandler}; + +use common::handlers::{TestClientHandler, TestServer}; + +#[test] +fn test_wrapped_server_handlers() { + // This test asserts that, when T: ServerHandler, both Box and Arc also implement ServerHandler. + fn accepts_server_handler(_handler: H) {} + + accepts_server_handler(Box::new(TestServer::new())); + accepts_server_handler(Arc::new(TestServer::new())); +} + +#[test] +fn test_wrapped_client_handlers() { + // This test asserts that, when T: ClientHandler, both Box and Arc also implement ClientHandler. + fn accepts_client_handler(_handler: H) {} + + let client = TestClientHandler::new(false, false); + + accepts_client_handler(Box::new(client.clone())); + accepts_client_handler(Arc::new(client)); +} From 641a8cfe87a981de87036db7e68f97bd4c53555d Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Wed, 7 Jan 2026 16:43:50 -0600 Subject: [PATCH 4/5] Remove needless maybe sized bound --- crates/rmcp/src/handler/client.rs | 4 ++-- crates/rmcp/src/handler/server.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rmcp/src/handler/client.rs b/crates/rmcp/src/handler/client.rs index b9e79387..73681894 100644 --- a/crates/rmcp/src/handler/client.rs +++ b/crates/rmcp/src/handler/client.rs @@ -211,7 +211,7 @@ impl ClientHandler for ClientInfo { } } -impl ClientHandler for Box { +impl ClientHandler for Box { fn ping( &self, context: RequestContext, @@ -316,7 +316,7 @@ impl ClientHandler for Box { } } -impl ClientHandler for std::sync::Arc { +impl ClientHandler for std::sync::Arc { fn ping( &self, context: RequestContext, diff --git a/crates/rmcp/src/handler/server.rs b/crates/rmcp/src/handler/server.rs index 70549607..477172ef 100644 --- a/crates/rmcp/src/handler/server.rs +++ b/crates/rmcp/src/handler/server.rs @@ -328,7 +328,7 @@ pub trait ServerHandler: Sized + Send + Sync + 'static { } } -impl ServerHandler for Box { +impl ServerHandler for Box { fn enqueue_task( &self, request: CallToolRequestParam, @@ -523,7 +523,7 @@ impl ServerHandler for Box { } } -impl ServerHandler for std::sync::Arc { +impl ServerHandler for std::sync::Arc { fn enqueue_task( &self, request: CallToolRequestParam, From a493962695b7683b3a906378c16bf324fccc3bed Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Fri, 9 Jan 2026 17:01:53 -0600 Subject: [PATCH 5/5] Deduplicate blanket implementations with macros --- crates/rmcp/src/handler/client.rs | 291 ++++++---------- crates/rmcp/src/handler/server.rs | 540 ++++++++++-------------------- 2 files changed, 274 insertions(+), 557 deletions(-) diff --git a/crates/rmcp/src/handler/client.rs b/crates/rmcp/src/handler/client.rs index 73681894..db73bf36 100644 --- a/crates/rmcp/src/handler/client.rs +++ b/crates/rmcp/src/handler/client.rs @@ -4,6 +4,7 @@ use crate::{ model::*, service::{NotificationContext, RequestContext, RoleClient, Service, ServiceRole}, }; +use std::sync::Arc; impl Service for H { async fn handle_request( @@ -211,212 +212,114 @@ impl ClientHandler for ClientInfo { } } -impl ClientHandler for Box { - fn ping( - &self, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).ping(context) - } +macro_rules! impl_client_handler_for_wrapper { + ($wrapper:ident) => { + impl ClientHandler for $wrapper { + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).ping(context) + } - fn create_message( - &self, - params: CreateMessageRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).create_message(params, context) - } + fn create_message( + &self, + params: CreateMessageRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).create_message(params, context) + } - fn list_roots( - &self, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_roots(context) - } + fn list_roots( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_roots(context) + } - fn create_elicitation( - &self, - request: CreateElicitationRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).create_elicitation(request, context) - } + fn create_elicitation( + &self, + request: CreateElicitationRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).create_elicitation(request, context) + } - fn on_custom_request( - &self, - request: CustomRequest, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).on_custom_request(request, context) - } + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).on_custom_request(request, context) + } - fn on_cancelled( - &self, - params: CancelledNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_cancelled(params, context) - } + fn on_cancelled( + &self, + params: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_cancelled(params, context) + } - fn on_progress( - &self, - params: ProgressNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_progress(params, context) - } + fn on_progress( + &self, + params: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_progress(params, context) + } - fn on_logging_message( - &self, - params: LoggingMessageNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_logging_message(params, context) - } + fn on_logging_message( + &self, + params: LoggingMessageNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_logging_message(params, context) + } - fn on_resource_updated( - &self, - params: ResourceUpdatedNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_resource_updated(params, context) - } + fn on_resource_updated( + &self, + params: ResourceUpdatedNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_resource_updated(params, context) + } - fn on_resource_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_resource_list_changed(context) - } + fn on_resource_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_resource_list_changed(context) + } - fn on_tool_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_tool_list_changed(context) - } + fn on_tool_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_tool_list_changed(context) + } - fn on_prompt_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_prompt_list_changed(context) - } + fn on_prompt_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_prompt_list_changed(context) + } - fn on_custom_notification( - &self, - notification: CustomNotification, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_custom_notification(notification, context) - } + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_custom_notification(notification, context) + } - fn get_info(&self) -> ClientInfo { - (**self).get_info() - } + fn get_info(&self) -> ClientInfo { + (**self).get_info() + } + } + }; } -impl ClientHandler for std::sync::Arc { - fn ping( - &self, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).ping(context) - } - - fn create_message( - &self, - params: CreateMessageRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).create_message(params, context) - } - - fn list_roots( - &self, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_roots(context) - } - - fn create_elicitation( - &self, - request: CreateElicitationRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).create_elicitation(request, context) - } - - fn on_custom_request( - &self, - request: CustomRequest, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).on_custom_request(request, context) - } - - fn on_cancelled( - &self, - params: CancelledNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_cancelled(params, context) - } - - fn on_progress( - &self, - params: ProgressNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_progress(params, context) - } - - fn on_logging_message( - &self, - params: LoggingMessageNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_logging_message(params, context) - } - - fn on_resource_updated( - &self, - params: ResourceUpdatedNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_resource_updated(params, context) - } - - fn on_resource_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_resource_list_changed(context) - } - - fn on_tool_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_tool_list_changed(context) - } - - fn on_prompt_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_prompt_list_changed(context) - } - - fn on_custom_notification( - &self, - notification: CustomNotification, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_custom_notification(notification, context) - } - - fn get_info(&self) -> ClientInfo { - (**self).get_info() - } -} +impl_client_handler_for_wrapper!(Box); +impl_client_handler_for_wrapper!(Arc); diff --git a/crates/rmcp/src/handler/server.rs b/crates/rmcp/src/handler/server.rs index 477172ef..30b90525 100644 --- a/crates/rmcp/src/handler/server.rs +++ b/crates/rmcp/src/handler/server.rs @@ -3,6 +3,7 @@ use crate::{ model::*, service::{NotificationContext, RequestContext, RoleServer, Service, ServiceRole}, }; +use std::sync::Arc; pub mod common; pub mod prompt; @@ -328,392 +329,205 @@ pub trait ServerHandler: Sized + Send + Sync + 'static { } } -impl ServerHandler for Box { - fn enqueue_task( - &self, - request: CallToolRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).enqueue_task(request, context) - } +macro_rules! impl_server_handler_for_wrapper { + ($wrapper:ident) => { + impl ServerHandler for $wrapper { + fn enqueue_task( + &self, + request: CallToolRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).enqueue_task(request, context) + } - fn ping( - &self, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).ping(context) - } + fn ping( + &self, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).ping(context) + } - fn initialize( - &self, - request: InitializeRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).initialize(request, context) - } + fn initialize( + &self, + request: InitializeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).initialize(request, context) + } - fn complete( - &self, - request: CompleteRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).complete(request, context) - } + fn complete( + &self, + request: CompleteRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).complete(request, context) + } - fn set_level( - &self, - request: SetLevelRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).set_level(request, context) - } + fn set_level( + &self, + request: SetLevelRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).set_level(request, context) + } - fn get_prompt( - &self, - request: GetPromptRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).get_prompt(request, context) - } + fn get_prompt( + &self, + request: GetPromptRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_prompt(request, context) + } - fn list_prompts( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_prompts(request, context) - } + fn list_prompts( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_prompts(request, context) + } - fn list_resources( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_resources(request, context) - } + fn list_resources( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_resources(request, context) + } - fn list_resource_templates( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_resource_templates(request, context) - } + fn list_resource_templates( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ + { + (**self).list_resource_templates(request, context) + } - fn read_resource( - &self, - request: ReadResourceRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).read_resource(request, context) - } + fn read_resource( + &self, + request: ReadResourceRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).read_resource(request, context) + } - fn subscribe( - &self, - request: SubscribeRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).subscribe(request, context) - } + fn subscribe( + &self, + request: SubscribeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).subscribe(request, context) + } - fn unsubscribe( - &self, - request: UnsubscribeRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).unsubscribe(request, context) - } + fn unsubscribe( + &self, + request: UnsubscribeRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).unsubscribe(request, context) + } - fn call_tool( - &self, - request: CallToolRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).call_tool(request, context) - } + fn call_tool( + &self, + request: CallToolRequestParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).call_tool(request, context) + } - fn list_tools( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_tools(request, context) - } + fn list_tools( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_tools(request, context) + } - fn on_custom_request( - &self, - request: CustomRequest, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).on_custom_request(request, context) - } + fn on_custom_request( + &self, + request: CustomRequest, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).on_custom_request(request, context) + } - fn on_cancelled( - &self, - notification: CancelledNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_cancelled(notification, context) - } + fn on_cancelled( + &self, + notification: CancelledNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_cancelled(notification, context) + } - fn on_progress( - &self, - notification: ProgressNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_progress(notification, context) - } + fn on_progress( + &self, + notification: ProgressNotificationParam, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_progress(notification, context) + } - fn on_initialized( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_initialized(context) - } + fn on_initialized( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_initialized(context) + } - fn on_roots_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_roots_list_changed(context) - } + fn on_roots_list_changed( + &self, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_roots_list_changed(context) + } - fn on_custom_notification( - &self, - notification: CustomNotification, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_custom_notification(notification, context) - } + fn on_custom_notification( + &self, + notification: CustomNotification, + context: NotificationContext, + ) -> impl Future + Send + '_ { + (**self).on_custom_notification(notification, context) + } - fn get_info(&self) -> ServerInfo { - (**self).get_info() - } + fn get_info(&self) -> ServerInfo { + (**self).get_info() + } - fn list_tasks( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_tasks(request, context) - } + fn list_tasks( + &self, + request: Option, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).list_tasks(request, context) + } - fn get_task_info( - &self, - request: GetTaskInfoParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).get_task_info(request, context) - } + fn get_task_info( + &self, + request: GetTaskInfoParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_task_info(request, context) + } - fn get_task_result( - &self, - request: GetTaskResultParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).get_task_result(request, context) - } + fn get_task_result( + &self, + request: GetTaskResultParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).get_task_result(request, context) + } - fn cancel_task( - &self, - request: CancelTaskParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).cancel_task(request, context) - } + fn cancel_task( + &self, + request: CancelTaskParam, + context: RequestContext, + ) -> impl Future> + Send + '_ { + (**self).cancel_task(request, context) + } + } + }; } -impl ServerHandler for std::sync::Arc { - fn enqueue_task( - &self, - request: CallToolRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).enqueue_task(request, context) - } - - fn ping( - &self, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).ping(context) - } - - fn initialize( - &self, - request: InitializeRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).initialize(request, context) - } - - fn complete( - &self, - request: CompleteRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).complete(request, context) - } - - fn set_level( - &self, - request: SetLevelRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).set_level(request, context) - } - - fn get_prompt( - &self, - request: GetPromptRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).get_prompt(request, context) - } - - fn list_prompts( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_prompts(request, context) - } - - fn list_resources( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_resources(request, context) - } - - fn list_resource_templates( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_resource_templates(request, context) - } - - fn read_resource( - &self, - request: ReadResourceRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).read_resource(request, context) - } - - fn subscribe( - &self, - request: SubscribeRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).subscribe(request, context) - } - - fn unsubscribe( - &self, - request: UnsubscribeRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).unsubscribe(request, context) - } - - fn call_tool( - &self, - request: CallToolRequestParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).call_tool(request, context) - } - - fn list_tools( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_tools(request, context) - } - - fn on_custom_request( - &self, - request: CustomRequest, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).on_custom_request(request, context) - } - - fn on_cancelled( - &self, - notification: CancelledNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_cancelled(notification, context) - } - - fn on_progress( - &self, - notification: ProgressNotificationParam, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_progress(notification, context) - } - - fn on_initialized( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_initialized(context) - } - - fn on_roots_list_changed( - &self, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_roots_list_changed(context) - } - - fn on_custom_notification( - &self, - notification: CustomNotification, - context: NotificationContext, - ) -> impl Future + Send + '_ { - (**self).on_custom_notification(notification, context) - } - - fn get_info(&self) -> ServerInfo { - (**self).get_info() - } - - fn list_tasks( - &self, - request: Option, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).list_tasks(request, context) - } - - fn get_task_info( - &self, - request: GetTaskInfoParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).get_task_info(request, context) - } - - fn get_task_result( - &self, - request: GetTaskResultParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).get_task_result(request, context) - } - - fn cancel_task( - &self, - request: CancelTaskParam, - context: RequestContext, - ) -> impl Future> + Send + '_ { - (**self).cancel_task(request, context) - } -} +impl_server_handler_for_wrapper!(Box); +impl_server_handler_for_wrapper!(Arc);