@@ -328,19 +328,19 @@ def _create_json_response(
328328 headers = response_headers ,
329329 )
330330
331- def _get_session_id (self , request : Request ) -> str | None : # pragma: no cover
331+ def _get_session_id (self , request : Request ) -> str | None :
332332 """Extract the session ID from request headers."""
333333 return request .headers .get (MCP_SESSION_ID_HEADER )
334334
335- def _create_event_data (self , event_message : EventMessage ) -> dict [str , str ]: # pragma: no cover
335+ def _create_event_data (self , event_message : EventMessage ) -> dict [str , str ]:
336336 """Create event data dictionary from an EventMessage."""
337337 event_data = {
338338 "event" : "message" ,
339339 "data" : event_message .message .model_dump_json (by_alias = True , exclude_none = True ),
340340 }
341341
342342 # If an event ID was provided, include it
343- if event_message .event_id :
343+ if event_message .event_id : # pragma: no cover
344344 event_data ["id" ] = event_message .event_id
345345
346346 return event_data
@@ -381,9 +381,9 @@ async def handle_request(self, scope: Scope, receive: Receive, send: Send) -> No
381381
382382 if request .method == "POST" :
383383 await self ._handle_post_request (scope , request , receive , send )
384- elif request .method == "GET" : # pragma: no cover
384+ elif request .method == "GET" :
385385 await self ._handle_get_request (request , send )
386- elif request .method == "DELETE" : # pragma: no cover
386+ elif request .method == "DELETE" :
387387 await self ._handle_delete_request (request , send )
388388 else : # pragma: no cover
389389 await self ._handle_unsupported_request (request , send )
@@ -470,14 +470,14 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
470470 # Check if this is an initialization request
471471 is_initialization_request = isinstance (message , JSONRPCRequest ) and message .method == "initialize"
472472
473- if is_initialization_request : # pragma: no cover
473+ if is_initialization_request :
474474 # Check if the server already has an established session
475475 if self .mcp_session_id :
476476 # Check if request has a session ID
477477 request_session_id = self ._get_session_id (request )
478478
479479 # If request has a session ID but doesn't match, return 404
480- if request_session_id and request_session_id != self .mcp_session_id :
480+ if request_session_id and request_session_id != self .mcp_session_id : # pragma: no cover
481481 response = self ._create_error_response (
482482 "Not Found: Invalid or expired session ID" ,
483483 HTTPStatus .NOT_FOUND ,
@@ -488,7 +488,7 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
488488 return
489489
490490 # For notifications and responses only, return 202 Accepted
491- if not isinstance (message , JSONRPCRequest ): # pragma: no cover
491+ if not isinstance (message , JSONRPCRequest ):
492492 # Create response object and send it
493493 response = self ._create_json_response (
494494 None ,
@@ -561,14 +561,14 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
561561 await response (scope , receive , send )
562562 finally :
563563 await self ._clean_up_memory_streams (request_id )
564- else : # pragma: no cover
564+ else :
565565 # Create SSE stream
566566 sse_stream_writer , sse_stream_reader = anyio .create_memory_object_stream [dict [str , str ]](0 )
567567
568568 # Store writer reference so close_sse_stream() can close it
569569 self ._sse_stream_writers [request_id ] = sse_stream_writer
570570
571- async def sse_writer ():
571+ async def sse_writer (): # pragma: lax no cover
572572 # Get the request ID from the incoming request message
573573 try :
574574 async with sse_stream_writer , request_stream_reader :
@@ -617,7 +617,7 @@ async def sse_writer():
617617 # Then send the message to be processed by the server
618618 session_message = self ._create_session_message (message , request , request_id , protocol_version )
619619 await writer .send (session_message )
620- except Exception :
620+ except Exception : # pragma: no cover
621621 logger .exception ("SSE response error" )
622622 await sse_stream_writer .aclose ()
623623 await self ._clean_up_memory_streams (request_id )
@@ -636,33 +636,33 @@ async def sse_writer():
636636 await writer .send (Exception (err ))
637637 return
638638
639- async def _handle_get_request (self , request : Request , send : Send ) -> None : # pragma: no cover
639+ async def _handle_get_request (self , request : Request , send : Send ) -> None :
640640 """Handle GET request to establish SSE.
641641
642642 This allows the server to communicate to the client without the client
643643 first sending data via HTTP POST. The server can send JSON-RPC requests
644644 and notifications on this stream.
645645 """
646646 writer = self ._read_stream_writer
647- if writer is None :
647+ if writer is None : # pragma: no cover
648648 raise ValueError ("No read stream writer available. Ensure connect() is called first." )
649649
650650 # Validate Accept header - must include text/event-stream
651651 _ , has_sse = self ._check_accept_headers (request )
652652
653- if not has_sse :
653+ if not has_sse : # pragma: no cover
654654 response = self ._create_error_response (
655655 "Not Acceptable: Client must accept text/event-stream" ,
656656 HTTPStatus .NOT_ACCEPTABLE ,
657657 )
658658 await response (request .scope , request .receive , send )
659659 return
660660
661- if not await self ._validate_request_headers (request , send ):
661+ if not await self ._validate_request_headers (request , send ): # pragma: no cover
662662 return
663663
664664 # Handle resumability: check for Last-Event-ID header
665- if last_event_id := request .headers .get (LAST_EVENT_ID_HEADER ):
665+ if last_event_id := request .headers .get (LAST_EVENT_ID_HEADER ): # pragma: no cover
666666 await self ._replay_events (last_event_id , request , send )
667667 return
668668
@@ -676,7 +676,7 @@ async def _handle_get_request(self, request: Request, send: Send) -> None: # pr
676676 headers [MCP_SESSION_ID_HEADER ] = self .mcp_session_id
677677
678678 # Check if we already have an active GET stream
679- if GET_STREAM_KEY in self ._request_streams :
679+ if GET_STREAM_KEY in self ._request_streams : # pragma: no cover
680680 response = self ._create_error_response (
681681 "Conflict: Only one SSE stream is allowed per session" ,
682682 HTTPStatus .CONFLICT ,
@@ -696,7 +696,7 @@ async def standalone_sse_writer():
696696
697697 async with sse_stream_writer , standalone_stream_reader :
698698 # Process messages from the standalone stream
699- async for event_message in standalone_stream_reader :
699+ async for event_message in standalone_stream_reader : # pragma: lax no cover
700700 # For the standalone stream, we handle:
701701 # - JSONRPCNotification (server sends notifications to client)
702702 # - JSONRPCRequest (server sends requests to client)
@@ -705,7 +705,7 @@ async def standalone_sse_writer():
705705 # Send the message via SSE
706706 event_data = self ._create_event_data (event_message )
707707 await sse_stream_writer .send (event_data )
708- except Exception :
708+ except Exception : # pragma: no cover
709709 logger .exception ("Error in standalone SSE writer" )
710710 finally :
711711 logger .debug ("Closing standalone SSE writer" )
@@ -721,17 +721,17 @@ async def standalone_sse_writer():
721721 try :
722722 # This will send headers immediately and establish the SSE connection
723723 await response (request .scope , request .receive , send )
724- except Exception :
724+ except Exception : # pragma: lax no cover
725725 logger .exception ("Error in standalone SSE response" )
726726 await self ._clean_up_memory_streams (GET_STREAM_KEY )
727727 finally :
728728 await sse_stream_writer .aclose ()
729729 await sse_stream_reader .aclose ()
730730
731- async def _handle_delete_request (self , request : Request , send : Send ) -> None : # pragma: no cover
731+ async def _handle_delete_request (self , request : Request , send : Send ) -> None :
732732 """Handle DELETE requests for explicit session termination."""
733733 # Validate session ID
734- if not self .mcp_session_id :
734+ if not self .mcp_session_id : # pragma: no cover
735735 # If no session ID set, return Method Not Allowed
736736 response = self ._create_error_response (
737737 "Method Not Allowed: Session termination not supported" ,
@@ -740,7 +740,7 @@ async def _handle_delete_request(self, request: Request, send: Send) -> None: #
740740 await response (request .scope , request .receive , send )
741741 return
742742
743- if not await self ._validate_request_headers (request , send ):
743+ if not await self ._validate_request_headers (request , send ): # pragma: no cover
744744 return
745745
746746 await self .terminate ()
@@ -798,24 +798,24 @@ async def _handle_unsupported_request(self, request: Request, send: Send) -> Non
798798 )
799799 await response (request .scope , request .receive , send )
800800
801- async def _validate_request_headers (self , request : Request , send : Send ) -> bool : # pragma: no cover
801+ async def _validate_request_headers (self , request : Request , send : Send ) -> bool : # pragma: lax no cover
802802 if not await self ._validate_session (request , send ):
803803 return False
804804 if not await self ._validate_protocol_version (request , send ):
805805 return False
806806 return True
807807
808- async def _validate_session (self , request : Request , send : Send ) -> bool : # pragma: no cover
808+ async def _validate_session (self , request : Request , send : Send ) -> bool :
809809 """Validate the session ID in the request."""
810- if not self .mcp_session_id :
810+ if not self .mcp_session_id : # pragma: no cover
811811 # If we're not using session IDs, return True
812812 return True
813813
814814 # Get the session ID from the request headers
815815 request_session_id = self ._get_session_id (request )
816816
817817 # If no session ID provided but required, return error
818- if not request_session_id :
818+ if not request_session_id : # pragma: no cover
819819 response = self ._create_error_response (
820820 "Bad Request: Missing session ID" ,
821821 HTTPStatus .BAD_REQUEST ,
@@ -824,7 +824,7 @@ async def _validate_session(self, request: Request, send: Send) -> bool: # prag
824824 return False
825825
826826 # If session ID doesn't match, return error
827- if request_session_id != self .mcp_session_id :
827+ if request_session_id != self .mcp_session_id : # pragma: no cover
828828 response = self ._create_error_response (
829829 "Not Found: Invalid or expired session ID" ,
830830 HTTPStatus .NOT_FOUND ,
@@ -834,17 +834,17 @@ async def _validate_session(self, request: Request, send: Send) -> bool: # prag
834834
835835 return True
836836
837- async def _validate_protocol_version (self , request : Request , send : Send ) -> bool : # pragma: no cover
837+ async def _validate_protocol_version (self , request : Request , send : Send ) -> bool :
838838 """Validate the protocol version header in the request."""
839839 # Get the protocol version from the request headers
840840 protocol_version = request .headers .get (MCP_PROTOCOL_VERSION_HEADER )
841841
842842 # If no protocol version provided, assume default version
843- if protocol_version is None :
843+ if protocol_version is None : # pragma: no cover
844844 protocol_version = DEFAULT_NEGOTIATED_VERSION
845845
846846 # Check if the protocol version is supported
847- if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS :
847+ if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS : # pragma: no cover
848848 supported_versions = ", " .join (SUPPORTED_PROTOCOL_VERSIONS )
849849 response = self ._create_error_response (
850850 f"Bad Request: Unsupported protocol version: { protocol_version } . "
@@ -1006,10 +1006,10 @@ async def message_router():
10061006 try :
10071007 # Send both the message and the event ID
10081008 await self ._request_streams [request_stream_id ][0 ].send (EventMessage (message , event_id ))
1009- except ( # pragma: no cover
1009+ except (
10101010 anyio .BrokenResourceError ,
10111011 anyio .ClosedResourceError ,
1012- ):
1012+ ): # pragma: no cover
10131013 # Stream might be closed, remove from registry
10141014 self ._request_streams .pop (request_stream_id , None )
10151015 else : # pragma: no cover
0 commit comments