rust_mcp_sdk/mcp_runtimes/client_runtime/
mcp_client_runtime_core.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use rust_mcp_schema::{
5    schema_utils::{
6        MessageFromClient, NotificationFromServer, RequestFromServer, ResultFromClient,
7        ServerMessage,
8    },
9    InitializeRequestParams, JsonrpcErrorError,
10};
11use rust_mcp_transport::Transport;
12
13use crate::{
14    error::SdkResult,
15    mcp_handlers::mcp_client_handler_core::ClientHandlerCore,
16    mcp_traits::{mcp_client::MCPClient, mcp_handler::MCPClientHandler},
17};
18
19use super::ClientRuntime;
20
21/// Creates a new MCP client runtime with the specified configuration.
22///
23/// This function initializes a client for (MCP) by accepting , client details, a transport ,
24/// and a handler for client-side logic.
25///
26/// The resulting `ClientRuntime` is wrapped in an `Arc` for shared ownership across threads.
27///
28/// # Arguments
29/// * `client_details` - Client name , version and capabilities.
30/// * `transport` - An implementation of the `Transport` trait facilitating communication with the MCP server.
31/// * `handler` - An implementation of the `ClientHandlerCore` trait that defines the client's
32///   core behavior and response logic.
33///
34/// # Returns
35/// An `Arc<ClientRuntime>` representing the initialized client, enabling shared access and
36/// asynchronous operation.
37///
38/// # Examples
39/// You can find a detailed example of how to use this function in the repository:
40///
41/// [Repository Example](https://github.com/rust-mcp-stack/rust-mcp-sdk/tree/main/examples/simple-mcp-client-core)
42pub fn create_client(
43    client_details: InitializeRequestParams,
44    transport: impl Transport<ServerMessage, MessageFromClient>,
45    handler: impl ClientHandlerCore,
46) -> Arc<ClientRuntime> {
47    Arc::new(ClientRuntime::new(
48        client_details,
49        transport,
50        Box::new(ClientCoreInternalHandler::new(Box::new(handler))),
51    ))
52}
53
54struct ClientCoreInternalHandler<H> {
55    handler: H,
56}
57
58impl ClientCoreInternalHandler<Box<dyn ClientHandlerCore>> {
59    pub fn new(handler: Box<dyn ClientHandlerCore>) -> Self {
60        Self { handler }
61    }
62}
63
64#[async_trait]
65impl MCPClientHandler for ClientCoreInternalHandler<Box<dyn ClientHandlerCore>> {
66    async fn handle_request(
67        &self,
68        server_jsonrpc_request: RequestFromServer,
69        runtime: &dyn MCPClient,
70    ) -> std::result::Result<ResultFromClient, JsonrpcErrorError> {
71        // handle request and get the result
72        self.handler
73            .handle_request(server_jsonrpc_request, runtime)
74            .await
75    }
76
77    async fn handle_error(
78        &self,
79        jsonrpc_error: JsonrpcErrorError,
80        runtime: &dyn MCPClient,
81    ) -> SdkResult<()> {
82        self.handler.handle_error(jsonrpc_error, runtime).await?;
83        Ok(())
84    }
85    async fn handle_notification(
86        &self,
87        server_jsonrpc_notification: NotificationFromServer,
88        runtime: &dyn MCPClient,
89    ) -> SdkResult<()> {
90        // handle notification
91        self.handler
92            .handle_notification(server_jsonrpc_notification, runtime)
93            .await?;
94        Ok(())
95    }
96
97    async fn handle_process_error(
98        &self,
99        error_message: String,
100        runtime: &dyn MCPClient,
101    ) -> SdkResult<()> {
102        self.handler
103            .handle_process_error(error_message, runtime)
104            .await
105            .map_err(|err| err.into())
106    }
107}