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
9pub 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}