gamecode_mcp2/
handlers.rs1use anyhow::Result;
5use serde_json::Value;
6use tracing::{debug, error, info};
7
8use crate::protocol::*;
9use crate::tools::ToolManager;
10
11pub struct RequestHandler {
12 tool_manager: ToolManager,
13}
14
15impl RequestHandler {
16 pub fn new(tool_manager: ToolManager) -> Self {
17 Self { tool_manager }
18 }
19
20 pub async fn handle_request(&self, request: JsonRpcRequest) -> JsonRpcResponse {
22 debug!("Handling request: {} (id: {})", request.method, request.id);
23
24 let result = match request.method.as_str() {
25 "initialize" => self.handle_initialize(request.params).await,
26 "tools/list" => self.handle_tools_list().await,
27 "tools/call" => self.handle_tools_call(request.params).await,
28 _ => Err(JsonRpcError {
29 code: METHOD_NOT_FOUND,
30 message: format!("Method '{}' not found", request.method),
31 data: None,
32 }),
33 };
34
35 match result {
36 Ok(value) => JsonRpcResponse {
37 jsonrpc: "2.0".to_string(),
38 id: request.id,
39 result: Some(value),
40 error: None,
41 },
42 Err(error) => JsonRpcResponse {
43 jsonrpc: "2.0".to_string(),
44 id: request.id,
45 result: None,
46 error: Some(error),
47 },
48 }
49 }
50
51 pub async fn handle_notification(&self, notification: JsonRpcNotification) {
52 debug!("Handling notification: {}", notification.method);
53
54 match notification.method.as_str() {
55 "notifications/initialized" => {
56 info!("Client initialized");
57 }
58 "notifications/cancelled" => {
59 info!("Request cancelled");
60 }
61 _ => {
62 debug!("Unknown notification: {}", notification.method);
63 }
64 }
65 }
66
67 async fn handle_initialize(&self, params: Option<Value>) -> Result<Value, JsonRpcError> {
69 let _params: InitializeParams = if let Some(p) = params {
70 serde_json::from_value(p).map_err(|e| JsonRpcError {
71 code: INVALID_PARAMS,
72 message: format!("Invalid initialize params: {}", e),
73 data: None,
74 })?
75 } else {
76 return Err(JsonRpcError {
77 code: INVALID_PARAMS,
78 message: "Missing initialize params".to_string(),
79 data: None,
80 });
81 };
82
83 let result = InitializeResult {
84 protocol_version: "2024-11-05".to_string(),
85 capabilities: ServerCapabilities {
86 tools: ToolsCapability {},
87 },
88 server_info: ServerInfo {
89 name: "gamecode-mcp2".to_string(),
90 version: env!("CARGO_PKG_VERSION").to_string(),
91 },
92 instructions: Some(
93 "GameCode MCP Server v2 - Direct tool integration. Configure tools in tools.yaml"
94 .to_string(),
95 ),
96 };
97
98 Ok(serde_json::to_value(result).unwrap())
99 }
100
101 async fn handle_tools_list(&self) -> Result<Value, JsonRpcError> {
103 let tools = self.tool_manager.get_mcp_tools();
104
105 let result = ListToolsResult { tools };
106
107 Ok(serde_json::to_value(result).unwrap())
108 }
109
110 async fn handle_tools_call(&self, params: Option<Value>) -> Result<Value, JsonRpcError> {
112 let params: CallToolParams = if let Some(p) = params {
113 serde_json::from_value(p).map_err(|e| JsonRpcError {
114 code: INVALID_PARAMS,
115 message: format!("Invalid tool call params: {}", e),
116 data: None,
117 })?
118 } else {
119 return Err(JsonRpcError {
120 code: INVALID_PARAMS,
121 message: "Missing tool call params".to_string(),
122 data: None,
123 });
124 };
125
126 match self
128 .tool_manager
129 .execute_tool(¶ms.name, params.arguments)
130 .await
131 {
132 Ok(result) => {
133 let response = CallToolResult {
134 content: vec![ContentBlock::Text {
135 text: serde_json::to_string(&result).unwrap_or_else(|_| "null".to_string()),
136 }],
137 is_error: None,
138 };
139
140 Ok(serde_json::to_value(response).unwrap())
141 }
142 Err(e) => {
143 error!("Tool execution failed: {}", e);
144
145 let response = CallToolResult {
146 content: vec![ContentBlock::Text {
147 text: format!("Error: {}", e),
148 }],
149 is_error: Some(true),
150 };
151
152 Ok(serde_json::to_value(response).unwrap())
153 }
154 }
155 }
156}