use jsonrpsee::async_client::Client; use jsonrpsee::core::client::ClientT; use tokio::process::Child; use stdio_transport::StdioTransport; use crate::rpc_helpers::{NoParams, ToRpcArg}; use crate::stdio_transport; use crate::types::{CallToolRequestParams, InitializeRequestParams, InitializeResult, ListToolsRequestParams, ListToolsResult, Tool}; pub struct McpClient { pub(crate) client: Client, } impl McpClient { async fn initialize(&self, params: InitializeRequestParams) -> Result { let result: InitializeResult = self.client.request("initialize", params.to_rpc()).await?; self.client.notification("notifications/initialized", NoParams).await?; Ok(result) } async fn list_tools(&self) -> Result, anyhow::Error> { let mut tools = vec![]; let result: ListToolsResult = self.client.request("tools/list", NoParams).await?; while let Some(cursor) = result.next_cursor.as_ref() { let result: ListToolsResult = self.client.request("tools/list", ListToolsRequestParams { cursor: Some(cursor.clone()) }.to_rpc()).await?; tools.extend(result.tools); } Ok(tools) } async fn call_tool(&self, params: CallToolRequestParams) -> Result { Ok(self.client.request("tools/call", params.to_rpc()).await?) } }