Skip to content

Commit dba5dab

Browse files
Theodor N. EngøyTheodor N. Engøy
authored andcommitted
docs/examples: safer CORS allowlist for StreamableHTTP
1 parent dda845a commit dba5dab

File tree

4 files changed

+12
-4
lines changed

4 files changed

+12
-4
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,9 @@ starlette_app = Starlette(routes=[...])
13631363
# Then wrap it with CORS middleware
13641364
starlette_app = CORSMiddleware(
13651365
starlette_app,
1366-
allow_origins=["*"], # Configure appropriately for production
1366+
# Allow browser-based clients (ChatGPT + local dev). For production, prefer
1367+
# a strict allowlist of known UI origins.
1368+
allow_origin_regex=r"^https://(chatgpt\.com|chat\.openai\.com)$|^https?://(localhost|127\.0\.0\.1)(:\d+)?$",
13671369
allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods
13681370
expose_headers=["Mcp-Session-Id"],
13691371
)

README.v2.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,9 @@ starlette_app = Starlette(routes=[...])
13641364
# Then wrap it with CORS middleware
13651365
starlette_app = CORSMiddleware(
13661366
starlette_app,
1367-
allow_origins=["*"], # Configure appropriately for production
1367+
# Allow browser-based clients (ChatGPT + local dev). For production, prefer
1368+
# a strict allowlist of known UI origins.
1369+
allow_origin_regex=r"^https://(chatgpt\.com|chat\.openai\.com)$|^https?://(localhost|127\.0\.0\.1)(:\d+)?$",
13681370
allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods
13691371
expose_headers=["Mcp-Session-Id"],
13701372
)

examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ async def lifespan(app: Starlette) -> AsyncIterator[None]:
127127
# for browser-based clients (ensures 500 errors get proper CORS headers)
128128
starlette_app = CORSMiddleware(
129129
starlette_app,
130-
allow_origins=["*"], # Allow all origins - adjust as needed for production
130+
# Allow browser-based clients (ChatGPT + local dev). For production, prefer
131+
# a strict allowlist of known UI origins.
132+
allow_origin_regex=r"^https://(chatgpt\.com|chat\.openai\.com)$|^https?://(localhost|127\.0\.0\.1)(:\d+)?$",
131133
allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods
132134
expose_headers=["Mcp-Session-Id"],
133135
)

examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ async def lifespan(app: Starlette) -> AsyncIterator[None]:
152152
# for browser-based clients (ensures 500 errors get proper CORS headers)
153153
starlette_app = CORSMiddleware(
154154
starlette_app,
155-
allow_origins=["*"], # Allow all origins - adjust as needed for production
155+
# Allow browser-based clients (ChatGPT + local dev). For production, prefer
156+
# a strict allowlist of known UI origins.
157+
allow_origin_regex=r"^https://(chatgpt\.com|chat\.openai\.com)$|^https?://(localhost|127\.0\.0\.1)(:\d+)?$",
156158
allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods
157159
expose_headers=["Mcp-Session-Id"],
158160
)

0 commit comments

Comments
 (0)