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
This commit is contained in:
+13
@@ -40,8 +40,11 @@ pub struct McpRequest {
|
|||||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
pub struct McpResponse {
|
pub struct McpResponse {
|
||||||
jsonrpc: String,
|
jsonrpc: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
id: Option<Value>,
|
id: Option<Value>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
result: Option<Value>,
|
result: Option<Value>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
error: Option<McpError>,
|
error: Option<McpError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +52,7 @@ pub struct McpResponse {
|
|||||||
pub struct McpError {
|
pub struct McpError {
|
||||||
code: i32,
|
code: i32,
|
||||||
message: String,
|
message: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
data: Option<Value>,
|
data: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +117,11 @@ async fn run_stdio_server() -> Result<()> {
|
|||||||
let server_clone = server.clone();
|
let server_clone = server.clone();
|
||||||
match serde_json::from_str::<McpRequest>(line) {
|
match serde_json::from_str::<McpRequest>(line) {
|
||||||
Ok(request) => {
|
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 = server_clone.handle_request(request).await;
|
||||||
let response_json = serde_json::to_string(&response)?;
|
let response_json = serde_json::to_string(&response)?;
|
||||||
println!("{}", response_json);
|
println!("{}", response_json);
|
||||||
@@ -182,6 +191,10 @@ async fn handle_connection(socket: tokio::net::TcpStream) -> Result<()> {
|
|||||||
|
|
||||||
match serde_json::from_str::<McpRequest>(line) {
|
match serde_json::from_str::<McpRequest>(line) {
|
||||||
Ok(request) => {
|
Ok(request) => {
|
||||||
|
if request.id.is_none() {
|
||||||
|
server.handle_notification(request).await;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let response = server.handle_request(request).await;
|
let response = server.handle_request(request).await;
|
||||||
let response_json = serde_json::to_string(&response)? + "\n";
|
let response_json = serde_json::to_string(&response)? + "\n";
|
||||||
writer.write_all(response_json.as_bytes()).await?;
|
writer.write_all(response_json.as_bytes()).await?;
|
||||||
|
|||||||
+13
-2
@@ -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 {
|
pub async fn handle_request(&self, request: McpRequest) -> McpResponse {
|
||||||
match request.method.as_str() {
|
match request.method.as_str() {
|
||||||
"initialize" => {
|
"initialize" => {
|
||||||
@@ -123,9 +135,8 @@ impl McpServer {
|
|||||||
// Return immediately with fast status
|
// Return immediately with fast status
|
||||||
let server_info = json!({
|
let server_info = json!({
|
||||||
"name": "MT5-Quant",
|
"name": "MT5-Quant",
|
||||||
"version": "1.27.0",
|
"version": env!("CARGO_PKG_VERSION"),
|
||||||
"setup": {
|
"setup": {
|
||||||
"verified": null, // null = checking
|
|
||||||
"hint": "Auto-verification running... Use verify_setup tool for detailed status",
|
"hint": "Auto-verification running... Use verify_setup tool for detailed status",
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user