stdio_integration/
stdio_integration.rs

1// This example shows how to use the mcp-client crate to interact with a server that has a simple counter tool.
2// The server is started by running `cargo run -p mcp-server` in the root of the mcp-server crate.
3use anyhow::Result;
4use mcp_client::client::{
5    ClientCapabilities, ClientInfo, Error as ClientError, McpClient, McpClientTrait,
6};
7use mcp_client::transport::{StdioTransport, Transport};
8use mcp_client::McpService;
9use std::collections::HashMap;
10use std::time::Duration;
11use tracing_subscriber::EnvFilter;
12
13#[tokio::main]
14async fn main() -> Result<(), ClientError> {
15    // Initialize logging
16    tracing_subscriber::fmt()
17        .with_env_filter(
18            EnvFilter::from_default_env()
19                .add_directive("mcp_client=debug".parse().unwrap())
20                .add_directive("eventsource_client=debug".parse().unwrap()),
21        )
22        .init();
23
24    // Create the transport
25    let transport = StdioTransport::new(
26        "cargo",
27        vec!["run", "-p", "mcp-server"]
28            .into_iter()
29            .map(|s| s.to_string())
30            .collect(),
31        HashMap::new(),
32    );
33
34    // Start the transport to get a handle
35    let transport_handle = transport.start().await.unwrap();
36
37    // Create the service with timeout middleware
38    let service = McpService::with_timeout(transport_handle, Duration::from_secs(10));
39
40    // Create client
41    let mut client = McpClient::new(service);
42
43    // Initialize
44    let server_info = client
45        .initialize(
46            ClientInfo {
47                name: "test-client".into(),
48                version: "1.0.0".into(),
49            },
50            ClientCapabilities::default(),
51        )
52        .await?;
53    println!("Connected to server: {server_info:?}\n");
54
55    // List tools
56    let tools = client.list_tools(None).await?;
57    println!("Available tools: {tools:?}\n");
58
59    // Call tool 'increment' tool 3 times
60    for _ in 0..3 {
61        let increment_result = client.call_tool("increment", serde_json::json!({})).await?;
62        println!("Tool result for 'increment': {increment_result:?}\n");
63    }
64
65    // Call tool 'get_value'
66    let get_value_result = client.call_tool("get_value", serde_json::json!({})).await?;
67    println!("Tool result for 'get_value': {get_value_result:?}\n");
68
69    // Call tool 'decrement' once
70    let decrement_result = client.call_tool("decrement", serde_json::json!({})).await?;
71    println!("Tool result for 'decrement': {decrement_result:?}\n");
72
73    // Call tool 'get_value'
74    let get_value_result = client.call_tool("get_value", serde_json::json!({})).await?;
75    println!("Tool result for 'get_value': {get_value_result:?}\n");
76
77    // List resources
78    let resources = client.list_resources(None).await?;
79    println!("Resources: {resources:?}\n");
80
81    // Read resource
82    let resource = client.read_resource("memo://insights").await?;
83    println!("Resource: {resource:?}\n");
84
85    let prompts = client.list_prompts(None).await?;
86    println!("Prompts: {prompts:?}\n");
87
88    let prompt = client
89        .get_prompt(
90            "example_prompt",
91            serde_json::json!({"message": "hello there!"}),
92        )
93        .await?;
94    println!("Prompt: {prompt:?}\n");
95
96    Ok(())
97}