@@ -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]
78100pub 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