From 5f2c55c865c2b78819d97c74a6696c40901af2eb Mon Sep 17 00:00:00 2001 From: Chris Farhood Date: Mon, 6 Jul 2026 22:13:36 -0400 Subject: [PATCH] mcp: CORS on the streamable-http app (answer OPTIONS preflight without auth) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OPTIONS /mcp returned 401 (auth layer rejecting the preflight) with no CORS headers, which blocks browser-based MCP clients / connector setup. Build the app explicitly and add CORSMiddleware (wildcard origin — bearer-token auth, no cookies) so preflight is answered 200 and Mcp-Session-Id/WWW-Authenticate are exposed. --- src/intervals_mcp_server/server_setup.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/intervals_mcp_server/server_setup.py b/src/intervals_mcp_server/server_setup.py index 698b613..6fad2af 100644 --- a/src/intervals_mcp_server/server_setup.py +++ b/src/intervals_mcp_server/server_setup.py @@ -69,10 +69,25 @@ def start_server(mcp_instance: FastMCP, transport: TransportAliases) -> None: ) mcp_instance.run(transport="sse", mount_path=mount_path) else: # STREAMABLE_HTTP + import uvicorn # noqa: PLC0415 + from starlette.middleware.cors import CORSMiddleware # noqa: PLC0415 + logger.info( "Starting MCP server with Streamable HTTP transport at http://%s:%s%s.", host, port, mcp_instance.settings.streamable_http_path, ) - mcp_instance.run(transport="streamable-http") + app = mcp_instance.streamable_http_app() + # CORS so browser-based MCP clients / connector setup can reach /mcp — the + # preflight is what matters: CORSMiddleware answers OPTIONS directly (200) + # instead of the auth layer rejecting it (401). Bearer-token auth, no + # cookies, so a wildcard origin is safe; expose the headers clients read. + app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_methods=["*"], + allow_headers=["*"], + expose_headers=["Mcp-Session-Id", "WWW-Authenticate"], + ) + uvicorn.run(app, host=host, port=port, log_level=os.getenv("FASTMCP_LOG_LEVEL", "info").lower())