Skip to main content

agentic_workflow_mcp/protocol/
mod.rs

1use crate::tools::ToolRegistry;
2use crate::types::{
3    JsonRpcError, JsonRpcRequest, JsonRpcResponse, ServerCapabilities,
4    INTERNAL_ERROR, METHOD_NOT_FOUND,
5};
6
7/// MCP protocol handler.
8pub struct ProtocolHandler {
9    registry: ToolRegistry,
10}
11
12impl ProtocolHandler {
13    pub fn new() -> Self {
14        Self {
15            registry: ToolRegistry::new(),
16        }
17    }
18
19    /// Handle a JSON-RPC request.
20    pub async fn handle_request(&self, request: JsonRpcRequest) -> JsonRpcResponse {
21        match request.method.as_str() {
22            "initialize" => self.handle_initialize(request),
23            "tools/list" => self.handle_tools_list(request),
24            "tools/call" => self.handle_tools_call(request).await,
25            "resources/list" => self.handle_resources_list(request),
26            "prompts/list" => self.handle_prompts_list(request),
27            _ => JsonRpcResponse {
28                jsonrpc: "2.0".to_string(),
29                id: request.id,
30                result: None,
31                error: Some(JsonRpcError {
32                    code: METHOD_NOT_FOUND,
33                    message: format!("Method not found: {}", request.method),
34                    data: None,
35                }),
36            },
37        }
38    }
39
40    fn handle_initialize(&self, request: JsonRpcRequest) -> JsonRpcResponse {
41        let capabilities = ServerCapabilities::default();
42        JsonRpcResponse {
43            jsonrpc: "2.0".to_string(),
44            id: request.id,
45            result: Some(serde_json::json!({
46                "protocolVersion": "2024-11-05",
47                "capabilities": capabilities,
48                "serverInfo": {
49                    "name": "agentic-workflow-mcp",
50                    "version": env!("CARGO_PKG_VERSION")
51                }
52            })),
53            error: None,
54        }
55    }
56
57    fn handle_tools_list(&self, request: JsonRpcRequest) -> JsonRpcResponse {
58        let tools = self.registry.tool_definitions();
59        JsonRpcResponse {
60            jsonrpc: "2.0".to_string(),
61            id: request.id,
62            result: Some(serde_json::json!({ "tools": tools })),
63            error: None,
64        }
65    }
66
67    async fn handle_tools_call(&self, request: JsonRpcRequest) -> JsonRpcResponse {
68        let tool_name = request.params.get("name")
69            .and_then(|v| v.as_str())
70            .unwrap_or("");
71
72        let arguments = request.params.get("arguments")
73            .cloned()
74            .unwrap_or(serde_json::json!({}));
75
76        match self.registry.call_tool(tool_name, arguments).await {
77            Ok(result) => JsonRpcResponse {
78                jsonrpc: "2.0".to_string(),
79                id: request.id,
80                result: Some(serde_json::to_value(result).unwrap_or_default()),
81                error: None,
82            },
83            Err((code, message)) => JsonRpcResponse {
84                jsonrpc: "2.0".to_string(),
85                id: request.id,
86                result: None,
87                error: Some(JsonRpcError {
88                    code,
89                    message,
90                    data: None,
91                }),
92            },
93        }
94    }
95
96    fn handle_resources_list(&self, request: JsonRpcRequest) -> JsonRpcResponse {
97        JsonRpcResponse {
98            jsonrpc: "2.0".to_string(),
99            id: request.id,
100            result: Some(serde_json::json!({ "resources": [] })),
101            error: None,
102        }
103    }
104
105    fn handle_prompts_list(&self, request: JsonRpcRequest) -> JsonRpcResponse {
106        JsonRpcResponse {
107            jsonrpc: "2.0".to_string(),
108            id: request.id,
109            result: Some(serde_json::json!({ "prompts": [] })),
110            error: None,
111        }
112    }
113}
114
115impl Default for ProtocolHandler {
116    fn default() -> Self {
117        Self::new()
118    }
119}