1313
1414if TYPE_CHECKING :
1515 from mcp .server import Server
16+ from mcp .server .sse import SseServerTransport
1617 from mcp .server .streamable_http_manager import StreamableHTTPSessionManager
1718
1819 from .toolset import Toolset
1920else :
2021 try :
2122 from mcp .server import Server
23+ from mcp .server .sse import SseServerTransport
2224 from mcp .server .streamable_http_manager import StreamableHTTPSessionManager
2325 except ImportError :
2426 Server = None
27+ SseServerTransport = None
2528 StreamableHTTPSessionManager = None
2629
2730
@@ -316,14 +319,7 @@ async def handle_streamable_http(
316319 scope : Scope , receive : Receive , send : Send
317320 ) -> None :
318321 path = scope .get ("path" , "" )
319- if not path .endswith (
320- (
321- "/gradio_api/mcp" ,
322- "/gradio_api/mcp/" ,
323- "/gradio_api/mcp/http" ,
324- "/gradio_api/mcp/http/" ,
325- )
326- ):
322+ if not path .startswith ("/gradio_api/mcp" ):
327323 response = Response (
328324 content = f"Path '{ path } ' not found. The MCP HTTP transport is available at /gradio_api/mcp." ,
329325 status_code = 404 ,
@@ -336,6 +332,38 @@ async def handle_streamable_http(
336332 async def get_schema (request : Request ) -> JSONResponse :
337333 return _get_complete_schema (toolset , request )
338334
335+ async def handle_sse (request : Request ) -> Response :
336+ """
337+ Handle SSE (Server-Sent Events) connections for MCP transport.
338+
339+ Args:
340+ request: The Starlette request object.
341+
342+ Returns:
343+ A Response object.
344+ """
345+ if SseServerTransport is None :
346+ return Response (
347+ content = "SSE transport is not available. Please install the mcp package." ,
348+ status_code = 503 ,
349+ )
350+
351+ try :
352+ messages_path = "/messages/"
353+ sse = SseServerTransport (messages_path )
354+ async with sse .connect_sse (
355+ request .scope , request .receive , request ._send
356+ ) as streams :
357+ await mcp_server .run (
358+ streams [0 ],
359+ streams [1 ],
360+ mcp_server .create_initialization_options (),
361+ )
362+ return Response ()
363+ except Exception as e :
364+ print (f"MCP SSE connection error: { str (e )} " )
365+ raise
366+
339367 @contextlib .asynccontextmanager
340368 async def mcp_lifespan (app : Starlette ) -> AsyncIterator [None ]:
341369 async with manager .run ():
@@ -344,12 +372,26 @@ async def mcp_lifespan(app: Starlette) -> AsyncIterator[None]:
344372 finally :
345373 pass
346374
347- mcp_app = Starlette (
348- routes = [
349- Route ("/schema" , endpoint = get_schema ),
350- Mount ("/" , app = handle_streamable_http ),
351- ],
352- )
375+ sse = None
376+ if SseServerTransport is not None :
377+ messages_path = "/messages/"
378+ sse = SseServerTransport (messages_path )
379+
380+ routes = [
381+ Route ("/schema" , endpoint = get_schema ),
382+ ]
383+
384+ if sse is not None :
385+ routes .extend (
386+ [
387+ Route ("/sse" , endpoint = handle_sse ),
388+ Mount ("/messages/" , app = sse .handle_post_message ),
389+ ]
390+ )
391+
392+ routes .append (Mount ("/" , app = handle_streamable_http ))
393+
394+ mcp_app = Starlette (routes = routes )
353395
354396 original_create_app = gr .routes .App .create_app
355397
0 commit comments