From 0970ef4ae026c38cab6d010a990b6c38635b982a Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 30 Dec 2024 10:04:19 -0800 Subject: [PATCH 1/3] Fix SSE server bug with uncaught TypeError --- .../servers/simple-prompt/mcp_simple_prompt/server.py | 9 +++------ .../simple-resource/mcp_simple_resource/server.py | 9 +++------ examples/servers/simple-tool/mcp_simple_tool/server.py | 9 +++------ src/mcp/server/fastmcp/server.py | 9 +++------ src/mcp/server/sse.py | 2 +- 5 files changed, 13 insertions(+), 25 deletions(-) diff --git a/examples/servers/simple-prompt/mcp_simple_prompt/server.py b/examples/servers/simple-prompt/mcp_simple_prompt/server.py index 8427b12f87..351099f6ee 100644 --- a/examples/servers/simple-prompt/mcp_simple_prompt/server.py +++ b/examples/servers/simple-prompt/mcp_simple_prompt/server.py @@ -90,9 +90,9 @@ async def get_prompt( if transport == "sse": from mcp.server.sse import SseServerTransport from starlette.applications import Starlette - from starlette.routing import Route + from starlette.routing import Route, Mount - sse = SseServerTransport("/messages") + sse = SseServerTransport("/messages/") async def handle_sse(request): async with sse.connect_sse( @@ -102,14 +102,11 @@ async def handle_sse(request): streams[0], streams[1], app.create_initialization_options() ) - async def handle_messages(request): - await sse.handle_post_message(request.scope, request.receive, request._send) - starlette_app = Starlette( debug=True, routes=[ Route("/sse", endpoint=handle_sse), - Route("/messages", endpoint=handle_messages, methods=["POST"]), + Mount("/messages/", app=sse.handle_post_message) ], ) diff --git a/examples/servers/simple-resource/mcp_simple_resource/server.py b/examples/servers/simple-resource/mcp_simple_resource/server.py index 9864fc519d..51f2933c67 100644 --- a/examples/servers/simple-resource/mcp_simple_resource/server.py +++ b/examples/servers/simple-resource/mcp_simple_resource/server.py @@ -47,9 +47,9 @@ async def read_resource(uri: AnyUrl) -> str | bytes: if transport == "sse": from mcp.server.sse import SseServerTransport from starlette.applications import Starlette - from starlette.routing import Route + from starlette.routing import Route, Mount - sse = SseServerTransport("/messages") + sse = SseServerTransport("/messages/") async def handle_sse(request): async with sse.connect_sse( @@ -59,14 +59,11 @@ async def handle_sse(request): streams[0], streams[1], app.create_initialization_options() ) - async def handle_messages(request): - await sse.handle_post_message(request.scope, request.receive, request._send) - starlette_app = Starlette( debug=True, routes=[ Route("/sse", endpoint=handle_sse), - Route("/messages", endpoint=handle_messages, methods=["POST"]), + Mount("/messages/", app=sse.handle_post_message), ], ) diff --git a/examples/servers/simple-tool/mcp_simple_tool/server.py b/examples/servers/simple-tool/mcp_simple_tool/server.py index 79b0b8b528..039af9e81d 100644 --- a/examples/servers/simple-tool/mcp_simple_tool/server.py +++ b/examples/servers/simple-tool/mcp_simple_tool/server.py @@ -60,9 +60,9 @@ async def list_tools() -> list[types.Tool]: if transport == "sse": from mcp.server.sse import SseServerTransport from starlette.applications import Starlette - from starlette.routing import Route + from starlette.routing import Route, Mount - sse = SseServerTransport("/messages") + sse = SseServerTransport("/messages/") async def handle_sse(request): async with sse.connect_sse( @@ -72,14 +72,11 @@ async def handle_sse(request): streams[0], streams[1], app.create_initialization_options() ) - async def handle_messages(request): - await sse.handle_post_message(request.scope, request.receive, request._send) - starlette_app = Starlette( debug=True, routes=[ Route("/sse", endpoint=handle_sse), - Route("/messages", endpoint=handle_messages, methods=["POST"]), + Mount("/messages/", app=sse.handle_post_message), ], ) diff --git a/src/mcp/server/fastmcp/server.py b/src/mcp/server/fastmcp/server.py index f0909287d6..5b657072ee 100644 --- a/src/mcp/server/fastmcp/server.py +++ b/src/mcp/server/fastmcp/server.py @@ -423,9 +423,9 @@ async def run_stdio_async(self) -> None: async def run_sse_async(self) -> None: """Run the server using SSE transport.""" from starlette.applications import Starlette - from starlette.routing import Route + from starlette.routing import Route, Mount - sse = SseServerTransport("/messages") + sse = SseServerTransport("/messages/") async def handle_sse(request): async with sse.connect_sse( @@ -437,14 +437,11 @@ async def handle_sse(request): self._mcp_server.create_initialization_options(), ) - async def handle_messages(request): - await sse.handle_post_message(request.scope, request.receive, request._send) - starlette_app = Starlette( debug=self.settings.debug, routes=[ Route("/sse", endpoint=handle_sse), - Route("/messages", endpoint=handle_messages, methods=["POST"]), + Mount("/messages/", app=sse.handle_post_message), ], ) diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py index 3062b32446..0f50023523 100644 --- a/src/mcp/server/sse.py +++ b/src/mcp/server/sse.py @@ -11,7 +11,7 @@ # Create Starlette routes for SSE and message handling routes = [ Route("/sse", endpoint=handle_sse), - Route("/messages", endpoint=handle_messages, methods=["POST"]) + Mount("/messages", endpoint=handle_messages, methods=["POST"]) ] # Define handler functions From 1134421a3af7950e609f2b595bf18296d4626b16 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 30 Dec 2024 10:08:57 -0800 Subject: [PATCH 2/3] Fix inconsistencies in examples --- examples/servers/simple-prompt/mcp_simple_prompt/server.py | 2 +- src/mcp/server/sse.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/servers/simple-prompt/mcp_simple_prompt/server.py b/examples/servers/simple-prompt/mcp_simple_prompt/server.py index 351099f6ee..89b0eeaf63 100644 --- a/examples/servers/simple-prompt/mcp_simple_prompt/server.py +++ b/examples/servers/simple-prompt/mcp_simple_prompt/server.py @@ -106,7 +106,7 @@ async def handle_sse(request): debug=True, routes=[ Route("/sse", endpoint=handle_sse), - Mount("/messages/", app=sse.handle_post_message) + Mount("/messages/", app=sse.handle_post_message), ], ) diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py index 0f50023523..96410bbf59 100644 --- a/src/mcp/server/sse.py +++ b/src/mcp/server/sse.py @@ -11,7 +11,7 @@ # Create Starlette routes for SSE and message handling routes = [ Route("/sse", endpoint=handle_sse), - Mount("/messages", endpoint=handle_messages, methods=["POST"]) + Mount("/messages", app=sse.handle_post_message), ] # Define handler functions @@ -23,9 +23,6 @@ async def handle_sse(request): streams[0], streams[1], app.create_initialization_options() ) - async def handle_messages(request): - await sse.handle_post_message(request.scope, request.receive, request._send) - # Create and run Starlette app starlette_app = Starlette(routes=routes) uvicorn.run(starlette_app, host="0.0.0.0", port=port) From 247aec9332665226f7b5a5aae348c37419a722bc Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 30 Dec 2024 10:09:42 -0800 Subject: [PATCH 3/3] Update paths in examples --- src/mcp/server/sse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py index 96410bbf59..0127753d01 100644 --- a/src/mcp/server/sse.py +++ b/src/mcp/server/sse.py @@ -6,12 +6,12 @@ Example usage: ``` # Create an SSE transport at an endpoint - sse = SseServerTransport("/messages") + sse = SseServerTransport("/messages/") # Create Starlette routes for SSE and message handling routes = [ Route("/sse", endpoint=handle_sse), - Mount("/messages", app=sse.handle_post_message), + Mount("/messages/", app=sse.handle_post_message), ] # Define handler functions