mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-17 22:24:21 +01:00
Co-authored-by: Michael Neale <michael.neale@gmail.com> Co-authored-by: Wendy Tang <wendytang@squareup.com> Co-authored-by: Jarrod Sibbison <72240382+jsibbison-square@users.noreply.github.com> Co-authored-by: Alex Hancock <alex.hancock@example.com> Co-authored-by: Alex Hancock <alexhancock@block.xyz> Co-authored-by: Lifei Zhou <lifei@squareup.com> Co-authored-by: Wes <141185334+wesrblock@users.noreply.github.com> Co-authored-by: Max Novich <maksymstepanenko1990@gmail.com> Co-authored-by: Zaki Ali <zaki@squareup.com> Co-authored-by: Salman Mohammed <smohammed@squareup.com> Co-authored-by: Kalvin C <kalvinnchau@users.noreply.github.com> Co-authored-by: Alec Thomas <alec@swapoff.org> Co-authored-by: lily-de <119957291+lily-de@users.noreply.github.com> Co-authored-by: kalvinnchau <kalvin@block.xyz> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Rizel Scarlett <rizel@squareup.com> Co-authored-by: bwrage <bwrage@squareup.com> Co-authored-by: Kalvin Chau <kalvin@squareup.com> Co-authored-by: Alice Hau <110418948+ahau-square@users.noreply.github.com> Co-authored-by: Alistair Gray <ajgray@stripe.com> Co-authored-by: Nahiyan Khan <nahiyan.khan@gmail.com> Co-authored-by: Alex Hancock <alexhancock@squareup.com> Co-authored-by: Nahiyan Khan <nahiyan@squareup.com> Co-authored-by: marcelle <1852848+laanak08@users.noreply.github.com> Co-authored-by: Yingjie He <yingjiehe@block.xyz> Co-authored-by: Yingjie He <yingjiehe@squareup.com> Co-authored-by: Lily Delalande <ldelalande@block.xyz> Co-authored-by: Adewale Abati <acekyd01@gmail.com> Co-authored-by: Ebony Louis <ebony774@gmail.com> Co-authored-by: Angie Jones <jones.angie@gmail.com> Co-authored-by: Ebony Louis <55366651+EbonyLouis@users.noreply.github.com>
132 lines
5.1 KiB
Rust
132 lines
5.1 KiB
Rust
use mcp_client::{
|
|
client::{ClientCapabilities, ClientInfo, McpClient, McpClientTrait},
|
|
transport::{SseTransport, StdioTransport, Transport},
|
|
McpService,
|
|
};
|
|
use rand::Rng;
|
|
use rand::SeedableRng;
|
|
use std::time::Duration;
|
|
use std::{collections::HashMap, sync::Arc};
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Initialize logging
|
|
tracing_subscriber::fmt()
|
|
.with_env_filter(
|
|
EnvFilter::from_default_env().add_directive("mcp_client=debug".parse().unwrap()),
|
|
)
|
|
.init();
|
|
|
|
let transport1 = StdioTransport::new("uvx", vec!["mcp-server-git".to_string()], HashMap::new());
|
|
let handle1 = transport1.start().await?;
|
|
let service1 = McpService::with_timeout(handle1, Duration::from_secs(30));
|
|
let client1 = McpClient::new(service1);
|
|
|
|
let transport2 = StdioTransport::new("uvx", vec!["mcp-server-git".to_string()], HashMap::new());
|
|
let handle2 = transport2.start().await?;
|
|
let service2 = McpService::with_timeout(handle2, Duration::from_secs(30));
|
|
let client2 = McpClient::new(service2);
|
|
|
|
let transport3 = SseTransport::new("http://localhost:8000/sse", HashMap::new());
|
|
let handle3 = transport3.start().await?;
|
|
let service3 = McpService::with_timeout(handle3, Duration::from_secs(10));
|
|
let client3 = McpClient::new(service3);
|
|
|
|
// Initialize both clients
|
|
let mut clients: Vec<Box<dyn McpClientTrait>> =
|
|
vec![Box::new(client1), Box::new(client2), Box::new(client3)];
|
|
|
|
// Initialize all clients
|
|
for (i, client) in clients.iter_mut().enumerate() {
|
|
let info = ClientInfo {
|
|
name: format!("example-client-{}", i + 1),
|
|
version: "1.0.0".to_string(),
|
|
};
|
|
let capabilities = ClientCapabilities::default();
|
|
|
|
println!("\nInitializing client {}", i + 1);
|
|
let init_result = client.initialize(info, capabilities).await?;
|
|
println!("Client {} initialized: {:?}", i + 1, init_result);
|
|
}
|
|
|
|
// List tools for all clients
|
|
for (i, client) in clients.iter_mut().enumerate() {
|
|
let tools = client.list_tools(None).await?;
|
|
println!("\nClient {} tools: {:?}", i + 1, tools);
|
|
}
|
|
|
|
println!("\n\n----------------------------------\n\n");
|
|
|
|
// Wrap clients in Arc before spawning tasks
|
|
let clients = Arc::new(clients);
|
|
let mut handles = vec![];
|
|
|
|
for i in 0..20 {
|
|
let clients = Arc::clone(&clients);
|
|
let handle = tokio::spawn(async move {
|
|
// let mut rng = rand::thread_rng();
|
|
let mut rng = rand::rngs::StdRng::from_entropy();
|
|
tokio::time::sleep(Duration::from_millis(rng.gen_range(5..50))).await;
|
|
|
|
// Randomly select an operation
|
|
match rng.gen_range(0..4) {
|
|
0 => {
|
|
println!("\n{i}: Listing tools for client 1 (stdio)");
|
|
match clients[0].list_tools(None).await {
|
|
Ok(tools) => {
|
|
println!(" {i}: -> Got tools, first one: {:?}", tools.tools.first())
|
|
}
|
|
Err(e) => println!(" {i}: -> Error: {}", e),
|
|
}
|
|
}
|
|
1 => {
|
|
println!("\n{i}: Calling tool for client 2 (stdio)");
|
|
match clients[1]
|
|
.call_tool("git_status", serde_json::json!({ "repo_path": "." }))
|
|
.await
|
|
{
|
|
Ok(result) => println!(
|
|
" {i}: -> Tool execution result, is_error: {:?}",
|
|
result.is_error
|
|
),
|
|
Err(e) => println!(" {i}: -> Error: {}", e),
|
|
}
|
|
}
|
|
2 => {
|
|
println!("\n{i}: Listing tools for client 3 (sse)");
|
|
match clients[2].list_tools(None).await {
|
|
Ok(tools) => {
|
|
println!(" {i}: -> Got tools, first one: {:?}", tools.tools.first())
|
|
}
|
|
Err(e) => println!(" {i}: -> Error: {}", e),
|
|
}
|
|
}
|
|
3 => {
|
|
println!("\n{i}: Calling tool for client 3 (sse)");
|
|
match clients[2]
|
|
.call_tool(
|
|
"echo_tool",
|
|
serde_json::json!({ "message": "Client with SSE transport - calling a tool" }),
|
|
)
|
|
.await
|
|
{
|
|
Ok(result) => println!(" {i}: -> Tool execution result, is_error: {:?}", result.is_error),
|
|
Err(e) => println!(" {i}: -> Error: {}", e),
|
|
}
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
|
|
});
|
|
handles.push(handle);
|
|
}
|
|
|
|
// Wait for all tasks to complete
|
|
for handle in handles {
|
|
handle.await.unwrap().unwrap();
|
|
}
|
|
|
|
Ok(())
|
|
}
|