Skip to main content

agent_engine/mcp/
tool.rs

1//! McpTool — bridges an MCP server tool into the native Tool trait.
2use crate::{Result, RuntimeError, Tool, ToolContext};
3use serde_json::Value;
4use std::sync::Arc;
5use tokio::sync::Mutex;
6
7use super::connection::McpConnection;
8
9/// A dynamic tool backed by an MCP server connection.
10/// The connection is shared (Arc<Mutex<>>) across all tools from the same server.
11pub struct McpTool {
12    pub(super) tool_name: String,
13    /// Original tool name as the MCP server knows it (without prefix).
14    pub(super) server_tool_name: String,
15    pub(super) server_name: String,
16    pub(super) description: String,
17    pub(super) input_schema: Value,
18    pub(super) connection: Arc<Mutex<McpConnection>>,
19}
20
21#[async_trait::async_trait]
22impl Tool for McpTool {
23    fn origin(&self) -> crate::tools::ToolOrigin {
24        crate::tools::ToolOrigin::Mcp {
25            server_id: self.server_name.clone(),
26            server_tool_name: self.server_tool_name.clone(),
27        }
28    }
29
30    fn name(&self) -> &str {
31        &self.tool_name
32    }
33
34    fn description(&self) -> &str {
35        &self.description
36    }
37
38    fn parameters(&self) -> Value {
39        self.input_schema.clone()
40    }
41
42    async fn execute(&self, params: Value, _ctx: ToolContext) -> Result<String> {
43        let mut conn = self.connection.lock().await;
44        conn.call_tool(&self.server_tool_name, params)
45            .await
46            .map_err(|e| {
47                RuntimeError::Tool(format!(
48                    "MCP tool '{}' (server '{}') failed: {}",
49                    self.tool_name, self.server_name, e
50                ))
51            })
52    }
53}