Skip to content

Commit d27b509

Browse files
committed
refactor: address PR feedback
1 parent 158e181 commit d27b509

1 file changed

Lines changed: 35 additions & 22 deletions

File tree

  • crates/rmcp/src/transport/streamable_http_server

crates/rmcp/src/transport/streamable_http_server/tower.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,34 @@ fn message_has_per_request_protocol_version(message: &ClientJsonRpcMessage) -> b
250250
}
251251
}
252252

253+
// SEP-2567: sessions are removed from 2026-07-28; older versions are legacy.
254+
fn is_legacy_request(message: Option<&ClientJsonRpcMessage>, headers: &HeaderMap) -> bool {
255+
let from_body = match message {
256+
Some(ClientJsonRpcMessage::Request(req)) => match &req.request {
257+
ClientRequest::InitializeRequest(init) => Some(init.params.protocol_version.clone()),
258+
_ => req.request.get_meta().protocol_version(),
259+
},
260+
_ => None,
261+
};
262+
let version = from_body
263+
.or_else(|| {
264+
headers
265+
.get(HEADER_MCP_PROTOCOL_VERSION)
266+
.and_then(|value| value.to_str().ok())
267+
.and_then(|s| serde_json::from_value(serde_json::Value::String(s.to_owned())).ok())
268+
})
269+
.unwrap_or(ProtocolVersion::V_2025_03_26);
270+
version < ProtocolVersion::V_2026_07_28
271+
}
272+
273+
fn method_not_allowed_response() -> BoxResponse {
274+
Response::builder()
275+
.status(http::StatusCode::METHOD_NOT_ALLOWED)
276+
.header(ALLOW, "POST")
277+
.body(Full::new(Bytes::from("Method Not Allowed")).boxed())
278+
.expect("valid response")
279+
}
280+
253281
fn invalid_request_jsonrpc_response(
254282
id: Option<RequestId>,
255283
message: impl Into<Cow<'static, str>>,
@@ -1204,6 +1232,9 @@ where
12041232
)
12051233
.expect("valid response"));
12061234
}
1235+
if !is_legacy_request(None, request.headers()) {
1236+
return Ok(method_not_allowed_response());
1237+
}
12071238
// check session id
12081239
let session_id = request
12091240
.headers()
@@ -1340,29 +1371,8 @@ where
13401371
Err(response) => return Ok(response),
13411372
};
13421373

1343-
// SEP-2567: sessions are removed at the protocol level from 2026-07-28.
1344-
// Serve such requests statelessly even in stateful mode, never assigning
1345-
// or requiring an Mcp-Session-Id. `initialize` declares the version in its
1346-
// body params; every other request in the `MCP-Protocol-Version` header
1347-
// (defaulting to `2025-03-26` when absent).
1348-
let init_version = match &message {
1349-
ClientJsonRpcMessage::Request(req) => match &req.request {
1350-
ClientRequest::InitializeRequest(init) => {
1351-
Some(init.params.protocol_version.clone())
1352-
}
1353-
_ => None,
1354-
},
1355-
_ => None,
1356-
};
1357-
let declared_version = init_version.unwrap_or_else(|| {
1358-
part.headers
1359-
.get(HEADER_MCP_PROTOCOL_VERSION)
1360-
.and_then(|value| value.to_str().ok())
1361-
.and_then(|s| serde_json::from_value(serde_json::Value::String(s.to_owned())).ok())
1362-
.unwrap_or(ProtocolVersion::V_2025_03_26)
1363-
});
13641374
let use_session =
1365-
self.config.stateful_mode && declared_version < ProtocolVersion::V_2026_07_28;
1375+
self.config.stateful_mode && is_legacy_request(Some(&message), &part.headers);
13661376

13671377
if use_session {
13681378
// do we have a session id?
@@ -1697,6 +1707,9 @@ where
16971707
B: Body + Send + 'static,
16981708
B::Error: Display,
16991709
{
1710+
if !is_legacy_request(None, request.headers()) {
1711+
return Ok(method_not_allowed_response());
1712+
}
17001713
// check session id
17011714
let session_id = request
17021715
.headers()

0 commit comments

Comments
 (0)