Spaces:
Runtime error
Runtime error
| //! Request Handler | |
| //! | |
| //! Shared request handling logic used by both stdio and HTTP transports. | |
| use anyhow::{Context, Result}; | |
| use std::sync::Arc; | |
| use super::protocol::ProtocolHandler; | |
| use super::types::*; | |
| use crate::tools::ToolRegistry; | |
| /// Shared request handler for MCP protocol messages | |
| pub struct RequestHandler { | |
| protocol: ProtocolHandler, | |
| registry: Arc<ToolRegistry>, | |
| } | |
| impl RequestHandler { | |
| /// Create a new request handler | |
| pub fn new(registry: ToolRegistry) -> Self { | |
| Self { | |
| protocol: ProtocolHandler::new(), | |
| registry: Arc::new(registry), | |
| } | |
| } | |
| /// Handle a JSON-RPC request | |
| pub async fn handle_request(&self, request: JsonRpcRequest) -> JsonRpcResponse { | |
| // Validate request | |
| if let Err(e) = self.protocol.validate_request(&request) { | |
| return self.protocol.create_error_response(request.id, e); | |
| } | |
| // Route to appropriate handler | |
| match request.method.as_str() { | |
| "initialize" => self.protocol.handle_initialize(request.id), | |
| "ping" => self.protocol.handle_ping(request.id), | |
| "tools/list" => { | |
| let tools = self.registry.list_tools(); | |
| self.protocol.create_tool_list_response(request.id, tools) | |
| } | |
| "tools/call" => { | |
| match self | |
| .handle_tool_call(request.id.clone(), request.params) | |
| .await | |
| { | |
| Ok(response) => response, | |
| Err(e) => self.protocol.create_error_response(request.id, e), | |
| } | |
| } | |
| _ => { | |
| let error = JsonRpcError::method_not_found(&request.method); | |
| JsonRpcResponse::error(request.id, error) | |
| } | |
| } | |
| } | |
| /// Handle a tool call | |
| async fn handle_tool_call( | |
| &self, | |
| id: RequestId, | |
| params: Option<serde_json::Value>, | |
| ) -> Result<JsonRpcResponse> { | |
| // Parse tool call parameters | |
| let tool_call = self.protocol.parse_tool_call(params)?; | |
| tracing::info!(tool_name = %tool_call.name, "Executing tool"); | |
| // Get the tool | |
| let tool = self | |
| .registry | |
| .get(&tool_call.name) | |
| .ok_or_else(|| anyhow::anyhow!("Tool not found: {}", tool_call.name))?; | |
| // Execute the tool | |
| let result = tool | |
| .execute(tool_call.arguments) | |
| .await | |
| .context("Tool execution failed")?; | |
| // Create response | |
| Ok(self.protocol.create_tool_result_response(id, result)) | |
| } | |
| } | |