@@ -78,6 +78,28 @@ fn cache_tools_from_response(
7878 }
7979}
8080
81+ /// Derives the negotiated protocol version and base request headers from an
82+ /// initialize response: returns `base` with `MCP-Protocol-Version` injected
83+ /// (per MCP 2025-06-18) plus the version used to gate SEP-2243 headers,
84+ /// defaulting to a pre-SEP version when the response can't be parsed.
85+ fn negotiate_version_headers (
86+ init_response : & ServerJsonRpcMessage ,
87+ base : HashMap < HeaderName , HeaderValue > ,
88+ ) -> ( ProtocolVersion , HashMap < HeaderName , HeaderValue > ) {
89+ let mut version = ProtocolVersion :: default ( ) ;
90+ let mut headers = base;
91+ if let ServerJsonRpcMessage :: Response ( response) = init_response {
92+ if let ServerResult :: InitializeResult ( init_result) = & response. result {
93+ version = init_result. protocol_version . clone ( ) ;
94+ // HeaderName::from_static requires lowercase
95+ if let Ok ( hv) = HeaderValue :: from_str ( init_result. protocol_version . as_str ( ) ) {
96+ headers. insert ( HeaderName :: from_static ( "mcp-protocol-version" ) , hv) ;
97+ }
98+ }
99+ }
100+ ( version, headers)
101+ }
102+
81103#[ derive( Debug ) ]
82104#[ non_exhaustive]
83105pub struct AuthRequiredError {
@@ -592,31 +614,29 @@ impl<C: StreamableHttpClient> StreamableHttpClientWorker<C> {
592614
593615 let new_session_id: Option < Arc < str > > = new_session_id_str. map ( |s| Arc :: from ( s. as_str ( ) ) ) ;
594616
595- // Start from custom_headers, then inject the negotiated MCP-Protocol-Version
596- // so all subsequent requests carry the right version (MCP 2025-06-18 spec).
597- let mut new_protocol_headers = custom_headers;
598- if let ServerJsonRpcMessage :: Response ( response) = & init_msg {
599- if let ServerResult :: InitializeResult ( init_result) = & response. result {
600- if let Ok ( hv) = HeaderValue :: from_str ( init_result. protocol_version . as_str ( ) ) {
601- new_protocol_headers
602- . insert ( HeaderName :: from_static ( "mcp-protocol-version" ) , hv) ;
603- }
604- }
605- }
617+ let ( negotiated_version, new_protocol_headers) =
618+ negotiate_version_headers ( & init_msg, custom_headers) ;
606619
607620 let initialized_notification = ClientJsonRpcMessage :: notification (
608621 ClientNotification :: InitializedNotification ( InitializedNotification {
609622 method : Default :: default ( ) ,
610623 extensions : Default :: default ( ) ,
611624 } ) ,
612625 ) ;
626+ // SEP-2243: notifications carry no Mcp-Param-*, so an empty tool cache suffices.
627+ let initialized_headers = build_request_headers (
628+ & new_protocol_headers,
629+ & initialized_notification,
630+ & HashMap :: new ( ) ,
631+ & negotiated_version,
632+ ) ;
613633 client
614634 . post_message (
615635 uri,
616636 initialized_notification,
617637 new_session_id. clone ( ) ,
618638 auth_header,
619- new_protocol_headers . clone ( ) ,
639+ initialized_headers ,
620640 )
621641 . await ?
622642 . expect_accepted_or_json :: < C :: Error > ( ) ?;
@@ -692,25 +712,8 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
692712 }
693713 None
694714 } ;
695- // Extract the negotiated protocol version from the init response
696- // and build a custom headers map that includes MCP-Protocol-Version
697- // for all subsequent HTTP requests (per MCP 2025-06-18 spec).
698- // Negotiated protocol version gates SEP-2243 standard headers; default to a
699- // pre-SEP version so headers are omitted if the version can't be determined.
700- let mut negotiated_version = ProtocolVersion :: default ( ) ;
701- let mut protocol_headers = {
702- let mut headers = config. custom_headers . clone ( ) ;
703- if let ServerJsonRpcMessage :: Response ( response) = & message {
704- if let ServerResult :: InitializeResult ( init_result) = & response. result {
705- negotiated_version = init_result. protocol_version . clone ( ) ;
706- if let Ok ( hv) = HeaderValue :: from_str ( init_result. protocol_version . as_str ( ) ) {
707- // HeaderName::from_static requires lowercase
708- headers. insert ( HeaderName :: from_static ( "mcp-protocol-version" ) , hv) ;
709- }
710- }
711- }
712- headers
713- } ;
715+ let ( negotiated_version, mut protocol_headers) =
716+ negotiate_version_headers ( & message, config. custom_headers . clone ( ) ) ;
714717 // SEP-2243: tool input schemas (name -> schema) cached from tools/list responses,
715718 // used to promote annotated tools/call arguments to Mcp-Param-* headers.
716719 let mut tool_header_cache: HashMap < String , Arc < JsonObject > > = HashMap :: new ( ) ;
0 commit comments