modelcontextprotocol_server/tools/
mod.rs1use std::collections::HashMap;
3use std::sync::Arc;
4use anyhow::Result;
5use tokio::sync::RwLock;
6use mcp_protocol::types::tool::{Tool, ToolCallResult};
7
8pub type ToolHandler = Arc<dyn Fn(serde_json::Value) -> Result<ToolCallResult> + Send + Sync>;
10
11pub struct ToolManager {
13 tools: Arc<RwLock<HashMap<String, (Tool, ToolHandler)>>>,
14}
15
16impl ToolManager {
17 pub fn new() -> Self {
19 Self {
20 tools: Arc::new(RwLock::new(HashMap::new())),
21 }
22 }
23
24 pub fn register_tool(&self, tool: Tool, handler: impl Fn(serde_json::Value) -> Result<ToolCallResult> + Send + Sync + 'static) {
26 let tools = self.tools.clone();
27 let handler = Arc::new(handler);
28
29 tokio::spawn(async move {
30 let mut tools = tools.write().await;
31 tools.insert(tool.name.clone(), (tool, handler));
32 });
33 }
34
35 pub async fn list_tools(&self) -> Vec<Tool> {
37 let tools = self.tools.read().await;
38 tools.values().map(|(tool, _)| tool.clone()).collect()
39 }
40
41 pub async fn execute_tool(&self, name: &str, arguments: serde_json::Value) -> Result<ToolCallResult> {
43 let tools = self.tools.read().await;
44 let (_, handler) = tools.get(name).ok_or_else(|| anyhow::anyhow!("Tool not found: {}", name))?;
45
46 handler(arguments)
47 }
48}
49
50impl Default for ToolManager {
51 fn default() -> Self {
52 Self::new()
53 }
54}