1use crate::auth::AuthInfo;
2use crate::error::SdkResult;
3use crate::schema::{
4 schema_utils::{
5 ClientMessage, McpMessage, MessageFromServer, NotificationFromServer, RequestFromServer,
6 ResultFromClient, ServerMessage,
7 },
8 CreateMessageRequestParams, CreateMessageResult, ElicitRequestParams, ElicitResult,
9 Implementation, InitializeRequestParams, InitializeResult, ListRootsResult, LoggingLevel,
10 LoggingMessageNotificationParams, NotificationParams, ProgressToken, RequestId, RequestParams,
11 ResourceUpdatedNotificationParams, RpcError, ServerCapabilities,
12};
13use crate::task_store::{ClientTaskStore, CreateTaskOptions, ServerTaskStore};
14use async_trait::async_trait;
15use rust_mcp_schema::schema_utils::{
16 ClientTaskResult, CustomNotification, CustomRequest, ServerJsonrpcRequest,
17};
18use rust_mcp_schema::{
19 CancelTaskParams, CancelTaskResult, CancelledNotificationParams, CreateTaskResult,
20 ElicitCompleteParams, GenericResult, GetTaskParams, GetTaskPayloadParams, GetTaskResult,
21 ListTasksResult, PaginatedRequestParams, ProgressNotificationParams,
22 TaskStatusNotificationParams,
23};
24use rust_mcp_transport::SessionId;
25use std::{sync::Arc, time::Duration};
26use tokio::sync::RwLockReadGuard;
27
28#[async_trait]
29pub trait McpServer: Sync + Send {
30 async fn start(self: Arc<Self>) -> SdkResult<()>;
31 async fn set_client_details(&self, client_details: InitializeRequestParams) -> SdkResult<()>;
32 fn server_info(&self) -> &InitializeResult;
33 fn client_info(&self) -> Option<InitializeRequestParams>;
34
35 async fn auth_info(&self) -> RwLockReadGuard<'_, Option<AuthInfo>>;
36 async fn auth_info_cloned(&self) -> Option<AuthInfo>;
37 async fn update_auth_info(&self, auth_info: Option<AuthInfo>);
38
39 async fn wait_for_initialization(&self);
40
41 fn task_store(&self) -> Option<Arc<ServerTaskStore>>;
45
46 fn client_task_store(&self) -> Option<Arc<ClientTaskStore>>;
51
52 fn client_supports_sampling(&self) -> Option<bool> {
64 self.client_info()
65 .map(|client_details| client_details.capabilities.sampling.is_some())
66 }
67
68 fn client_supports_root_list(&self) -> Option<bool> {
80 self.client_info()
81 .map(|client_details| client_details.capabilities.roots.is_some())
82 }
83
84 fn client_supports_experimental(&self) -> Option<bool> {
96 self.client_info()
97 .map(|client_details| client_details.capabilities.experimental.is_some())
98 }
99
100 async fn stderr_message(&self, message: String) -> SdkResult<()>;
102
103 fn session_id(&self) -> Option<SessionId>;
104
105 async fn send(
106 &self,
107 message: MessageFromServer,
108 request_id: Option<RequestId>,
109 request_timeout: Option<Duration>,
110 ) -> SdkResult<Option<ClientMessage>>;
111
112 async fn send_batch(
113 &self,
114 messages: Vec<ServerMessage>,
115 request_timeout: Option<Duration>,
116 ) -> SdkResult<Option<Vec<ClientMessage>>>;
117
118 fn is_initialized(&self) -> bool {
120 self.client_info().is_some()
121 }
122
123 fn client_version(&self) -> Option<Implementation> {
126 self.client_info()
127 .map(|client_details| client_details.client_info)
128 }
129
130 fn capabilities(&self) -> &ServerCapabilities {
132 &self.server_info().capabilities
133 }
134
135 async fn request(
145 &self,
146 request: RequestFromServer,
147 timeout: Option<Duration>,
148 ) -> SdkResult<ResultFromClient> {
149 let request_clone = if request.is_task_augmented() {
151 Some(request.clone())
152 } else {
153 None
154 };
155 let response = self
157 .send(MessageFromServer::RequestFromServer(request), None, timeout)
158 .await?;
159
160 let client_message = response.ok_or_else(|| {
161 RpcError::internal_error()
162 .with_message("An empty response was received from the client.".to_string())
163 })?;
164
165 if client_message.is_error() {
166 return Err(client_message.as_error()?.error.into());
167 }
168
169 let client_response = client_message.as_response()?;
170
171 if let ResultFromClient::CreateTaskResult(create_task_result) = &client_response.result {
175 if let Some(request_to_store) = request_clone {
176 if let Some(client_task_store) = self.client_task_store() {
177 let session_id = self.session_id();
178 client_task_store
179 .create_task(
180 CreateTaskOptions {
181 ttl: create_task_result.task.ttl,
182 poll_interval: create_task_result.task.poll_interval,
183 meta: create_task_result.meta.clone(),
184 },
185 client_response.id.clone(),
186 ServerJsonrpcRequest::new(client_response.id, request_to_store),
187 session_id,
188 )
189 .await;
190 }
191 } else {
192 return Err(RpcError::internal_error()
193 .with_message("No eligible request found for task storage.".to_string())
194 .into());
195 }
196 }
197
198 return Ok(client_response.result);
199 }
200
201 async fn request_elicitation(&self, params: ElicitRequestParams) -> SdkResult<ElicitResult> {
206 let response = self
207 .request(RequestFromServer::ElicitRequest(params), None)
208 .await?;
209 ElicitResult::try_from(response).map_err(|err| err.into())
210 }
211
212 async fn request_elicitation_task(
213 &self,
214 params: ElicitRequestParams,
215 ) -> SdkResult<CreateTaskResult> {
216 if !params.is_task_augmented() {
217 return Err(RpcError::invalid_params()
218 .with_message(
219 "Invalid parameters: the request is not identified as task-augmented."
220 .to_string(),
221 )
222 .into());
223 }
224 let response = self
225 .request(RequestFromServer::ElicitRequest(params), None)
226 .await?;
227
228 let response = CreateTaskResult::try_from(response)?;
229
230 Ok(response)
231 }
232
233 async fn request_root_list(&self, params: Option<RequestParams>) -> SdkResult<ListRootsResult> {
239 let response = self
240 .request(RequestFromServer::ListRootsRequest(params), None)
241 .await?;
242 ListRootsResult::try_from(response).map_err(|err| err.into())
243 }
244
245 async fn ping(
256 &self,
257 params: Option<RequestParams>,
258 timeout: Option<Duration>,
259 ) -> SdkResult<crate::schema::Result> {
260 let response = self
261 .request(RequestFromServer::PingRequest(params), timeout)
262 .await?;
263 Ok(response.try_into()?)
264 }
265
266 async fn request_message_creation(
272 &self,
273 params: CreateMessageRequestParams,
274 ) -> SdkResult<CreateMessageResult> {
275 let response = self
276 .request(RequestFromServer::CreateMessageRequest(params), None)
277 .await?;
278 Ok(response.try_into()?)
279 }
280
281 async fn request_get_task(&self, params: GetTaskParams) -> SdkResult<GetTaskResult> {
283 let response = self
284 .request(RequestFromServer::GetTaskRequest(params), None)
285 .await?;
286 Ok(response.try_into()?)
287 }
288
289 async fn request_get_task_payload(
291 &self,
292 params: GetTaskPayloadParams,
293 ) -> SdkResult<ClientTaskResult> {
294 let response = self
295 .request(RequestFromServer::GetTaskPayloadRequest(params), None)
296 .await?;
297 Ok(response.try_into()?)
298 }
299
300 async fn request_task_cancellation(
302 &self,
303 params: CancelTaskParams,
304 ) -> SdkResult<CancelTaskResult> {
305 let response = self
306 .request(RequestFromServer::CancelTaskRequest(params), None)
307 .await?;
308 Ok(response.try_into()?)
309 }
310
311 async fn request_task_list(
313 &self,
314 params: Option<PaginatedRequestParams>,
315 ) -> SdkResult<ListTasksResult> {
316 let response = self
317 .request(RequestFromServer::ListTasksRequest(params), None)
318 .await?;
319 Ok(response.try_into()?)
320 }
321
322 async fn request_custom(&self, params: CustomRequest) -> SdkResult<GenericResult> {
324 let response = self
325 .request(RequestFromServer::CustomRequest(params), None)
326 .await?;
327 Ok(response.try_into()?)
328 }
329
330 async fn send_notification(&self, notification: NotificationFromServer) -> SdkResult<()> {
338 self.send(
339 MessageFromServer::NotificationFromServer(notification),
340 None,
341 None,
342 )
343 .await?;
344 Ok(())
345 }
346
347 async fn notify_log_message(&self, params: LoggingMessageNotificationParams) -> SdkResult<()> {
350 self.send_notification(NotificationFromServer::LoggingMessageNotification(params))
351 .await
352 }
353
354 async fn notify_prompt_list_changed(
358 &self,
359 params: Option<NotificationParams>,
360 ) -> SdkResult<()> {
361 self.send_notification(NotificationFromServer::PromptListChangedNotification(
362 params,
363 ))
364 .await
365 }
366
367 async fn notify_resource_list_changed(
371 &self,
372 params: Option<NotificationParams>,
373 ) -> SdkResult<()> {
374 self.send_notification(NotificationFromServer::ResourceListChangedNotification(
375 params,
376 ))
377 .await
378 }
379
380 async fn notify_resource_updated(
384 &self,
385 params: ResourceUpdatedNotificationParams,
386 ) -> SdkResult<()> {
387 self.send_notification(NotificationFromServer::ResourceUpdatedNotification(params))
388 .await
389 }
390
391 async fn notify_tool_list_changed(&self, params: Option<NotificationParams>) -> SdkResult<()> {
395 self.send_notification(NotificationFromServer::ToolListChangedNotification(params))
396 .await
397 }
398
399 async fn notify_cancellation(&self, params: CancelledNotificationParams) -> SdkResult<()> {
405 self.send_notification(NotificationFromServer::CancelledNotification(params))
406 .await
407 }
408
409 async fn notify_progress(&self, params: ProgressNotificationParams) -> SdkResult<()> {
411 self.send_notification(NotificationFromServer::ProgressNotification(params))
412 .await
413 }
414
415 async fn report_progress(
428 &self,
429 progress_token: Option<ProgressToken>,
430 progress: f64,
431 total: Option<f64>,
432 message: Option<String>,
433 ) -> SdkResult<()> {
434 let Some(progress_token) = progress_token else {
435 return Ok(());
436 };
437 self.notify_progress(ProgressNotificationParams {
438 progress_token,
439 progress,
440 total,
441 message,
442 meta: None,
443 })
444 .await
445 }
446
447 async fn log_debug(&self, message: String) -> SdkResult<()> {
453 self.notify_log_message(LoggingMessageNotificationParams {
454 level: LoggingLevel::Debug,
455 data: ::serde_json::Value::String(message),
456 logger: None,
457 meta: None,
458 })
459 .await
460 }
461
462 async fn log_info(&self, message: String) -> SdkResult<()> {
464 self.notify_log_message(LoggingMessageNotificationParams {
465 level: LoggingLevel::Info,
466 data: ::serde_json::Value::String(message),
467 logger: None,
468 meta: None,
469 })
470 .await
471 }
472
473 async fn log_warn(&self, message: String) -> SdkResult<()> {
475 self.notify_log_message(LoggingMessageNotificationParams {
476 level: LoggingLevel::Warning,
477 data: ::serde_json::Value::String(message),
478 logger: None,
479 meta: None,
480 })
481 .await
482 }
483
484 async fn log_error(&self, message: String) -> SdkResult<()> {
486 self.notify_log_message(LoggingMessageNotificationParams {
487 level: LoggingLevel::Error,
488 data: ::serde_json::Value::String(message),
489 logger: None,
490 meta: None,
491 })
492 .await
493 }
494
495 async fn notify_task_status(&self, params: TaskStatusNotificationParams) -> SdkResult<()> {
498 self.send_notification(NotificationFromServer::TaskStatusNotification(params))
499 .await
500 }
501
502 async fn notify_elicitation_completed(&self, params: ElicitCompleteParams) -> SdkResult<()> {
504 self.send_notification(NotificationFromServer::ElicitationCompleteNotification(
505 params,
506 ))
507 .await
508 }
509
510 async fn notify_custom(&self, params: CustomNotification) -> SdkResult<()> {
512 self.send_notification(NotificationFromServer::CustomNotification(params))
513 .await
514 }
515
516 #[deprecated(since = "0.8.0", note = "Use `request_root_list()` instead.")]
517 async fn list_roots(&self, params: Option<RequestParams>) -> SdkResult<ListRootsResult> {
518 let response = self
519 .request(RequestFromServer::ListRootsRequest(params), None)
520 .await?;
521 ListRootsResult::try_from(response).map_err(|err| err.into())
522 }
523
524 #[deprecated(since = "0.8.0", note = "Use `request_elicitation()` instead.")]
525 async fn elicit_input(&self, params: ElicitRequestParams) -> SdkResult<ElicitResult> {
526 let response = self
527 .request(RequestFromServer::ElicitRequest(params), None)
528 .await?;
529 ElicitResult::try_from(response).map_err(|err| err.into())
530 }
531
532 #[deprecated(since = "0.8.0", note = "Use `request_message_creation()` instead.")]
533 async fn create_message(
534 &self,
535 params: CreateMessageRequestParams,
536 ) -> SdkResult<CreateMessageResult> {
537 let response = self
538 .request(RequestFromServer::CreateMessageRequest(params), None)
539 .await?;
540 Ok(response.try_into()?)
541 }
542
543 #[deprecated(since = "0.8.0", note = "Use `notify_tool_list_changed()` instead.")]
544 async fn send_tool_list_changed(&self, params: Option<NotificationParams>) -> SdkResult<()> {
545 self.send_notification(NotificationFromServer::ToolListChangedNotification(params))
546 .await
547 }
548
549 #[deprecated(since = "0.8.0", note = "Use `notify_resource_updated()` instead.")]
550 async fn send_resource_updated(
551 &self,
552 params: ResourceUpdatedNotificationParams,
553 ) -> SdkResult<()> {
554 self.send_notification(NotificationFromServer::ResourceUpdatedNotification(params))
555 .await
556 }
557
558 #[deprecated(
559 since = "0.8.0",
560 note = "Use `notify_resource_list_changed()` instead."
561 )]
562 async fn send_resource_list_changed(
563 &self,
564 params: Option<NotificationParams>,
565 ) -> SdkResult<()> {
566 self.send_notification(NotificationFromServer::ResourceListChangedNotification(
567 params,
568 ))
569 .await
570 }
571
572 #[deprecated(since = "0.8.0", note = "Use `notify_prompt_list_changed()` instead.")]
573 async fn send_prompt_list_changed(&self, params: Option<NotificationParams>) -> SdkResult<()> {
574 self.send_notification(NotificationFromServer::PromptListChangedNotification(
575 params,
576 ))
577 .await
578 }
579
580 #[deprecated(since = "0.8.0", note = "Use `notify_log_message()` instead.")]
581 async fn send_logging_message(
582 &self,
583 params: LoggingMessageNotificationParams,
584 ) -> SdkResult<()> {
585 self.send_notification(NotificationFromServer::LoggingMessageNotification(params))
586 .await
587 }
588}