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::SubscriptionsAcknowledgedNotification(notification) => {
70 self.on_subscriptions_acknowledged(notification.params, context)
71 .await
72 }
73 ServerNotification::TaskStatusNotification(notification) => {
74 self.on_task_status(notification.params, context).await
75 }
76 ServerNotification::CustomNotification(notification) => {
77 self.on_custom_notification(notification, context).await
78 }
79 };
80 Ok(())
81 }
82
83 fn get_info(&self) -> <RoleClient as ServiceRole>::Info {
84 self.get_info()
85 }
86}
87
88macro_rules! client_handler_methods {
89 () => {
90 fn ping(
91 &self,
92 context: RequestContext<RoleClient>,
93 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
94 std::future::ready(Ok(()))
95 }
96
97 fn create_message(
98 &self,
99 params: CreateMessageRequestParams,
100 context: RequestContext<RoleClient>,
101 ) -> impl Future<Output = Result<CreateMessageResult, McpError>> + MaybeSendFuture + '_ {
102 std::future::ready(Err(
103 McpError::method_not_found::<CreateMessageRequestMethod>(),
104 ))
105 }
106
107 fn list_roots(
108 &self,
109 context: RequestContext<RoleClient>,
110 ) -> impl Future<Output = Result<ListRootsResult, McpError>> + MaybeSendFuture + '_ {
111 std::future::ready(Ok(ListRootsResult::default()))
112 }
113
114 fn create_elicitation(
180 &self,
181 request: ElicitRequestParams,
182 context: RequestContext<RoleClient>,
183 ) -> impl Future<Output = Result<ElicitResult, McpError>> + MaybeSendFuture + '_ {
184 let _ = (request, context);
186 std::future::ready(Ok(ElicitResult {
187 action: ElicitationAction::Decline,
188 content: None,
189 meta: None,
190 }))
191 }
192
193 fn on_custom_request(
194 &self,
195 request: CustomRequest,
196 context: RequestContext<RoleClient>,
197 ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
198 let CustomRequest { method, .. } = request;
199 let _ = context;
200 std::future::ready(Err(McpError::new(
201 ErrorCode::METHOD_NOT_FOUND,
202 method,
203 None,
204 )))
205 }
206
207 fn on_cancelled(
208 &self,
209 params: CancelledNotificationParam,
210 context: NotificationContext<RoleClient>,
211 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
212 std::future::ready(())
213 }
214 fn on_progress(
215 &self,
216 params: ProgressNotificationParam,
217 context: NotificationContext<RoleClient>,
218 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
219 std::future::ready(())
220 }
221 fn on_logging_message(
222 &self,
223 params: LoggingMessageNotificationParam,
224 context: NotificationContext<RoleClient>,
225 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
226 std::future::ready(())
227 }
228 fn on_resource_updated(
229 &self,
230 params: ResourceUpdatedNotificationParam,
231 context: NotificationContext<RoleClient>,
232 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
233 std::future::ready(())
234 }
235 fn on_resource_list_changed(
236 &self,
237 context: NotificationContext<RoleClient>,
238 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
239 std::future::ready(())
240 }
241 fn on_tool_list_changed(
242 &self,
243 context: NotificationContext<RoleClient>,
244 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
245 std::future::ready(())
246 }
247 fn on_prompt_list_changed(
248 &self,
249 context: NotificationContext<RoleClient>,
250 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
251 std::future::ready(())
252 }
253 fn on_subscriptions_acknowledged(
254 &self,
255 params: SubscriptionsAcknowledgedNotificationParams,
256 context: NotificationContext<RoleClient>,
257 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
258 std::future::ready(())
259 }
260
261 fn on_task_status(
262 &self,
263 params: TaskStatusNotificationParams,
264 context: NotificationContext<RoleClient>,
265 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
266 std::future::ready(())
267 }
268 fn on_custom_notification(
269 &self,
270 notification: CustomNotification,
271 context: NotificationContext<RoleClient>,
272 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
273 let _ = (notification, context);
274 std::future::ready(())
275 }
276
277 fn get_info(&self) -> ClientInfo {
278 ClientInfo::default()
279 }
280 };
281}
282
283#[allow(unused_variables)]
284#[cfg(not(feature = "local"))]
285pub trait ClientHandler: Sized + Send + Sync + 'static {
286 client_handler_methods!();
287}
288
289#[allow(unused_variables)]
290#[cfg(feature = "local")]
291pub trait ClientHandler: Sized + 'static {
292 client_handler_methods!();
293}
294
295impl ClientHandler for () {}
297
298impl ClientHandler for ClientInfo {
300 fn get_info(&self) -> ClientInfo {
301 self.clone()
302 }
303}
304
305macro_rules! impl_client_handler_for_wrapper {
306 ($wrapper:ident) => {
307 impl<T: ClientHandler> ClientHandler for $wrapper<T> {
308 fn ping(
309 &self,
310 context: RequestContext<RoleClient>,
311 ) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
312 (**self).ping(context)
313 }
314
315 fn create_message(
316 &self,
317 params: CreateMessageRequestParams,
318 context: RequestContext<RoleClient>,
319 ) -> impl Future<Output = Result<CreateMessageResult, McpError>> + MaybeSendFuture + '_
320 {
321 (**self).create_message(params, context)
322 }
323
324 fn list_roots(
325 &self,
326 context: RequestContext<RoleClient>,
327 ) -> impl Future<Output = Result<ListRootsResult, McpError>> + MaybeSendFuture + '_
328 {
329 (**self).list_roots(context)
330 }
331
332 fn create_elicitation(
333 &self,
334 request: ElicitRequestParams,
335 context: RequestContext<RoleClient>,
336 ) -> impl Future<Output = Result<ElicitResult, McpError>> + MaybeSendFuture + '_ {
337 (**self).create_elicitation(request, context)
338 }
339
340 fn on_custom_request(
341 &self,
342 request: CustomRequest,
343 context: RequestContext<RoleClient>,
344 ) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
345 (**self).on_custom_request(request, context)
346 }
347
348 fn on_cancelled(
349 &self,
350 params: CancelledNotificationParam,
351 context: NotificationContext<RoleClient>,
352 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
353 (**self).on_cancelled(params, context)
354 }
355
356 fn on_progress(
357 &self,
358 params: ProgressNotificationParam,
359 context: NotificationContext<RoleClient>,
360 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
361 (**self).on_progress(params, context)
362 }
363
364 fn on_logging_message(
365 &self,
366 params: LoggingMessageNotificationParam,
367 context: NotificationContext<RoleClient>,
368 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
369 (**self).on_logging_message(params, context)
370 }
371
372 fn on_resource_updated(
373 &self,
374 params: ResourceUpdatedNotificationParam,
375 context: NotificationContext<RoleClient>,
376 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
377 (**self).on_resource_updated(params, context)
378 }
379
380 fn on_resource_list_changed(
381 &self,
382 context: NotificationContext<RoleClient>,
383 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
384 (**self).on_resource_list_changed(context)
385 }
386
387 fn on_tool_list_changed(
388 &self,
389 context: NotificationContext<RoleClient>,
390 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
391 (**self).on_tool_list_changed(context)
392 }
393
394 fn on_prompt_list_changed(
395 &self,
396 context: NotificationContext<RoleClient>,
397 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
398 (**self).on_prompt_list_changed(context)
399 }
400
401 fn on_subscriptions_acknowledged(
402 &self,
403 params: SubscriptionsAcknowledgedNotificationParams,
404 context: NotificationContext<RoleClient>,
405 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
406 (**self).on_subscriptions_acknowledged(params, context)
407 }
408
409 fn on_task_status(
410 &self,
411 params: TaskStatusNotificationParams,
412 context: NotificationContext<RoleClient>,
413 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
414 (**self).on_task_status(params, context)
415 }
416
417 fn on_custom_notification(
418 &self,
419 notification: CustomNotification,
420 context: NotificationContext<RoleClient>,
421 ) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
422 (**self).on_custom_notification(notification, context)
423 }
424
425 fn get_info(&self) -> ClientInfo {
426 (**self).get_info()
427 }
428 }
429 };
430}
431
432impl_client_handler_for_wrapper!(Box);
433impl_client_handler_for_wrapper!(Arc);