rs-utcp
Universal Tool Calling Protocol Client for Rust
A powerful, async-first Rust implementation of the Universal Tool Calling Protocol (UTCP)
______________________________________________________________________
🌟 特性
- 🔌 12种通信协议(以前称为传输协议) -HTTP、MCP、WebSocket、gRPC、CLI、GraphQL、TCP、UDP、SSE、WebRTC、HTTP流和基于文本
- 🚀 异步/等待本机 -与Tokio一起构建,用于高性能并发操作
- 📦 配置驱动 -通过自动发现和注册从JSON加载工具提供程序
- 🔍 智能工具发现 -跨所有注册工具的基于标签的语义搜索
- 🤖 LLM集成 -用于AI驱动工作流的内置Codemode编排器
- 🔄 自动迁移 -与UTCP v0.1和v1.0格式无缝兼容
- 📝 OpenAPI支持 -根据OpenAPI 3.0规范自动生成工具
- 🔐 多重认证 -支持API密钥、基本身份验证、OAuth2和自定义身份验证
- 💾 流媒体 -对跨兼容通信协议的流式响应的一流支持
- 🧪 测试良好 -90+测试确保可靠性和正确性
📦 安装
添加 rs-utcp 你的 Cargo.toml:
[dependencies]
rs-utcp = "0.1.8"
tokio = { version = "1.0", features = ["full"] }或使用 cargo add:
cargo add rs-utcp
cargo add tokio --features full🚀 快速开始
基本用法
use rs_utcp::{
config::UtcpClientConfig,
repository::in_memory::InMemoryToolRepository,
tag::tag_search::TagSearchStrategy,
UtcpClient, UtcpClientInterface,
};
use std::{collections::HashMap, sync::Arc};
#[tokio::main]
async fn main() -> anyhow::Result {
// 1. Configure the client
let config = UtcpClientConfig::new()
.with_manual_path("providers.json".into());
// 2. Set up repository and search
let repo = Arc::new(InMemoryToolRepository::new());
let search = Arc::new(TagSearchStrategy::new(repo.clone(), 1.0));
// 3. Create the client
let client = UtcpClient::create(config, repo, search).await?;
// 4. Discover tools
let tools = client.search_tools("weather", 10).await?;
println!("Found {} tools", tools.len());
// 5. Call a tool
let mut args = HashMap::new();
args.insert("city".to_string(), serde_json::json!("London"));
let result = client.call_tool("weather.get_forecast", args).await?;
println!("Result: {}", serde_json::to_string_pretty(&result)?);
Ok(())
}配置文件(providers.json)
{
"manual_version": "1.0.0",
"utcp_version": "0.3.0",
"allowed_communication_protocols": ["http", "mcp"],
"info": {
"title": "Example UTCP Manual",
"version": "1.0.0",
"description": "Manual v1.0 with tools"
},
"tools": [
{
"name": "get_forecast",
"description": "Get current weather for a city",
"inputs": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name" },
"units": { "type": "string", "enum": ["metric", "imperial"] }
},
"required": ["city"]
},
"outputs": { "type": "object" },
"tool_call_template": {
"call_template_type": "http",
"name": "weather_api",
"url": "https://api.weather.example.com/tools",
"http_method": "GET",
"headers": { "Accept": "application/json" }
},
"tags": ["weather", "demo"]
},
{
"name": "read_file",
"description": "Read a text file via MCP stdio",
"inputs": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "File path" }
},
"required": ["path"]
},
"outputs": { "type": "object" },
"tool_call_template": {
"call_template_type": "mcp",
"name": "file_tools",
"command": "python3",
"args": ["mcp_server.py"]
},
"tags": ["mcp", "filesystem"]
}
],
"load_variables_from": [
{
"variable_loader_type": "dotenv",
"env_file_path": ".env"
}
]
}🔌 支持的通信协议
rs utcp支持各种通信协议,每种协议都有完全的异步支持:
生产就绪协议
| 协议 | 描述 | 状态 | 流媒体 |
|---|---|---|---|
| 超文本传输协议 | 带有UTCP清单或OpenAPI的REST API | ✅ 稳定 | ❌ |
| 主控程序 | 模型上下文协议(stdio和SSE) | ✅ 稳定 | ✅ |
| 网页实时通信 | 带信令的P2P数据信道 | ✅ 稳定 | ✅ |
| WebSocket | 实时双向通信 | ✅ 稳定 | ✅ |
| 命令行界面 | 将本地二进制文件作为工具执行 | ✅ 稳定 | ❌ |
| gRPC | 具有TLS和认证元数据的高性能RPC | ✅ 稳定 | ✅ |
| 图查询语言 | 具有类型感知变量的基于查询的工具调用 | ✅ 稳定 | ❌ |
| 上海证券交易所 | 服务器发送的事件 | ✅ 稳定 | ✅ |
| HTTP流 | 流式HTTP响应 | ✅ 稳定 | ✅ |
| 传输控制协议 | 低级套接字传输(框架JSON) | ✅ 稳定 | ✅ |
| 用户数据报协议 | 低级数据报传输 | ✅ 稳定 | ❌ |
| 文本 | 基于文件的工具提供程序(JS/SH/Python.exe) | ✅ 稳定 | ❌ |
💡 例子
带有OpenAPI的HTTP提供程序
use rs_utcp::openapi::OpenApiConverter;
// Automatically convert OpenAPI spec to UTCP tools
let converter = OpenApiConverter::new_from_url(
"https://petstore.swagger.io/v2/swagger.json",
Some("petstore".to_string())
).await?;
let manual = converter.convert();
println!("Discovered {} tools from OpenAPI spec", manual.tools.len());MCP标准提供商
let config = serde_json::json!({
"manual_call_templates": [{
"call_template_type": "mcp",
"name": "calculator",
"command": "python3",
"args": ["calculator_server.py"],
"env_vars": {
"DEBUG": "1"
}
}]
});
let client = create_client_from_config(config).await?;
let result = client.call_tool("calculator.add",
HashMap::from([
("a".to_string(), json!(5)),
("b".to_string(), json!(3))
])
).await?;流媒体工具
// Call a streaming tool
let mut stream = client.call_tool_stream(
"sse_provider.events",
HashMap::new()
).await?;
// Process stream results
while let Some(item) = stream.next().await {
match item {
Ok(value) => println!("Received: {}", value),
Err(e) => eprintln!("Error: {}", e),
}
}
stream.close().await?;WebRTC点对点
WebRTC支持直接对等工具调用:
# Terminal 1: Start WebRTC server with signaling
cargo run --example webrtc_server
# Terminal 2: Connect and call tools
cargo run --example webrtc_client看 examples/webrtc_server/ 为了全面实施。
🤖 代码模式和LLM编排
rs utcp包括一个强大的 编码模式 该功能允许在完全访问已注册工具的情况下动态执行脚本。这非常适合LLM驱动的工作流。
Codemode基础知识
use rs_utcp::plugins::codemode::{CodeModeUtcp, CodeModeArgs};
let codemode = CodeModeUtcp::new(client);
// Execute a Rhai script that calls tools
let script = r#"
let weather = call_tool("weather.get_forecast", #{
"city": "Tokyo"
});
let summary = call_tool("ai.summarize", #{
"text": weather.to_string()
});
summary
"#;
let result = codemode.execute(CodeModeArgs {
code: script.to_string(),
timeout: Some(30_000),
}).await?;
println!("Result: {:?}", result.value);LLM编排
这 CodemodeOrchestrator 提供了一个4步AI驱动的工作流程:
- 决定 -LLM确定是否需要工具
- 选择 -LLM选择相关工具
- 生成 -LLM编写Rhai脚本
- 执行 -脚本在沙盒环境中运行
use rs_utcp::plugins::codemode::CodemodeOrchestrator;
let codemode = Arc::new(CodeModeUtcp::new(client));
let llm_model = Arc::new(YourLLMModel::new());
let orchestrator = CodemodeOrchestrator::new(codemode, llm_model);
// Let the LLM figure out how to accomplish the task
let result = orchestrator
.call_prompt("Get the weather in Paris and summarize it")
.await?;
match result {
Some(value) => println!("LLM completed task: {}", value),
None => println!("No tools needed for this request"),
}请参阅 双子座示例 以实现完整的LLM集成。
代码模式安全
Codemode在 硬化沙箱 具有全面的安全措施:
- ✅ 代码验证 -执行前检查危险图案和尺寸限制
- ✅ 超时强制 -严格的超时(默认5秒,最大30秒)可防止脚本失控
- ✅ 资源限制 -内存、CPU和输出大小限制
- ✅ 沙盒执行 -Rhai脚本与文件系统和操作系统隔离运行
看 安全.md 获取完整的安全文档。
🎯 用例
1. 多协议API网关
从单个统一接口跨HTTP、gRPC和MCP调用工具。
2. LLM代理工具包
为语言模型提供一致的方法来执行工具,无论其实现如何。
3. 微服务编排
使用不同的协议跨异构服务协调呼叫。
4. 插件系统
构建可扩展的应用程序,可以通过配置添加插件。
5. 测试与模拟
轻松交换实现(例如HTTP→ CLI),无需更改代码即可进行测试。
📚 文档
🧪 测试
运行综合测试套件:
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_http_transport
# Run examples
cargo run --example basic_usage
cargo run --example all_providers🏗️ 建筑
┌─────────────────────────────────────────────────────┐
│ UtcpClient │
│ (Unified interface for all tool operations) │
└─────────────────┬───────────────────────────────────┘
│
┌────────┴──────────┐
│ │
┌──────▼──────┐ ┌────────▼────────┐
│ Repository │ │ Communication │
│ │ │ Protocols │
│ - Tools │ │ - HTTP │
│ - Search │ │ - MCP │
└─────────────┘ │ - gRPC │
│ - WebSocket │
│ - CLI │
│ - etc. │
└─────────────────┘关键组件
- UtcpClient -所有操作的主要入口点
- 通信协议注册表 (原名TransportRegistry)-管理所有通信协议的实现
- 调用模板处理程序 -映射的注册表
call_template_type供应商建设者 - 工具库 -存储和索引发现的工具
- 搜索策略 -跨工具的语义搜索
- 编码模式 -脚本执行环境
- 加载器 -配置和提供程序加载
插件注册(自定义协议)
在构建客户端之前,注册新的通信协议并调用模板处理程序:
use std::sync::Arc;
use rs_utcp::call_templates::register_call_template_handler;
use rs_utcp::transports::register_communication_protocol;
fn myproto_template_handler(template: serde_json::Value) -> anyhow::Result {
// normalize/augment the template into a provider config
Ok(template)
}
register_call_template_handler("myproto", myproto_template_handler);
register_communication_protocol("myproto", Arc::new(MyProtocol::new())); // implements CommunicationProtocol🔧 高级配置
认证
{
"manual_call_templates": [{
"call_template_type": "http",
"name": "secure_api",
"url": "https://api.example.com",
"auth": {
"auth_type": "api_key",
"api_key": "${API_KEY}",
"var_name": "X-API-Key",
"location": "header"
}
}]
}环境变量
{
"load_variables_from": [
{
"variable_loader_type": "dotenv",
"env_file_path": ".env"
}
],
"variables": {
"DEFAULT_TIMEOUT": "30000"
}
}协议限制
您可以使用限制手册或提供商允许使用哪些通信协议 allowed_communication_protocols 现场。这提供了一种默认安全机制,除非明确允许,否则工具只能使用自己的协议。
{
"manual_version": "1.0.0",
"info": { "title": "Restricted Manual", "version": "1.0.0" },
"allowed_communication_protocols": ["http", "cli"],
"tools": [
{
"name": "http_tool",
"tool_call_template": {
"call_template_type": "http",
"url": "http://example.com"
}
},
{
"name": "cli_tool",
"tool_call_template": {
"call_template_type": "cli",
"command": "echo"
}
}
]
}如果 allowed_communication_protocols 如果未指定,则默认情况下只允许工具自己的协议类型。尝试使用不允许的协议的工具将在注册过程中被过滤掉,呼叫将无法通过验证。
自定义搜索策略
use rs_utcp::tools::ToolSearchStrategy;
use async_trait::async_trait;
struct MySearchStrategy;
#[async_trait]
impl ToolSearchStrategy for MySearchStrategy {
async fn search_tools(&self, query: &str, limit: usize)
-> anyhow::Result>
{
// Your custom search logic
Ok(vec![])
}
}🤝 贡献
欢迎投稿!以下是您可以提供帮助的方式:
- 发现bug了吗? 打开一个问题
- 有一个功能想法吗? 开始讨论
- 想贡献代码吗? 提交PR
开发设置
# Clone the repository
git clone https://github.com/universal-tool-calling-protocol/rs-utcp.git
cd rs-utcp
# Run tests
cargo test
# Format code
cargo fmt
# Run lints
cargo clippy
# Build all examples
cargo build --examples📜 许可证
根据以下任一方式获得许可:
- Apache许可证,版本2.0(特许通行证 或http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(许可证-麻省理工学院 或http://opensource.org/licenses/MIT)
由您选择。
🙏 致谢
📬 联系与支持
- 问题:
- 讨论:
- UTCP社区: utcp.io
______________________________________________________________________
Made with ❤️ by the UTCP community
