From f3c786706a04fbd2cbeac1b4dea8d80b37a1f900 Mon Sep 17 00:00:00 2001 From: mrcs64 Date: Wed, 29 Jul 2026 22:02:49 +0200 Subject: [PATCH] fix: return header mismatch for missing protocol header (#1083) Co-authored-by: mrcs64 <9069178+mrcs64@users.noreply.github.com> --- .../transport/streamable_http_server/tower.rs | 4 +-- .../test_streamable_http_protocol_version.rs | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/crates/rmcp/src/transport/streamable_http_server/tower.rs b/crates/rmcp/src/transport/streamable_http_server/tower.rs index a869bd1..3eb593a 100644 --- a/crates/rmcp/src/transport/streamable_http_server/tower.rs +++ b/crates/rmcp/src/transport/streamable_http_server/tower.rs @@ -473,9 +473,9 @@ fn validate_request_protocol_version_meta( .get(HEADER_MCP_PROTOCOL_VERSION) .and_then(|value| value.to_str().ok()) else { - return Err(invalid_request_jsonrpc_response( + return Err(header_mismatch_jsonrpc_response( Some(request.id.clone()), - "Invalid Request: request _meta protocolVersion requires MCP-Protocol-Version header", + "request _meta protocolVersion requires MCP-Protocol-Version header", )); }; if header_version != meta_version.as_str() { diff --git a/crates/rmcp/tests/test_streamable_http_protocol_version.rs b/crates/rmcp/tests/test_streamable_http_protocol_version.rs index cf63624..c6806c7 100644 --- a/crates/rmcp/tests/test_streamable_http_protocol_version.rs +++ b/crates/rmcp/tests/test_streamable_http_protocol_version.rs @@ -185,3 +185,35 @@ async fn stateful_rejected_initial_posts_do_not_create_sessions() -> anyhow::Res ct.cancel(); Ok(()) } + +#[tokio::test] +async fn stateless_missing_protocol_header_returns_header_mismatch() -> anyhow::Result<()> { + let (client, url, ct) = spawn_server(stateless_json_config()).await; + + let body = r#"{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"test","version":"1.0"},"io.modelcontextprotocol/clientCapabilities":{}}}}"#; + let response = client + .post(&url) + .header("Content-Type", "application/json") + .header("Accept", "application/json, text/event-stream") + .header("Mcp-Method", "tools/list") + .body(body) + .send() + .await + .expect("send non-initialize request"); + + assert_eq!(response.status(), 400); + + let body: serde_json::Value = response.json().await?; + assert_eq!(body["jsonrpc"], "2.0"); + assert_eq!(body["id"], 1); + assert_eq!(body["error"]["code"], -32020); + assert!( + body["error"]["message"] + .as_str() + .is_some_and(|message| message.contains("requires MCP-Protocol-Version header")), + "expected missing protocol header message, got: {body}" + ); + + ct.cancel(); + Ok(()) +}