json_mcp_server/mcp/
server.rs

1use crate::json_tools::handler::JsonToolsHandler;
2use crate::mcp::protocol::{MCPRequest, MCPResponse, Tool, ToolCall, ToolResult};
3use serde_json::{json, Value};
4use std::collections::HashMap;
5use tracing::{debug, error};
6
7#[async_trait::async_trait]
8pub trait ToolHandler {
9    async fn get_tools(&self) -> anyhow::Result<Vec<Tool>>;
10    async fn call_tool(&self, tool_call: ToolCall) -> anyhow::Result<ToolResult>;
11}
12
13pub struct MCPServer {
14    tools: HashMap<String, Tool>,
15    handler: JsonToolsHandler,
16}
17
18impl MCPServer {
19    pub fn new(handler: JsonToolsHandler) -> Self {
20        Self {
21            tools: HashMap::new(),
22            handler,
23        }
24    }
25
26    pub async fn register_tools(&mut self) -> anyhow::Result<()> {
27        let tools = self.handler.get_tools().await?;
28        for tool in tools {
29            self.tools.insert(tool.name.clone(), tool);
30        }
31        Ok(())
32    }
33
34    pub async fn handle_request(&self, input: &str) -> anyhow::Result<String> {
35        debug!("Handling request: {}", input);
36
37        let request: MCPRequest = serde_json::from_str(input)?;
38
39        let response = match request.method.as_str() {
40            "tools/list" => {
41                let tools: Vec<&Tool> = self.tools.values().collect();
42                MCPResponse::success(request.id, json!({ "tools": tools }))
43            }
44            "tools/call" => {
45                if let Some(params) = request.params {
46                    match self.handle_tool_call(params).await {
47                        Ok(result) => MCPResponse::success(request.id, json!(result)),
48                        Err(e) => {
49                            error!("Tool call failed: {}", e);
50                            MCPResponse::error(request.id, -32603, &format!("Tool call failed: {}", e))
51                        }
52                    }
53                } else {
54                    MCPResponse::error(request.id, -32602, "Missing params for tool call")
55                }
56            }
57            "initialize" => {
58                let capabilities = json!({
59                    "tools": {},
60                    "logging": {},
61                    "prompts": {},
62                    "resources": {}
63                });
64                MCPResponse::success(request.id, json!({
65                    "protocolVersion": "2024-11-05",
66                    "capabilities": capabilities,
67                    "serverInfo": {
68                        "name": "json-mcp-server",
69                        "version": "0.1.0"
70                    }
71                }))
72            }
73            "initialized" => {
74                // Notification - no response needed, but we'll send success
75                MCPResponse::success(request.id, json!({}))
76            }
77            _ => MCPResponse::error(request.id, -32601, "Method not found"),
78        };
79
80        Ok(serde_json::to_string(&response)?)
81    }
82
83    async fn handle_tool_call(&self, params: Value) -> anyhow::Result<ToolResult> {
84        let tool_call: ToolCall = serde_json::from_value(params)?;
85
86        if !self.tools.contains_key(&tool_call.name) {
87            return Ok(ToolResult::error(format!("Unknown tool: {}", tool_call.name)));
88        }
89
90        self.handler.call_tool(tool_call).await
91    }
92}