Skip to content

fix: ensure appropriate CORS headers for browser based MCP clients#2307

Open
jappievw wants to merge 1 commit into
envoyproxy:mainfrom
jappievw:feature/resolve-cors-issues
Open

fix: ensure appropriate CORS headers for browser based MCP clients#2307
jappievw wants to merge 1 commit into
envoyproxy:mainfrom
jappievw:feature/resolve-cors-issues

Conversation

@jappievw

@jappievw jappievw commented Jul 1, 2026

Copy link
Copy Markdown

Description

This PR ensures that the appropriate CORS headers are included both for the .well-known paths as well as the main MCP route. This allows MCP Inspector to connect to an MCP Server exposed by the AI Gateway.

Related Issues/PRs (if applicable)
The CORS headers implemented to support the MCP Inspector were not functioning properly.

For the .well-known/oauth-protected-resource/mcp path CORS headers were returned, see below:

access-control-allow-headers: mcp-protocol-version
access-control-allow-methods: GET
access-control-allow-origin: *

The access-control-allow-headers and access-control-allow-methods are not needed for the protected resources path.

The OPTIONS preflight request for the /mcp route returns an HTTP 401 due to an authorization error, see response headers below:

HTTP/2 401 
content-length: 0
www-authenticate: Bearer error="invalid_token", error_description="The access token is missing or invalid", resource_metadata="https://mcp.host/.well-known/oauth-protected-resource/mcp", scope="scope1 scope2"
access-control-allow-origin: *
access-control-allow-methods: GET
access-control-allow-headers: mcp-protocol-version

There are two problems with this response:

  • By design, the CORS preflight calls are unauthenticated. Failing due to auth should not be possible.
  • The methods and headers are not sufficient.

Special notes for reviewers (if applicable)
The Envoy SecurityPolicy is now always included to serve the OPTIONS preflight requests and include CORS headers.

This PR has been created with help from Claude (thank you)

@jappievw jappievw requested a review from a team as a code owner July 1, 2026 19:14
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 1, 2026
@jappievw jappievw changed the title Ensure appropriate CORS headers for browser based MCP clients fix: Ensure appropriate CORS headers for browser based MCP clients Jul 1, 2026
@jappievw jappievw changed the title fix: Ensure appropriate CORS headers for browser based MCP clients fix: ensure appropriate CORS headers for browser based MCP clients Jul 1, 2026
Signed-off-by: Jasper van Wanrooy <jasper@vanwanrooy.net>
@jappievw jappievw force-pushed the feature/resolve-cors-issues branch from e77d0d2 to 24dfb04 Compare July 1, 2026 19:23
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.20690% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.93%. Comparing base (53e58b4) to head (24dfb04).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
internal/controller/mcp_route_security_policy.go 86.20% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2307      +/-   ##
==========================================
+ Coverage   84.88%   84.93%   +0.05%     
==========================================
  Files         144      144              
  Lines       21255    21248       -7     
==========================================
+ Hits        18043    18048       +5     
+ Misses       2132     2126       -6     
+ Partials     1080     1074       -6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nacx nacx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! Overall LGTM!

I'm cusious about:

This allows MCP Inspector to connect to an MCP Server exposed by the AI Gateway.

Could you describe what did not work properly? While developing the MCP feature we used the MCP inspector extensively without issues, so I'm wondering what issues you found?

@Hritik003 Hritik003 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for pointing it out, I remember facing this issue while trying out the PoC with MCP Route Oauth. Had to exclusively add the CORS policy for the well known HTTP Route, for the inspector to able to able to send requests.

LGTM, one minor comment

// CORS applies to every MCP route (browser MCP requests are always preflighted). Envoy Gateway orders
// the cors filter ahead of the auth filters, so a preflight OPTIONS is answered and short-circuited
// before jwt_authn/ext_authz — the preflight is never authenticated.
securityPolicySpec.CORS = &egv1a1.CORS{

@Hritik003 Hritik003 Jul 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

does performance concern here by not setting egv1a1.CORS.maxAge( maxAge tells the browser how long it can cache the preflight response) ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants