Skip to content

Commit 8c5eb71

Browse files
committed
fix: emit Mcp-Method on reinit initialized POST
1 parent cfa5218 commit 8c5eb71

1 file changed

Lines changed: 34 additions & 31 deletions

File tree

crates/rmcp/src/transport/streamable_http_client.rs

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@ fn cache_tools_from_response(
7373
}
7474
}
7575

76+
/// Derives the negotiated protocol version and base request headers from an
77+
/// initialize response: returns `base` with `MCP-Protocol-Version` injected
78+
/// (per MCP 2025-06-18) plus the version used to gate SEP-2243 headers,
79+
/// defaulting to a pre-SEP version when the response can't be parsed.
80+
fn negotiate_version_headers(
81+
init_response: &ServerJsonRpcMessage,
82+
base: HashMap<HeaderName, HeaderValue>,
83+
) -> (ProtocolVersion, HashMap<HeaderName, HeaderValue>) {
84+
let mut version = ProtocolVersion::default();
85+
let mut headers = base;
86+
if let ServerJsonRpcMessage::Response(response) = init_response {
87+
if let ServerResult::InitializeResult(init_result) = &response.result {
88+
version = init_result.protocol_version.clone();
89+
// HeaderName::from_static requires lowercase
90+
if let Ok(hv) = HeaderValue::from_str(init_result.protocol_version.as_str()) {
91+
headers.insert(HeaderName::from_static("mcp-protocol-version"), hv);
92+
}
93+
}
94+
}
95+
(version, headers)
96+
}
97+
7698
#[derive(Debug)]
7799
#[non_exhaustive]
78100
pub struct AuthRequiredError {
@@ -455,31 +477,29 @@ impl<C: StreamableHttpClient> StreamableHttpClientWorker<C> {
455477

456478
let new_session_id: Option<Arc<str>> = new_session_id_str.map(|s| Arc::from(s.as_str()));
457479

458-
// Start from custom_headers, then inject the negotiated MCP-Protocol-Version
459-
// so all subsequent requests carry the right version (MCP 2025-06-18 spec).
460-
let mut new_protocol_headers = custom_headers;
461-
if let ServerJsonRpcMessage::Response(response) = &init_msg {
462-
if let ServerResult::InitializeResult(init_result) = &response.result {
463-
if let Ok(hv) = HeaderValue::from_str(init_result.protocol_version.as_str()) {
464-
new_protocol_headers
465-
.insert(HeaderName::from_static("mcp-protocol-version"), hv);
466-
}
467-
}
468-
}
480+
let (negotiated_version, new_protocol_headers) =
481+
negotiate_version_headers(&init_msg, custom_headers);
469482

470483
let initialized_notification = ClientJsonRpcMessage::notification(
471484
ClientNotification::InitializedNotification(InitializedNotification {
472485
method: Default::default(),
473486
extensions: Default::default(),
474487
}),
475488
);
489+
// SEP-2243: notifications carry no Mcp-Param-*, so an empty tool cache suffices.
490+
let initialized_headers = build_request_headers(
491+
&new_protocol_headers,
492+
&initialized_notification,
493+
&HashMap::new(),
494+
&negotiated_version,
495+
);
476496
client
477497
.post_message(
478498
uri,
479499
initialized_notification,
480500
new_session_id.clone(),
481501
auth_header,
482-
new_protocol_headers.clone(),
502+
initialized_headers,
483503
)
484504
.await?
485505
.expect_accepted_or_json::<C::Error>()?;
@@ -555,25 +575,8 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
555575
}
556576
None
557577
};
558-
// Extract the negotiated protocol version from the init response
559-
// and build a custom headers map that includes MCP-Protocol-Version
560-
// for all subsequent HTTP requests (per MCP 2025-06-18 spec).
561-
// Negotiated protocol version gates SEP-2243 standard headers; default to a
562-
// pre-SEP version so headers are omitted if the version can't be determined.
563-
let mut negotiated_version = ProtocolVersion::default();
564-
let mut protocol_headers = {
565-
let mut headers = config.custom_headers.clone();
566-
if let ServerJsonRpcMessage::Response(response) = &message {
567-
if let ServerResult::InitializeResult(init_result) = &response.result {
568-
negotiated_version = init_result.protocol_version.clone();
569-
if let Ok(hv) = HeaderValue::from_str(init_result.protocol_version.as_str()) {
570-
// HeaderName::from_static requires lowercase
571-
headers.insert(HeaderName::from_static("mcp-protocol-version"), hv);
572-
}
573-
}
574-
}
575-
headers
576-
};
578+
let (negotiated_version, mut protocol_headers) =
579+
negotiate_version_headers(&message, config.custom_headers.clone());
577580
// SEP-2243: tool input schemas (name -> schema) cached from tools/list responses,
578581
// used to promote annotated tools/call arguments to Mcp-Param-* headers.
579582
let mut tool_header_cache: HashMap<String, Arc<JsonObject>> = HashMap::new();

0 commit comments

Comments
 (0)