@@ -187,7 +187,6 @@ def __init__(
187187 self ._receive_notification_type = receive_notification_type
188188 self ._session_read_timeout_seconds = read_timeout_seconds
189189 self ._in_flight = {}
190-
191190 self ._exit_stack = AsyncExitStack ()
192191
193192 async def __aenter__ (self ) -> Self :
@@ -232,45 +231,48 @@ async def send_request(
232231 ](1 )
233232 self ._response_streams [request_id ] = response_stream
234233
235- self ._exit_stack .push_async_callback (lambda : response_stream .aclose ())
236- self ._exit_stack .push_async_callback (lambda : response_stream_reader .aclose ())
237-
238- jsonrpc_request = JSONRPCRequest (
239- jsonrpc = "2.0" ,
240- id = request_id ,
241- ** request .model_dump (by_alias = True , mode = "json" , exclude_none = True ),
242- )
243-
244- # TODO: Support progress callbacks
245-
246- await self ._write_stream .send (JSONRPCMessage (jsonrpc_request ))
247-
248- # request read timeout takes precedence over session read timeout
249- timeout = None
250- if request_read_timeout_seconds is not None :
251- timeout = request_read_timeout_seconds .total_seconds ()
252- elif self ._session_read_timeout_seconds is not None :
253- timeout = self ._session_read_timeout_seconds .total_seconds ()
254-
255234 try :
256- with anyio .fail_after (timeout ):
257- response_or_error = await response_stream_reader .receive ()
258- except TimeoutError :
259- raise McpError (
260- ErrorData (
261- code = httpx .codes .REQUEST_TIMEOUT ,
262- message = (
263- f"Timed out while waiting for response to "
264- f"{ request .__class__ .__name__ } . Waited "
265- f"{ timeout } seconds."
266- ),
267- )
235+ jsonrpc_request = JSONRPCRequest (
236+ jsonrpc = "2.0" ,
237+ id = request_id ,
238+ ** request .model_dump (by_alias = True , mode = "json" , exclude_none = True ),
268239 )
269240
270- if isinstance (response_or_error , JSONRPCError ):
271- raise McpError (response_or_error .error )
272- else :
273- return result_type .model_validate (response_or_error .result )
241+ # TODO: Support progress callbacks
242+
243+ await self ._write_stream .send (JSONRPCMessage (jsonrpc_request ))
244+
245+ # request read timeout takes precedence over session read timeout
246+ timeout = None
247+ if request_read_timeout_seconds is not None :
248+ timeout = request_read_timeout_seconds .total_seconds ()
249+ elif self ._session_read_timeout_seconds is not None :
250+ timeout = self ._session_read_timeout_seconds .total_seconds ()
251+
252+ try :
253+ with anyio .fail_after (timeout ):
254+ response_or_error = await response_stream_reader .receive ()
255+ except TimeoutError :
256+ raise McpError (
257+ ErrorData (
258+ code = httpx .codes .REQUEST_TIMEOUT ,
259+ message = (
260+ f"Timed out while waiting for response to "
261+ f"{ request .__class__ .__name__ } . Waited "
262+ f"{ timeout } seconds."
263+ ),
264+ )
265+ )
266+
267+ if isinstance (response_or_error , JSONRPCError ):
268+ raise McpError (response_or_error .error )
269+ else :
270+ return result_type .model_validate (response_or_error .result )
271+
272+ finally :
273+ self ._response_streams .pop (request_id , None )
274+ await response_stream .aclose ()
275+ await response_stream_reader .aclose ()
274276
275277 async def send_notification (self , notification : SendNotificationT ) -> None :
276278 """
0 commit comments