async_mcp/
client.rs

1use crate::{
2    protocol::{Protocol, ProtocolBuilder, RequestOptions},
3    transport::Transport,
4    types::{
5        ClientCapabilities, Implementation, InitializeRequest, InitializeResponse,
6        RootCapabilities, LATEST_PROTOCOL_VERSION,
7    },
8};
9
10use anyhow::Result;
11use tracing::debug;
12
13#[derive(Clone)]
14pub struct Client<T: Transport> {
15    protocol: Protocol<T>,
16}
17
18impl<T: Transport> Client<T> {
19    pub fn builder(transport: T) -> ClientBuilder<T> {
20        ClientBuilder::new(transport)
21    }
22
23    pub async fn initialize(&self, client_info: Implementation) -> Result<InitializeResponse> {
24        let request = InitializeRequest {
25            protocol_version: LATEST_PROTOCOL_VERSION.to_string(),
26            capabilities: ClientCapabilities {
27                experimental: Some(serde_json::json!({})),
28                sampling: Some(serde_json::json!({})),
29                roots: Some(RootCapabilities {
30                    list_changed: Some(false),
31                }),
32            },
33            client_info,
34        };
35        let response = self
36            .request(
37                "initialize",
38                Some(serde_json::to_value(request)?),
39                RequestOptions::default(),
40            )
41            .await?;
42        let response: InitializeResponse = serde_json::from_value(response)
43            .map_err(|e| anyhow::anyhow!("Failed to parse response: {}", e))?;
44
45        if response.protocol_version != LATEST_PROTOCOL_VERSION {
46            return Err(anyhow::anyhow!(
47                "Unsupported protocol version: {}",
48                response.protocol_version
49            ));
50        }
51
52        debug!(
53            "Initialized with protocol version: {}",
54            response.protocol_version
55        );
56        self.protocol
57            .notify("notifications/initialized", None)
58            .await?;
59        Ok(response)
60    }
61
62    pub async fn request(
63        &self,
64        method: &str,
65        params: Option<serde_json::Value>,
66        options: RequestOptions,
67    ) -> Result<serde_json::Value> {
68        let response = self.protocol.request(method, params, options).await?;
69        response
70            .result
71            .ok_or_else(|| anyhow::anyhow!("Request failed: {:?}", response.error))
72    }
73
74    pub async fn start(&self) -> Result<()> {
75        self.protocol.listen().await
76    }
77}
78
79pub struct ClientBuilder<T: Transport> {
80    protocol: ProtocolBuilder<T>,
81}
82
83impl<T: Transport> ClientBuilder<T> {
84    pub fn new(transport: T) -> Self {
85        Self {
86            protocol: ProtocolBuilder::new(transport),
87        }
88    }
89
90    pub fn build(self) -> Client<T> {
91        Client {
92            protocol: self.protocol.build(),
93        }
94    }
95}