agenterra_rmcp/handler/
client.rs1use crate::{
2 error::Error as McpError,
3 model::*,
4 service::{NotificationContext, RequestContext, RoleClient, Service, ServiceRole},
5};
6
7impl<H: ClientHandler> Service<RoleClient> for H {
8 async fn handle_request(
9 &self,
10 request: <RoleClient as ServiceRole>::PeerReq,
11 context: RequestContext<RoleClient>,
12 ) -> Result<<RoleClient as ServiceRole>::Resp, McpError> {
13 match request {
14 ServerRequest::PingRequest(_) => self.ping(context).await.map(ClientResult::empty),
15 ServerRequest::CreateMessageRequest(request) => self
16 .create_message(request.params, context)
17 .await
18 .map(ClientResult::CreateMessageResult),
19 ServerRequest::ListRootsRequest(_) => self
20 .list_roots(context)
21 .await
22 .map(ClientResult::ListRootsResult),
23 }
24 }
25
26 async fn handle_notification(
27 &self,
28 notification: <RoleClient as ServiceRole>::PeerNot,
29 context: NotificationContext<RoleClient>,
30 ) -> Result<(), McpError> {
31 match notification {
32 ServerNotification::CancelledNotification(notification) => {
33 self.on_cancelled(notification.params, context).await
34 }
35 ServerNotification::ProgressNotification(notification) => {
36 self.on_progress(notification.params, context).await
37 }
38 ServerNotification::LoggingMessageNotification(notification) => {
39 self.on_logging_message(notification.params, context).await
40 }
41 ServerNotification::ResourceUpdatedNotification(notification) => {
42 self.on_resource_updated(notification.params, context).await
43 }
44 ServerNotification::ResourceListChangedNotification(_notification_no_param) => {
45 self.on_resource_list_changed(context).await
46 }
47 ServerNotification::ToolListChangedNotification(_notification_no_param) => {
48 self.on_tool_list_changed(context).await
49 }
50 ServerNotification::PromptListChangedNotification(_notification_no_param) => {
51 self.on_prompt_list_changed(context).await
52 }
53 };
54 Ok(())
55 }
56
57 fn get_info(&self) -> <RoleClient as ServiceRole>::Info {
58 self.get_info()
59 }
60}
61
62#[allow(unused_variables)]
63pub trait ClientHandler: Sized + Send + Sync + 'static {
64 fn ping(
65 &self,
66 context: RequestContext<RoleClient>,
67 ) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
68 std::future::ready(Ok(()))
69 }
70
71 fn create_message(
72 &self,
73 params: CreateMessageRequestParam,
74 context: RequestContext<RoleClient>,
75 ) -> impl Future<Output = Result<CreateMessageResult, McpError>> + Send + '_ {
76 std::future::ready(Err(
77 McpError::method_not_found::<CreateMessageRequestMethod>(),
78 ))
79 }
80
81 fn list_roots(
82 &self,
83 context: RequestContext<RoleClient>,
84 ) -> impl Future<Output = Result<ListRootsResult, McpError>> + Send + '_ {
85 std::future::ready(Ok(ListRootsResult::default()))
86 }
87
88 fn on_cancelled(
89 &self,
90 params: CancelledNotificationParam,
91 context: NotificationContext<RoleClient>,
92 ) -> impl Future<Output = ()> + Send + '_ {
93 std::future::ready(())
94 }
95 fn on_progress(
96 &self,
97 params: ProgressNotificationParam,
98 context: NotificationContext<RoleClient>,
99 ) -> impl Future<Output = ()> + Send + '_ {
100 std::future::ready(())
101 }
102 fn on_logging_message(
103 &self,
104 params: LoggingMessageNotificationParam,
105 context: NotificationContext<RoleClient>,
106 ) -> impl Future<Output = ()> + Send + '_ {
107 std::future::ready(())
108 }
109 fn on_resource_updated(
110 &self,
111 params: ResourceUpdatedNotificationParam,
112 context: NotificationContext<RoleClient>,
113 ) -> impl Future<Output = ()> + Send + '_ {
114 std::future::ready(())
115 }
116 fn on_resource_list_changed(
117 &self,
118 context: NotificationContext<RoleClient>,
119 ) -> impl Future<Output = ()> + Send + '_ {
120 std::future::ready(())
121 }
122 fn on_tool_list_changed(
123 &self,
124 context: NotificationContext<RoleClient>,
125 ) -> impl Future<Output = ()> + Send + '_ {
126 std::future::ready(())
127 }
128 fn on_prompt_list_changed(
129 &self,
130 context: NotificationContext<RoleClient>,
131 ) -> impl Future<Output = ()> + Send + '_ {
132 std::future::ready(())
133 }
134
135 fn get_info(&self) -> ClientInfo {
136 ClientInfo::default()
137 }
138}
139
140impl ClientHandler for () {}
142
143impl ClientHandler for ClientInfo {
145 fn get_info(&self) -> ClientInfo {
146 self.clone()
147 }
148}