Skip to content

fix(mcp): strip trailing slash from OAuth resource parameter#14001

Open
venkat22022202 wants to merge 2 commits intovercel:mainfrom
venkat22022202:fix/mcp-oauth-resource-trailing-slash
Open

fix(mcp): strip trailing slash from OAuth resource parameter#14001
venkat22022202 wants to merge 2 commits intovercel:mainfrom
venkat22022202:fix/mcp-oauth-resource-trailing-slash

Conversation

@venkat22022202
Copy link
Copy Markdown

Summary

Fixes #13988

new URL("https://mcp.example.com").href returns "https://mcp.example.com/" per the URL spec. Auth servers that do exact matching on the resource parameter reject the request because the trailing slash makes it a different URI than what was registered.

Fix

Strip trailing slash from resource.href in all three locations where it's used as an OAuth parameter:

  • startAuthorization (line 454)
  • exchangeAuthorization (line 678)
  • refreshAuthorization (line 765)
- params.set('resource', resource.href);
+ params.set('resource', resource.href.replace(/\/$/, ''));

Why this is correct

The MCP spec explicitly recommends the form without trailing slash for better interoperability:

implementations SHOULD consistently use the form without the trailing slash

Source: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#canonical-server-uri

Test plan

  • MCP servers with pathless resource URLs (e.g. https://mcp.example.com) should no longer get rejected by auth servers doing exact match
  • MCP servers with path-based resource URLs (e.g. https://mcp.example.com/api) are unaffected (no trailing slash to strip)

`new URL("https://mcp.example.com").href` returns
"https://mcp.example.com/" per the URL spec. Auth servers that do
exact matching on the resource parameter reject the request because
the trailing slash makes it a different URI than what was registered.

The MCP spec recommends the form without trailing slash:
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#canonical-server-uri

Fix: strip trailing slash from `resource.href` in all three locations
where it's used as an OAuth parameter (startAuthorization,
exchangeAuthorization, refreshAuthorization).

Fixes vercel#13988
@tigent tigent bot added ai/mcp related to `@ai-sdk/mcp` package bug Something isn't working as documented labels Apr 1, 2026
Address review feedback: the blanket regex would strip trailing slashes
from path-based resource URIs like https://host/api/ which may be
intentional.

Extract canonicalResourceUri() helper that only strips the trailing
slash when pathname is exactly "/" (origin-only URL). Path-based
resource URIs are left unchanged.
@venkat22022202
Copy link
Copy Markdown
Author

Good catch — fixed in 8206bfa.

Extracted a canonicalResourceUri() helper that only strips the trailing slash when resource.pathname === '/' (origin-only URL like https://mcp.example.com/). Path-based resource URIs like https://mcp.example.com/api/ are now left unchanged.

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

Labels

ai/mcp related to `@ai-sdk/mcp` package bug Something isn't working as documented

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth resource parameter gets trailing slash from URL.href, breaking auth servers that do exact matching

1 participant