@@ -389,7 +389,11 @@ def handle_post(request)
389389 end
390390 rescue StandardError => e
391391 MCP . configuration . exception_reporter . call ( e , { request : body_string } )
392- [ 500 , { "Content-Type" => "application/json" } , [ { error : "Internal server error" } . to_json ] ]
392+ json_rpc_error_response (
393+ status : 500 ,
394+ code : JsonRpcHandler ::ErrorCode ::INTERNAL_ERROR ,
395+ message : "Internal server error" ,
396+ )
393397 end
394398
395399 def handle_get ( request )
@@ -513,19 +517,19 @@ def validate_content_type(request)
513517 media_type = content_type &.split ( ";" ) &.first &.strip &.downcase
514518 return if media_type == "application/json"
515519
516- [
517- 415 ,
518- { "Content-Type" => "application/json" } ,
519- [ { error : "Unsupported Media Type: Content-Type must be application/json" } . to_json ] ,
520- ]
520+ json_rpc_error_response (
521+ status : 415 ,
522+ code : JsonRpcHandler :: ErrorCode :: INVALID_REQUEST ,
523+ message : "Unsupported Media Type: Content-Type must be application/json" ,
524+ )
521525 end
522526
523527 def not_acceptable_response ( required_types )
524- [
525- 406 ,
526- { "Content-Type" => "application/json" } ,
527- [ { error : "Not Acceptable: Accept header must include #{ required_types . join ( " and " ) } " } . to_json ] ,
528- ]
528+ json_rpc_error_response (
529+ status : 406 ,
530+ code : JsonRpcHandler :: ErrorCode :: INVALID_REQUEST ,
531+ message : "Not Acceptable: Accept header must include #{ required_types . join ( " and " ) } " ,
532+ )
529533 end
530534
531535 def parse_request_body ( body_string )
@@ -535,7 +539,11 @@ def parse_request_body(body_string)
535539 end
536540
537541 def invalid_json_response
538- [ 400 , { "Content-Type" => "application/json" } , [ { error : "Invalid JSON" } . to_json ] ]
542+ json_rpc_error_response (
543+ status : 400 ,
544+ code : JsonRpcHandler ::ErrorCode ::PARSE_ERROR ,
545+ message : "Parse error: Invalid JSON" ,
546+ )
539547 end
540548
541549 def initialize_request? ( body )
@@ -548,15 +556,16 @@ def validate_protocol_version_header(request)
548556 return if MCP ::Configuration ::SUPPORTED_STABLE_PROTOCOL_VERSIONS . include? ( header_value )
549557
550558 supported = MCP ::Configuration ::SUPPORTED_STABLE_PROTOCOL_VERSIONS . join ( ", " )
551- body = {
552- jsonrpc : "2.0" ,
553- id : nil ,
554- error : {
555- code : JsonRpcHandler ::ErrorCode ::INVALID_REQUEST ,
556- message : "Bad Request: Unsupported protocol version: #{ header_value } . Supported versions: #{ supported } " ,
557- } ,
558- }
559- [ 400 , { "Content-Type" => "application/json" } , [ body . to_json ] ]
559+ json_rpc_error_response (
560+ status : 400 ,
561+ code : JsonRpcHandler ::ErrorCode ::INVALID_REQUEST ,
562+ message : "Bad Request: Unsupported protocol version: #{ header_value } . Supported versions: #{ supported } " ,
563+ )
564+ end
565+
566+ def json_rpc_error_response ( status :, code :, message :)
567+ body = { jsonrpc : "2.0" , id : nil , error : { code : code , message : message } }
568+ [ status , { "Content-Type" => "application/json" } , [ body . to_json ] ]
560569 end
561570
562571 def notification? ( body )
@@ -793,15 +802,27 @@ def session_active?(session_id)
793802 end
794803
795804 def method_not_allowed_response
796- [ 405 , { "Content-Type" => "application/json" } , [ { error : "Method not allowed" } . to_json ] ]
805+ json_rpc_error_response (
806+ status : 405 ,
807+ code : JsonRpcHandler ::ErrorCode ::INVALID_REQUEST ,
808+ message : "Method not allowed" ,
809+ )
797810 end
798811
799812 def missing_session_id_response
800- [ 400 , { "Content-Type" => "application/json" } , [ { error : "Missing session ID" } . to_json ] ]
813+ json_rpc_error_response (
814+ status : 400 ,
815+ code : JsonRpcHandler ::ErrorCode ::INVALID_REQUEST ,
816+ message : "Missing session ID" ,
817+ )
801818 end
802819
803820 def session_not_found_response
804- [ 404 , { "Content-Type" => "application/json" } , [ { error : "Session not found" } . to_json ] ]
821+ json_rpc_error_response (
822+ status : 404 ,
823+ code : JsonRpcHandler ::ErrorCode ::INVALID_REQUEST ,
824+ message : "Session not found" ,
825+ )
805826 end
806827
807828 def already_initialized_response ( request_id )
@@ -821,11 +842,11 @@ def invalid_request_response(message, request_id: nil)
821842 end
822843
823844 def session_already_connected_response
824- [
825- 409 ,
826- { "Content-Type" => "application/json" } ,
827- [ { error : "Conflict: Only one SSE stream is allowed per session" } . to_json ] ,
828- ]
845+ json_rpc_error_response (
846+ status : 409 ,
847+ code : JsonRpcHandler :: ErrorCode :: INVALID_REQUEST ,
848+ message : "Conflict: Only one SSE stream is allowed per session" ,
849+ )
829850 end
830851
831852 def setup_sse_stream ( session_id )
0 commit comments