rust_mcp_sdk/mcp_runtimes/client_runtime/
mcp_client_runtime.rs1use std::sync::Arc;
2
3use crate::schema::{
4 schema_utils::{
5 ClientMessage, ClientMessages, MessageFromClient, NotificationFromServer,
6 RequestFromServer, ResultFromClient, ServerMessage, ServerMessages,
7 },
8 InitializeRequestParams, RpcError, ServerNotification, ServerRequest,
9};
10use async_trait::async_trait;
11use rust_mcp_transport::Transport;
12
13use crate::{
14 error::SdkResult, mcp_client::ClientHandler, mcp_traits::mcp_handler::McpClientHandler,
15 McpClient,
16};
17
18use super::ClientRuntime;
19
20pub fn create_client(
42 client_details: InitializeRequestParams,
43 transport: impl Transport<
44 ServerMessages,
45 MessageFromClient,
46 ServerMessage,
47 ClientMessages,
48 ClientMessage,
49 >,
50 handler: impl ClientHandler,
51) -> Arc<ClientRuntime> {
52 Arc::new(ClientRuntime::new(
53 client_details,
54 transport,
55 Box::new(ClientInternalHandler::new(Box::new(handler))),
56 ))
57}
58
59struct ClientInternalHandler<H> {
62 handler: H,
63}
64impl ClientInternalHandler<Box<dyn ClientHandler>> {
65 pub fn new(handler: Box<dyn ClientHandler>) -> Self {
66 Self { handler }
67 }
68}
69
70#[async_trait]
73impl McpClientHandler for ClientInternalHandler<Box<dyn ClientHandler>> {
74 async fn handle_request(
76 &self,
77 server_jsonrpc_request: RequestFromServer,
78 runtime: &dyn McpClient,
79 ) -> std::result::Result<ResultFromClient, RpcError> {
80 match server_jsonrpc_request {
81 RequestFromServer::ServerRequest(request) => match request {
82 ServerRequest::PingRequest(ping_request) => self
83 .handler
84 .handle_ping_request(ping_request, runtime)
85 .await
86 .map(|value| value.into()),
87 ServerRequest::CreateMessageRequest(create_message_request) => self
88 .handler
89 .handle_create_message_request(create_message_request, runtime)
90 .await
91 .map(|value| value.into()),
92 ServerRequest::ListRootsRequest(list_roots_request) => self
93 .handler
94 .handle_list_roots_request(list_roots_request, runtime)
95 .await
96 .map(|value| value.into()),
97 #[cfg(feature = "2025_06_18")]
98 ServerRequest::ElicitRequest(elicit_request) => self
99 .handler
100 .handle_elicit_request(elicit_request, runtime)
101 .await
102 .map(|value| value.into()),
103 },
104 RequestFromServer::CustomRequest(custom_request) => self
106 .handler
107 .handle_custom_request(custom_request, runtime)
108 .await
109 .map(|value| value.into()),
110 }
111 }
112
113 async fn handle_error(
115 &self,
116 jsonrpc_error: &RpcError,
117 runtime: &dyn McpClient,
118 ) -> SdkResult<()> {
119 self.handler.handle_error(jsonrpc_error, runtime).await?;
120 Ok(())
121 }
122
123 async fn handle_notification(
125 &self,
126 server_jsonrpc_notification: NotificationFromServer,
127 runtime: &dyn McpClient,
128 ) -> SdkResult<()> {
129 match server_jsonrpc_notification {
130 NotificationFromServer::ServerNotification(server_notification) => {
131 match server_notification {
132 ServerNotification::CancelledNotification(cancelled_notification) => {
133 self.handler
134 .handle_cancelled_notification(cancelled_notification, runtime)
135 .await?;
136 }
137 ServerNotification::ProgressNotification(progress_notification) => {
138 self.handler
139 .handle_progress_notification(progress_notification, runtime)
140 .await?;
141 }
142 ServerNotification::ResourceListChangedNotification(
143 resource_list_changed_notification,
144 ) => {
145 self.handler
146 .handle_resource_list_changed_notification(
147 resource_list_changed_notification,
148 runtime,
149 )
150 .await?;
151 }
152 ServerNotification::ResourceUpdatedNotification(
153 resource_updated_notification,
154 ) => {
155 self.handler
156 .handle_resource_updated_notification(
157 resource_updated_notification,
158 runtime,
159 )
160 .await?;
161 }
162 ServerNotification::PromptListChangedNotification(
163 prompt_list_changed_notification,
164 ) => {
165 self.handler
166 .handle_prompt_list_changed_notification(
167 prompt_list_changed_notification,
168 runtime,
169 )
170 .await?;
171 }
172 ServerNotification::ToolListChangedNotification(
173 tool_list_changed_notification,
174 ) => {
175 self.handler
176 .handle_tool_list_changed_notification(
177 tool_list_changed_notification,
178 runtime,
179 )
180 .await?;
181 }
182 ServerNotification::LoggingMessageNotification(
183 logging_message_notification,
184 ) => {
185 self.handler
186 .handle_logging_message_notification(
187 logging_message_notification,
188 runtime,
189 )
190 .await?;
191 }
192 }
193 }
194 NotificationFromServer::CustomNotification(custom_notification) => {
196 self.handler
197 .handle_custom_notification(custom_notification, runtime)
198 .await?;
199 }
200 }
201 Ok(())
202 }
203
204 async fn handle_process_error(
206 &self,
207 error_message: String,
208 runtime: &dyn McpClient,
209 ) -> SdkResult<()> {
210 self.handler
211 .handle_process_error(error_message, runtime)
212 .await
213 .map_err(|err| err.into())
214 }
215}