Skip to main content

codei_tools/
mcp_tool.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use codei_mcp::{registered_tool_name, McpConnection, McpManager};
5use serde_json::Value;
6
7use crate::{Tool, ToolContext, ToolError, ToolResult};
8
9/// Register all MCP tools from connected servers into the registry.
10pub fn register_mcp_tools(registry: &mut crate::ToolRegistry, manager: &McpManager) {
11    for conn in manager.connections() {
12        for tool in &conn.tools {
13            registry.register(Box::new(McpRegisteredTool {
14                registered_name: registered_tool_name(&conn.server_name, &tool.name),
15                remote_name: tool.name.clone(),
16                description: tool.description.clone(),
17                input_schema: tool.input_schema.clone(),
18                connection: Arc::clone(conn),
19            }));
20        }
21    }
22}
23
24struct McpRegisteredTool {
25    registered_name: String,
26    remote_name: String,
27    description: String,
28    input_schema: Value,
29    connection: Arc<McpConnection>,
30}
31
32#[async_trait]
33impl Tool for McpRegisteredTool {
34    fn name(&self) -> &str {
35        &self.registered_name
36    }
37
38    fn description(&self) -> &str {
39        &self.description
40    }
41
42    fn parameters_schema(&self) -> Value {
43        self.input_schema.clone()
44    }
45
46    async fn execute(&self, _ctx: &ToolContext, args: Value) -> Result<ToolResult, ToolError> {
47        let result = self
48            .connection
49            .call_tool(&self.remote_name, args)
50            .await
51            .map_err(|err| ToolError::Failed {
52                name: self.registered_name.clone(),
53                message: err.to_string(),
54            })?;
55        Ok(ToolResult {
56            content: result.text(),
57            is_error: result.is_error,
58        })
59    }
60}