From ceda49025eb2f248a09277d6d2f00a84223d0447 Mon Sep 17 00:00:00 2001 From: TheRealSeber Date: Thu, 7 Aug 2025 10:23:33 +0800 Subject: [PATCH 1/3] fix: allow preflight options request for streamable http --- src/mcp/server/streamable_http.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/mcp/server/streamable_http.py b/src/mcp/server/streamable_http.py index 802cb8680..aaf3e8d3a 100644 --- a/src/mcp/server/streamable_http.py +++ b/src/mcp/server/streamable_http.py @@ -286,6 +286,8 @@ async def handle_request(self, scope: Scope, receive: Receive, send: Send) -> No await self._handle_get_request(request, send) elif request.method == "DELETE": await self._handle_delete_request(request, send) + elif await request.method == "OPTIONS": + await self._handle_options_request(request, send) else: await self._handle_unsupported_request(request, send) @@ -620,6 +622,21 @@ async def _handle_delete_request(self, request: Request, send: Send) -> None: ) await response(request.scope, request.receive, send) + async def _handle_options_request(self, request: Request, send: Send) -> None: + """Handle OPTIONS requests for CORS preflight.""" + headers = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS", + "Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers", "") + } + + response = Response( + content=None, + status_code=HTTPStatus.NO_CONTENT, + headers=headers + ) + await response(request.scope, request.receive, send) + async def terminate(self) -> None: """Terminate the current session, closing all streams. From 2d5212b7e559afcbb1a9a2c01757fcb0dca55293 Mon Sep 17 00:00:00 2001 From: TheRealSeber Date: Thu, 7 Aug 2025 10:28:56 +0800 Subject: [PATCH 2/3] chore: run lint --- src/mcp/server/streamable_http.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/mcp/server/streamable_http.py b/src/mcp/server/streamable_http.py index aaf3e8d3a..442a23750 100644 --- a/src/mcp/server/streamable_http.py +++ b/src/mcp/server/streamable_http.py @@ -627,14 +627,10 @@ async def _handle_options_request(self, request: Request, send: Send) -> None: headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS", - "Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers", "") + "Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers", ""), } - response = Response( - content=None, - status_code=HTTPStatus.NO_CONTENT, - headers=headers - ) + response = Response(content=None, status_code=HTTPStatus.NO_CONTENT, headers=headers) await response(request.scope, request.receive, send) async def terminate(self) -> None: From 26ed405d43e7db8d26c93bf797c0ae208ca55845 Mon Sep 17 00:00:00 2001 From: TheRealSeber Date: Thu, 7 Aug 2025 10:39:12 +0800 Subject: [PATCH 3/3] fix: typo --- src/mcp/server/streamable_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcp/server/streamable_http.py b/src/mcp/server/streamable_http.py index 442a23750..b44147f2f 100644 --- a/src/mcp/server/streamable_http.py +++ b/src/mcp/server/streamable_http.py @@ -286,7 +286,7 @@ async def handle_request(self, scope: Scope, receive: Receive, send: Send) -> No await self._handle_get_request(request, send) elif request.method == "DELETE": await self._handle_delete_request(request, send) - elif await request.method == "OPTIONS": + elif request.method == "OPTIONS": await self._handle_options_request(request, send) else: await self._handle_unsupported_request(request, send)