1#![expect(deprecated)]
3pub mod progress;
4use std::sync::Arc;
5
6use crate::{
7 error::ErrorData as McpError,
8 model::*,
9 service::{
10 MaybeSendFuture, NotificationContext, RequestContext, RoleClient, Service, ServiceRole,
11 },
12};
13
14impl<H: ClientHandler> Service<RoleClient> for H {
15 async fn handle_request(
16 &self,
17 request: <RoleClient as ServiceRole>::PeerReq,
18 context: RequestContext<RoleClient>,
19 ) -> Result<<RoleClient as ServiceRole>::Resp, McpError> {
20 match request {
21 ServerRequest::PingRequest(_) => self.ping(context).await.map(ClientResult::empty),
22 ServerRequest::CreateMessageRequest(request) => self
23 .create_message(request.params, context)
24 .await
25 .map(Box::new)
26 .map(ClientResult::CreateMessageResult),
27 ServerRequest::ListRootsRequest(_) => self
28 .list_roots(context)
29 .await
30 .map(ClientResult::ListRootsResult),
31 ServerRequest::ElicitRequest(request) => self
32 .create_elicitation(request.params, context)
33 .await
34 .map(ClientResult::ElicitResult),
35 ServerRequest::CustomRequest(request) => self
36 .on_custom_request(request, context)
37 .await
38 .map(ClientResult::CustomResult),
39 }
40 }
41
42 async fn handle_notification(
43 &self,
44 notification: <RoleClient as ServiceRole>::PeerNot,
45 context: NotificationContext<RoleClient>,
46 ) -> Result<(), McpError> {
47 match notification {
48 ServerNotification::CancelledNotification(notification) => {
49 self.on_cancelled(notification.params, context).await
50 }
51 ServerNotification::ProgressNotification(notification) => {
52 self.on_progress(notification.params, context).await
53 }
54 ServerNotification::LoggingMessageNotification(notification) => {
55 self.on_logging_message(notification.params, context).await
56 }
57 ServerNotification::ResourceUpdatedNotification(notification) => {
58 self.on_resource_updated(notification.params, context).await
59 }
60 ServerNotification::ResourceListChangedNotification(_notification_no_param) => {
61 self.on_resource_list_changed(context).await
62 }
63 ServerNotification::ToolListChangedNotification(_notification_no_param) => {
64 self.on_tool_list_changed(context).await
65 }
66 ServerNotification::PromptListChangedNotification(_notification_no_param) => {
67 self.on_prompt_list_changed(context).await
68 }
69 ServerNotification::TaskStatusNotification(notification) => {
70 self.on_task_status(notification.params, context).await
71 }
72 ServerNotification::CustomNotification(notification) => {
73 self.on_custom_notification(notification, context).await
74 }
75 };
76 Ok(())
77 }
78
79 fn get_info(&self) -> <RoleClient as ServiceRole>::Info {
80 self.get_info()
81 }
82}
83
84#[allow(unused_variables)]
85pub trait ClientHandler: Sized + Send + Sync + 'static {
86 fn ping(
87 &self,
88 context: RequestContext<RoleClient>,
89 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
90 std::future::ready(Ok(()))
91 }
92
93 fn create_message(
94 &self,
95 params: CreateMessageRequestParams,
96 context: RequestContext<RoleClient>,
97 ) -> impl Future<Output = Result<CreateMessageResult, McpError>> + MaybeSendFuture + '_ {
98 std::future::ready(Err(
99 McpError::method_not_found::<CreateMessageRequestMethod>(),
100 ))
101 }
102
103 fn list_roots(
104 &self,
105 context: RequestContext<RoleClient>,
106 ) -> impl Future<Output = Result<ListRootsResult, McpError>> + MaybeSendFuture + '_ {
107 std::future::ready(Ok(ListRootsResult::default()))
108 }
109
110 fn create_elicitation(
167 &self,
168 request: ElicitRequestParams,
169 context: RequestContext<RoleClient>,
170 ) -> impl Future<Output = Result<ElicitResult, McpError>> + MaybeSendFuture + '_ {
171 let _ = (request, context);
173 std::future::ready(Ok(ElicitResult {
174 action: ElicitationAction::Decline,
175 content: None,
176 meta: None,
177 }))
178 }
179
180 fn on_custom_request(
181 &self,
182 request: CustomRequest,
183 context: RequestContext<RoleClient>,
184 ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
185 let CustomRequest { method, .. } = request;
186 let _ = context;
187 std::future::ready(Err(McpError::new(
188 ErrorCode::METHOD_NOT_FOUND,
189 method,
190 None,
191 )))
192 }
193
194 fn on_cancelled(
195 &self,
196 params: CancelledNotificationParam,
197 context: NotificationContext<RoleClient>,
198 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
199 std::future::ready(())
200 }
201 fn on_progress(
202 &self,
203 params: ProgressNotificationParam,
204 context: NotificationContext<RoleClient>,
205 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
206 std::future::ready(())
207 }
208 fn on_logging_message(
209 &self,
210 params: LoggingMessageNotificationParam,
211 context: NotificationContext<RoleClient>,
212 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
213 std::future::ready(())
214 }
215 fn on_resource_updated(
216 &self,
217 params: ResourceUpdatedNotificationParam,
218 context: NotificationContext<RoleClient>,
219 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
220 std::future::ready(())
221 }
222 fn on_resource_list_changed(
223 &self,
224 context: NotificationContext<RoleClient>,
225 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
226 std::future::ready(())
227 }
228 fn on_tool_list_changed(
229 &self,
230 context: NotificationContext<RoleClient>,
231 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
232 std::future::ready(())
233 }
234 fn on_prompt_list_changed(
235 &self,
236 context: NotificationContext<RoleClient>,
237 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
238 std::future::ready(())
239 }
240
241 fn on_task_status(
242 &self,
243 params: TaskStatusNotificationParam,
244 context: NotificationContext<RoleClient>,
245 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
246 std::future::ready(())
247 }
248 fn on_custom_notification(
249 &self,
250 notification: CustomNotification,
251 context: NotificationContext<RoleClient>,
252 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
253 let _ = (notification, context);
254 std::future::ready(())
255 }
256
257 fn get_info(&self) -> ClientInfo {
258 ClientInfo::default()
259 }
260}
261
262impl ClientHandler for () {}
264
265impl ClientHandler for ClientInfo {
267 fn get_info(&self) -> ClientInfo {
268 self.clone()
269 }
270}
271
272macro_rules! impl_client_handler_for_wrapper {
273 ($wrapper:ident) => {
274 impl<T: ClientHandler> ClientHandler for $wrapper<T> {
275 fn ping(
276 &self,
277 context: RequestContext<RoleClient>,
278 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
279 (**self).ping(context)
280 }
281
282 fn create_message(
283 &self,
284 params: CreateMessageRequestParams,
285 context: RequestContext<RoleClient>,
286 ) -> impl Future<Output = Result<CreateMessageResult, McpError>> + MaybeSendFuture + '_
287 {
288 (**self).create_message(params, context)
289 }
290
291 fn list_roots(
292 &self,
293 context: RequestContext<RoleClient>,
294 ) -> impl Future<Output = Result<ListRootsResult, McpError>> + MaybeSendFuture + '_
295 {
296 (**self).list_roots(context)
297 }
298
299 fn create_elicitation(
300 &self,
301 request: ElicitRequestParams,
302 context: RequestContext<RoleClient>,
303 ) -> impl Future<Output = Result<ElicitResult, McpError>> + MaybeSendFuture + '_ {
304 (**self).create_elicitation(request, context)
305 }
306
307 fn on_custom_request(
308 &self,
309 request: CustomRequest,
310 context: RequestContext<RoleClient>,
311 ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
312 (**self).on_custom_request(request, context)
313 }
314
315 fn on_cancelled(
316 &self,
317 params: CancelledNotificationParam,
318 context: NotificationContext<RoleClient>,
319 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
320 (**self).on_cancelled(params, context)
321 }
322
323 fn on_progress(
324 &self,
325 params: ProgressNotificationParam,
326 context: NotificationContext<RoleClient>,
327 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
328 (**self).on_progress(params, context)
329 }
330
331 fn on_logging_message(
332 &self,
333 params: LoggingMessageNotificationParam,
334 context: NotificationContext<RoleClient>,
335 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
336 (**self).on_logging_message(params, context)
337 }
338
339 fn on_resource_updated(
340 &self,
341 params: ResourceUpdatedNotificationParam,
342 context: NotificationContext<RoleClient>,
343 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
344 (**self).on_resource_updated(params, context)
345 }
346
347 fn on_resource_list_changed(
348 &self,
349 context: NotificationContext<RoleClient>,
350 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
351 (**self).on_resource_list_changed(context)
352 }
353
354 fn on_tool_list_changed(
355 &self,
356 context: NotificationContext<RoleClient>,
357 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
358 (**self).on_tool_list_changed(context)
359 }
360
361 fn on_prompt_list_changed(
362 &self,
363 context: NotificationContext<RoleClient>,
364 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
365 (**self).on_prompt_list_changed(context)
366 }
367
368 fn on_task_status(
369 &self,
370 params: TaskStatusNotificationParam,
371 context: NotificationContext<RoleClient>,
372 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
373 (**self).on_task_status(params, context)
374 }
375
376 fn on_custom_notification(
377 &self,
378 notification: CustomNotification,
379 context: NotificationContext<RoleClient>,
380 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
381 (**self).on_custom_notification(notification, context)
382 }
383
384 fn get_info(&self) -> ClientInfo {
385 (**self).get_info()
386 }
387 }
388 };
389}
390
391impl_client_handler_for_wrapper!(Box);
392impl_client_handler_for_wrapper!(Arc);