项目简介
'claude-agent-sdk-rs' 是一个Rust语言开发的SDK,用于与Claude Code命令行工具(CLI)进行交互。它不仅提供客户端功能,实现对Claude AI的程序化访问和双向流式通信,还包含了一项独特的能力:在Rust应用程序内部运行“Model Context Protocol (MCP)”服务器,以托管和提供自定义工具给Claude Code CLI使用。这意味着您可以利用Rust的强大性能和类型安全来创建Claude AI可调用的个性化功能。
主要功能点
- 嵌入式MCP工具服务器: 在您的Rust应用中创建并运行轻量级的MCP服务器,用于向Claude AI暴露自定义工具。
- 工具注册与执行: 通过简单的宏定义('tool!'),快速注册自定义函数作为Claude可调用的工具,并处理其调用逻辑。
- JSON-RPC协议支持: SDK内部的MCP服务器遵循JSON-RPC协议,确保与Claude Code CLI的标准化通信。
- 高度可扩展: 允许您以类型安全的方式扩展Claude的功能,集成各种外部服务或业务逻辑。
安装步骤
- Rust环境: 确保您已安装Rust编程语言(版本1.70或更高)。
- Claude Code CLI: 这是一个外部依赖,请按照Claude官方指南安装Claude Code CLI工具(版本2.0.0或更高)。
- API Key: 配置Anthropic API Key,可以设置为环境变量'ANTHROPIC_API_KEY'或通过Claude Code CLI进行配置。
- 添加依赖: 在您的Rust项目的'Cargo.toml'文件中添加'claude-agent-sdk-rs'和'tokio'作为依赖:
或者使用'cargo add'命令:[dependencies] claude-agent-sdk-rs = "0.1" tokio = { version = "1", features = ["full"] }cargo add claude-agent-sdk-rs cargo add tokio --features full
服务器配置
要在您的Rust应用程序中启动一个MCP服务器来托管自定义工具,您需要先定义工具,然后将它们集合成一个SDK MCP服务器实例,最终在Claude客户端配置中引用它。MCP服务器的配置信息将作为Claude客户端启动参数的一部分,由Claude Code CLI(MCP客户端)来解析和连接。
以下是MCP客户端(Claude Code CLI)所需的配置信息格式及参数注释,您的Rust MCP工具服务器将作为其中的'sdk'类型服务器被引用:
{ "mcp_servers": { "your-server-name": { // 您为MCP服务器定义的唯一名称 "type": "sdk" // 表明这是一个SDK内部实现的MCP服务器 // 注意:SDK内部服务器实例本身无法直接序列化到JSON。 // 在实际运行中,Rust SDK会将您的 'SdkMcpServer' 实例 // 传递给内部逻辑,Claude Code CLI通过Rust SDK的控制协议 // 直接与该内部实例通信。因此,这里的JSON配置仅为概念性说明, // 实际Rust代码中是直接构建 'McpServerConfig::Sdk(server)'。 } }, "allowed_tools": [ "mcp__your-server-name__your-tool-1", // 允许Claude Code CLI调用您的自定义工具 "mcp__your-server-name__your-tool-2" // 格式为 mcp__{服务器名称}__{工具名称} ] // 其他ClaudeAgentOptions配置,如model、max_turns、permission_mode等 }
您的Rust代码将通过'create_sdk_mcp_server'函数创建MCP服务器实例,并将其传入'ClaudeAgentOptions':
use claude_agent_sdk_rs::{tool, create_sdk_mcp_server, ToolResult, McpToolResultContent, ClaudeAgentOptions, McpServers}; use serde_json::json; use std::collections::HashMap; // 1. 定义工具的处理逻辑 async fn greet_handler(args: serde_json::Value) -> anyhow::Result<ToolResult> { let name = args["name"].as_str().unwrap_or("World"); Ok(ToolResult { content: vec![McpToolResultContent::Text { text: format!("Hello, {}!", name), }], is_error: false, }) } // 2. 使用 'tool!' 宏创建工具定义 let greet_tool = tool!( "greet", // 工具名称,会出现在 allowed_tools 中 "Greet a user", // 工具描述 json!({ "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] }), // 工具的JSON Schema输入定义 greet_handler // 工具的处理函数 ); // 3. 创建SDK MCP服务器实例 let server_name = "my-rust-tools"; // 您的服务器名称 let server_version = "1.0.0"; let my_mcp_server_instance = create_sdk_mcp_server( server_name, server_version, vec![greet_tool] // 包含所有自定义工具 ); // 4. 将MCP服务器配置到ClaudeAgentOptions let mut mcp_servers_map = HashMap::new(); mcp_servers_map.insert( server_name.to_string(), claude_agent_sdk_rs::McpServerConfig::Sdk(my_mcp_server_instance) ); let options = ClaudeAgentOptions { mcp_servers: McpServers::Dict(mcp_servers_map), // 允许Claude Code CLI调用您的自定义工具 allowed_tools: vec![format!("mcp__{}__{}", server_name, "greet")], permission_mode: Some(claude_agent_sdk_rs::PermissionMode::AcceptEdits), ..Default::default() }; // 接下来,使用这个 'options' 创建 'ClaudeClient' 并进行交互。
基本使用方法
配置好'ClaudeAgentOptions'并创建'ClaudeClient'后,即可连接Claude Code CLI并与您的自定义工具进行交互。Claude AI会根据您的提示和工具定义,在需要时自动调用您提供的工具。
use claude_agent_sdk_rs::{ClaudeClient, ClaudeAgentOptions, McpServers, McpToolResultContent, Message, ContentBlock, tool, create_sdk_mcp_server, ToolResult}; use serde_json::json; use std::collections::HashMap; use futures::StreamExt; // 用于处理异步流 // 定义一个简单的问候工具 async fn greet_handler(args: serde_json::Value) -> anyhow::Result<ToolResult> { let name = args["name"].as_str().unwrap_or("World"); Ok(ToolResult { content: vec![McpToolResultContent::Text { text: format!("Hello, {}!", name), }], is_error: false, }) } #[tokio::main] async fn main() -> anyhow::Result<()> { // 1. 创建自定义工具 let greet_tool = tool!( "greet", "Greet a user by name", json!({"type": "object", "properties": {"name": {"type": "string"}}, "required": ["name"]}), greet_handler ); // 2. 将工具集合到SDK MCP服务器 let server_name = "my-custom-tools"; let my_mcp_server = create_sdk_mcp_server(server_name, "1.0.0", vec![greet_tool]); // 3. 配置Claude客户端,使其知晓并允许使用该MCP服务器及其工具 let mut mcp_servers_map = HashMap::new(); mcp_servers_map.insert(server_name.to_string(), claude_agent_sdk_rs::McpServerConfig::Sdk(my_mcp_server)); let options = ClaudeAgentOptions { mcp_servers: McpServers::Dict(mcp_servers_map), allowed_tools: vec![format!("mcp__{}__{}", server_name, "greet")], permission_mode: Some(claude_agent_sdk_rs::PermissionMode::AcceptEdits), max_turns: Some(5), ..Default::default() }; // 4. 创建并连接Claude客户端 let mut client = ClaudeClient::new(options); client.connect().await?; println!("客户端已连接。"); // 5. 向Claude发送请求,让其使用您的自定义工具 println!("用户: 问候Alice。"); client.query("Greet Alice").await?; // 6. 接收并处理来自Claude的响应 let mut stream = client.receive_response(); while let Some(message) = stream.next().await { match message? { Message::Assistant(msg) => { for block in msg.message.content { if let ContentBlock::Text(text) = block { println!("Claude: {}", text.text); } } } Message::User(user_msg) => { // 工具结果通常作为UserMessage返回 if let Some(content_blocks) = &user_msg.content { for content in content_blocks { if let ContentBlock::ToolResult(result) = content { if let Some(claude_agent_sdk_rs::ToolResultContent::Text(text)) = &result.content { println!("自定义工具 ({}) 返回: {}", result.tool_use_id, text); } } } } } Message::Result(result) => { println!("\n[对话结束] 耗时: {}ms, 成本: ${:.4}\n", result.duration_ms, result.total_cost_usd.unwrap_or(0.0)); } _ => {} } } drop(stream); // 释放对流的借用 // 7. 断开连接 client.disconnect().await?; println!("客户端已断开连接。"); Ok(()) }
信息
分类
开发者工具