1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Example: Using MCP stdio transport
//
// This example demonstrates how to use the MCP transport with stdio communication.
// It spawns an MCP server as a child process and communicates with it over stdin/stdout.
use rs_utcp::UtcpClientInterface;
use serde_json::json;
use std::collections::HashMap;
#[path = "common/mod.rs"]
mod common;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("🚀 MCP Stdio Transport Example\n");
// Example 1: Using MCP stdio with node (if you have an MCP server)
// Uncomment this if you have a real MCP server installed
/*
let client = common::client_from_providers(json!({
"manual_version": "1.0.0",
"utcp_version": "0.3.0",
"allowed_communication_protocols": ["mcp"],
"info": {
"title": "MCP Stdio Demo (Node)",
"version": "1.0.0",
"description": "MCP Stdio Demo Manual (Node)"
},
"tools": [{
"name": "filesystem",
"description": "Filesystem tools from MCP server",
"inputs": { "type": "object" },
"outputs": { "type": "object" },
"tool_call_template": {
"call_template_type": "mcp",
"name": "filesystem",
"command": "node",
"args": ["/path/to/mcp-server/index.js"],
"env_vars": {
"MCP_DEBUG": "1"
}
}
}]
}))
.await?;
*/
// Example 2: Using the example stdio MCP server (Python)
// First, run: python examples/mcp_stdio_server.py
println!("📡 Creating UTCP client with MCP stdio provider");
let client = common::client_from_providers(json!({
"manual_version": "1.0.0",
"utcp_version": "0.3.0",
"allowed_communication_protocols": ["mcp"],
"info": {
"title": "MCP Stdio Demo",
"version": "1.0.0",
"description": "MCP Stdio Demo Manual"
},
"tools": [
{
"name": "add",
"description": "Add two numbers",
"inputs": { "type": "object" },
"outputs": { "type": "object" },
"tool_call_template": {
"call_template_type": "mcp",
"name": "calculator",
"command": "python3",
"args": ["examples/mcp_stdio_server.py"]
}
},
{
"name": "multiply",
"description": "Multiply two numbers",
"inputs": { "type": "object" },
"outputs": { "type": "object" },
"tool_call_template": {
"call_template_type": "mcp",
"name": "calculator",
"command": "python3",
"args": ["examples/mcp_stdio_server.py"]
}
}
]
}))
.await?;
println!("✓ UTCP Client initialized with MCP stdio transport\n");
// List available tools from the stdio MCP server
println!("📋 Listing available tools:");
let tools = client.search_tools("", 10).await?;
for tool in &tools {
println!(" • {}: {}", tool.name, tool.description);
}
// Example 3: Call a tool via stdio
println!("\nâš¡ Calling 'add' tool:");
let mut args = HashMap::new();
args.insert("a".to_string(), json!(5));
args.insert("b".to_string(), json!(3));
let result = client.call_tool("calculator.add", args).await?;
println!(" Result: {}", serde_json::to_string_pretty(&result)?);
// Example 4: Call another tool
println!("\nâš¡ Calling 'multiply' tool:");
let mut args2 = HashMap::new();
args2.insert("a".to_string(), json!(7));
args2.insert("b".to_string(), json!(6));
let result2 = client.call_tool("calculator.multiply", args2).await?;
println!(" Result: {}", serde_json::to_string_pretty(&result2)?);
println!("\n✨ Demo complete!");
println!("\nNote: MCP stdio transport communicates with processes via stdin/stdout");
println!(" This is useful for local tools, sandboxed environments, and");
println!(" language-agnostic tool providers.");
Ok(())
}