@@ -118,20 +118,34 @@ def _proxy(self, method: str):
118118 self ._forward (method , gateway_url , upstream_headers , body )
119119
120120 def _forward (self , method : str , url : str , headers : dict , body : bytes | None ):
121- """Forward a non- streaming request ."""
121+ """Forward a request, streaming if the response is SSE ."""
122122 try :
123- resp = client .request (method , url , headers = headers , content = body )
123+ # Use a streaming request so we can detect SSE responses
124+ # before reading the full body.
125+ with httpx .stream (
126+ method , url , headers = headers , content = body ,
127+ timeout = httpx .Timeout (120.0 , connect = 10.0 ),
128+ ) as resp :
129+ content_type = resp .headers .get ("content-type" , "" )
130+ is_sse = "text/event-stream" in content_type
131+
132+ self .send_response (resp .status_code )
133+ for k , v in resp .headers .items ():
134+ if k .lower () not in ("transfer-encoding" , "connection" ):
135+ self .send_header (k , v )
136+ self .end_headers ()
137+
138+ if is_sse :
139+ # Stream SSE chunks with flushing so the MCP client
140+ # receives events incrementally instead of timing out.
141+ for chunk in resp .iter_bytes ():
142+ self .wfile .write (chunk )
143+ self .wfile .flush ()
144+ else :
145+ self .wfile .write (resp .read ())
124146 except httpx .HTTPError as e :
125147 logger .error ("upstream request failed: %s" , e )
126148 self .send_error (502 , "upstream request failed" )
127- return
128-
129- self .send_response (resp .status_code )
130- for k , v in resp .headers .items ():
131- if k .lower () not in ("transfer-encoding" , "connection" ):
132- self .send_header (k , v )
133- self .end_headers ()
134- self .wfile .write (resp .content )
135149
136150 def _stream_sse (self , url : str , headers : dict ):
137151 """Stream an SSE response, rewriting gateway URLs to localhost."""
0 commit comments