@@ -573,6 +573,164 @@ class StreamableHTTPTransportTest < ActiveSupport::TestCase
573573 assert_equal "Method not allowed" , body [ "error" ]
574574 end
575575
576+ test "POST request without Accept header returns 406" do
577+ request = create_rack_request_without_accept (
578+ "POST" ,
579+ "/" ,
580+ { "CONTENT_TYPE" => "application/json" } ,
581+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
582+ )
583+
584+ response = @transport . handle_request ( request )
585+ assert_equal 406 , response [ 0 ]
586+ assert_equal ( { "Content-Type" => "application/json" } , response [ 1 ] )
587+
588+ body = JSON . parse ( response [ 2 ] [ 0 ] )
589+ assert_equal "Not Acceptable: Accept header must include application/json and text/event-stream" ,
590+ body [ "error" ]
591+ end
592+
593+ test "POST request with Accept header missing text/event-stream returns 406" do
594+ request = create_rack_request_without_accept (
595+ "POST" ,
596+ "/" ,
597+ {
598+ "CONTENT_TYPE" => "application/json" ,
599+ "HTTP_ACCEPT" => "application/json" ,
600+ } ,
601+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
602+ )
603+
604+ response = @transport . handle_request ( request )
605+ assert_equal 406 , response [ 0 ]
606+
607+ body = JSON . parse ( response [ 2 ] [ 0 ] )
608+ assert_equal "Not Acceptable: Accept header must include application/json and text/event-stream" ,
609+ body [ "error" ]
610+ end
611+
612+ test "POST request with Accept header missing application/json returns 406" do
613+ request = create_rack_request_without_accept (
614+ "POST" ,
615+ "/" ,
616+ {
617+ "CONTENT_TYPE" => "application/json" ,
618+ "HTTP_ACCEPT" => "text/event-stream" ,
619+ } ,
620+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
621+ )
622+
623+ response = @transport . handle_request ( request )
624+ assert_equal 406 , response [ 0 ]
625+
626+ body = JSON . parse ( response [ 2 ] [ 0 ] )
627+ assert_equal "Not Acceptable: Accept header must include application/json and text/event-stream" ,
628+ body [ "error" ]
629+ end
630+
631+ test "POST request with valid Accept header succeeds" do
632+ request = create_rack_request (
633+ "POST" ,
634+ "/" ,
635+ {
636+ "CONTENT_TYPE" => "application/json" ,
637+ "HTTP_ACCEPT" => "application/json, text/event-stream" ,
638+ } ,
639+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
640+ )
641+
642+ response = @transport . handle_request ( request )
643+ assert_equal 200 , response [ 0 ]
644+ end
645+
646+ test "POST request with Accept header containing quality values succeeds" do
647+ request = create_rack_request (
648+ "POST" ,
649+ "/" ,
650+ {
651+ "CONTENT_TYPE" => "application/json" ,
652+ "HTTP_ACCEPT" => "application/json;q=0.9, text/event-stream;q=0.8" ,
653+ } ,
654+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
655+ )
656+
657+ response = @transport . handle_request ( request )
658+ assert_equal 200 , response [ 0 ]
659+ end
660+
661+ test "GET request without Accept header returns 406" do
662+ init_request = create_rack_request (
663+ "POST" ,
664+ "/" ,
665+ { "CONTENT_TYPE" => "application/json" } ,
666+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
667+ )
668+ init_response = @transport . handle_request ( init_request )
669+ session_id = init_response [ 1 ] [ "Mcp-Session-Id" ]
670+
671+ request = create_rack_request_without_accept (
672+ "GET" ,
673+ "/" ,
674+ { "HTTP_MCP_SESSION_ID" => session_id } ,
675+ )
676+
677+ response = @transport . handle_request ( request )
678+ assert_equal 406 , response [ 0 ]
679+
680+ body = JSON . parse ( response [ 2 ] [ 0 ] )
681+ assert_equal "Not Acceptable: Accept header must include text/event-stream" , body [ "error" ]
682+ end
683+
684+ test "GET request with Accept header missing text/event-stream returns 406" do
685+ init_request = create_rack_request (
686+ "POST" ,
687+ "/" ,
688+ { "CONTENT_TYPE" => "application/json" } ,
689+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
690+ )
691+ init_response = @transport . handle_request ( init_request )
692+ session_id = init_response [ 1 ] [ "Mcp-Session-Id" ]
693+
694+ request = create_rack_request_without_accept (
695+ "GET" ,
696+ "/" ,
697+ {
698+ "HTTP_MCP_SESSION_ID" => session_id ,
699+ "HTTP_ACCEPT" => "application/json" ,
700+ } ,
701+ )
702+
703+ response = @transport . handle_request ( request )
704+ assert_equal 406 , response [ 0 ]
705+
706+ body = JSON . parse ( response [ 2 ] [ 0 ] )
707+ assert_equal "Not Acceptable: Accept header must include text/event-stream" , body [ "error" ]
708+ end
709+
710+ test "GET request with valid Accept header succeeds" do
711+ init_request = create_rack_request (
712+ "POST" ,
713+ "/" ,
714+ { "CONTENT_TYPE" => "application/json" } ,
715+ { jsonrpc : "2.0" , method : "initialize" , id : "123" } . to_json ,
716+ )
717+ init_response = @transport . handle_request ( init_request )
718+ session_id = init_response [ 1 ] [ "Mcp-Session-Id" ]
719+
720+ request = create_rack_request (
721+ "GET" ,
722+ "/" ,
723+ {
724+ "HTTP_MCP_SESSION_ID" => session_id ,
725+ "HTTP_ACCEPT" => "text/event-stream" ,
726+ } ,
727+ )
728+
729+ response = @transport . handle_request ( request )
730+ assert_equal 200 , response [ 0 ]
731+ assert_equal "text/event-stream" , response [ 1 ] [ "Content-Type" ]
732+ end
733+
576734 test "stateless mode allows requests without session IDs, responding with no session ID" do
577735 stateless_transport = StreamableHTTPTransport . new ( @server , stateless : true )
578736
@@ -771,6 +929,25 @@ class StreamableHTTPTransportTest < ActiveSupport::TestCase
771929 private
772930
773931 def create_rack_request ( method , path , headers , body = nil )
932+ default_accept = case method
933+ when "POST"
934+ { "HTTP_ACCEPT" => "application/json, text/event-stream" }
935+ when "GET"
936+ { "HTTP_ACCEPT" => "text/event-stream" }
937+ else
938+ { }
939+ end
940+
941+ env = {
942+ "REQUEST_METHOD" => method ,
943+ "PATH_INFO" => path ,
944+ "rack.input" => StringIO . new ( body . to_s ) ,
945+ } . merge ( default_accept ) . merge ( headers )
946+
947+ Rack ::Request . new ( env )
948+ end
949+
950+ def create_rack_request_without_accept ( method , path , headers , body = nil )
774951 env = {
775952 "REQUEST_METHOD" => method ,
776953 "PATH_INFO" => path ,
0 commit comments