Skip to content

feat: Add CORS configuration for browser-based MCP clients #1059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 21, 2025

Conversation

jerome3o-anthropic
Copy link
Member

Summary

  • Add CORS middleware to streamable HTTP example servers
  • Configure minimal CORS settings to expose Mcp-Session-Id header
  • Add documentation for CORS configuration in the README

Problem

Browser-based MCP clients cannot access the Mcp-Session-Id header from initialization responses due to CORS restrictions. Without this header, they cannot establish sessions with MCP servers.

Solution

This PR adds Starlette's CORSMiddleware to the example servers and configures it to expose the Mcp-Session-Id header via expose_headers. The configuration is minimal, only allowing the HTTP methods required by the MCP protocol (GET, POST, DELETE).

Changes

  • Add CORSMiddleware import and configuration to:
    • examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py
    • examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py
  • Add CORS configuration section to README under "Streamable HTTP Transport"

Test plan

  • Example servers start successfully with CORS configured
  • Browser-based clients can read the Mcp-Session-Id header from responses
  • CORS headers are properly set on responses
  • Only GET, POST, and DELETE methods are allowed

Reported-by: Jerome

Comment on lines 135 to 142

# Add CORS middleware to expose Mcp-Session-Id header for browser-based clients
starlette_app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allow all origins - adjust as needed for production
allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods
expose_headers=["Mcp-Session-Id"],
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to wrap the whole application instead of using add_middleware, otherwise 500s don't get in this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

- Add CORSMiddleware to streamable HTTP example servers
- Configure minimal CORS with Mcp-Session-Id exposed
- Add CORS documentation section to README

This enables browser-based clients to connect to MCP servers by properly
exposing the Mcp-Session-Id header required for session management.

Reported-by: Jerome
@jerome3o-anthropic jerome3o-anthropic force-pushed the jerome/cors-browser-support branch from 7a554e7 to 28aaa02 Compare July 4, 2025 15:22
@felixweinberger felixweinberger requested review from felixweinberger and removed request for felixweinberger July 6, 2025 11:10
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
@jerome3o-anthropic jerome3o-anthropic requested a review from Kludex July 7, 2025 12:53
Kludex
Kludex previously approved these changes Jul 7, 2025
@felixweinberger felixweinberger removed their request for review July 8, 2025 13:53
Copy link
Contributor

@felixweinberger felixweinberger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes to put back in your queue for fixing CI

@Kludex
Copy link
Member

Kludex commented Jul 10, 2025

Requesting changes to put back in your queue for fixing CI

That's a flaky test.

@ihrpr
Copy link
Contributor

ihrpr commented Jul 10, 2025

We still need to address comment in #1059 (comment) for examples, only readme was changed, right?

- Change from add_middleware() to CORSMiddleware wrapper pattern
- Ensures 500 errors get proper CORS headers for browser clients
- Update both streamable HTTP example servers
- Fix README documentation to show complete example

Reported-by: Jerome
@felixweinberger felixweinberger requested a review from a team as a code owner August 21, 2025 13:09
@felixweinberger felixweinberger self-requested a review August 21, 2025 13:09
@felixweinberger felixweinberger dismissed their stale review August 21, 2025 13:11

Dismissing my own review

@felixweinberger felixweinberger requested a review from ihrpr August 21, 2025 13:11
Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@ihrpr ihrpr merged commit 09e3a05 into main Aug 21, 2025
21 checks passed
@ihrpr ihrpr deleted the jerome/cors-browser-support branch August 21, 2025 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants