From 41c8b36826d22346e498157184de525f7a23ec17 Mon Sep 17 00:00:00 2001 From: Devid HW Date: Sun, 19 Apr 2026 09:51:46 +0700 Subject: [PATCH] fix: handle MCP notifications properly (notifications/initialized) - Add handle_notification() for notification messages (no id field) - Use CARGO_PKG_VERSION for dynamic version in initialize response - Skip serializing None fields in McpResponse and McpError - Remove verified field from setup info --- src/main.rs | 13 +++++++++++++ src/mcp_server.rs | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 287ed0c..78f9b11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,8 +40,11 @@ pub struct McpRequest { #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct McpResponse { jsonrpc: String, + #[serde(skip_serializing_if = "Option::is_none")] id: Option, + #[serde(skip_serializing_if = "Option::is_none")] result: Option, + #[serde(skip_serializing_if = "Option::is_none")] error: Option, } @@ -49,6 +52,7 @@ pub struct McpResponse { pub struct McpError { code: i32, message: String, + #[serde(skip_serializing_if = "Option::is_none")] data: Option, } @@ -113,6 +117,11 @@ async fn run_stdio_server() -> Result<()> { let server_clone = server.clone(); match serde_json::from_str::(line) { Ok(request) => { + // Notifications have no id — don't send a response + if request.id.is_none() { + server_clone.handle_notification(request).await; + continue; + } let response = server_clone.handle_request(request).await; let response_json = serde_json::to_string(&response)?; println!("{}", response_json); @@ -182,6 +191,10 @@ async fn handle_connection(socket: tokio::net::TcpStream) -> Result<()> { match serde_json::from_str::(line) { Ok(request) => { + if request.id.is_none() { + server.handle_notification(request).await; + continue; + } let response = server.handle_request(request).await; let response_json = serde_json::to_string(&response)? + "\n"; writer.write_all(response_json.as_bytes()).await?; diff --git a/src/mcp_server.rs b/src/mcp_server.rs index f848ed5..c121b5d 100644 --- a/src/mcp_server.rs +++ b/src/mcp_server.rs @@ -99,6 +99,18 @@ impl McpServer { } } + /// Handle a notification (no id — no response sent) + pub async fn handle_notification(&self, request: McpRequest) { + match request.method.as_str() { + "notifications/initialized" => { + // Client confirms initialization is complete — no action needed + } + _ => { + tracing::debug!("Unhandled notification: {}", request.method); + } + } + } + pub async fn handle_request(&self, request: McpRequest) -> McpResponse { match request.method.as_str() { "initialize" => { @@ -123,9 +135,8 @@ impl McpServer { // Return immediately with fast status let server_info = json!({ "name": "MT5-Quant", - "version": "1.27.0", + "version": env!("CARGO_PKG_VERSION"), "setup": { - "verified": null, // null = checking "hint": "Auto-verification running... Use verify_setup tool for detailed status", } });