Skip to content

Conversation

@KKonstantinov
Copy link
Contributor

@KKonstantinov KKonstantinov commented Jan 28, 2026

This PR fixes OAuth authentication flow issues in the better-auth example implementation, enabling compatibility with MCP Inspector in both Direct and Proxy modes.

Thanks @cliffhall for reporting this!

Motivation and Context

The better-auth OAuth implementation in the examples had several issues preventing it from working correctly with MCP clients:

  1. Missing CORS headers - Browser-based clients couldn't fetch OAuth metadata or make authenticated requests
  2. Wrong metadata path - Protected resource metadata was served at /.well-known/oauth-protected-resource instead of RFC 9728-compliant /.well-known/oauth-protected-resource/mcp (per MCP Authorization Spec)
  3. Incompatible WWW-Authenticate header format - The header was missing error and error_description fields that MCP Inspector's proxy expects

How Has This Been Tested?

  • Tested with MCP Inspector in Direct mode - OAuth flow completes successfully
  • Tested with MCP Inspector in Proxy mode - OAuth flow completes successfully
  • Verified OAuth metadata endpoints return correct CORS headers
  • Verified protected resource metadata is served at correct RFC 9728 path
  • Verified WWW-Authenticate header format matches v1.x implementation

Breaking Changes

No breaking changes. The createProtectedResourceMetadataRouter() function now accepts an optional resourcePath parameter (defaults to '/mcp'), but existing calls without the parameter will continue to work.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Key changes:

CORS Configuration:

  • Added cors middleware to MCP server with exposed headers for WWW-Authenticate and Mcp-Session-Id
  • Added cors middleware to auth server for all OAuth endpoints
  • Added explicit OPTIONS handlers for metadata endpoints

RFC 9728 Compliance:

  • createProtectedResourceMetadataRouter(resourcePath) now serves metadata at the path-specific URL (e.g., /.well-known/oauth-protected-resource/mcp)
  • Per MCP Authorization Specification: MCP servers MUST implement RFC 9728 and serve metadata at the path of the server's MCP endpoint

WWW-Authenticate Header:

  • Updated format to match v1.x: Bearer error="invalid_token", error_description="...", resource_metadata="..."
  • This is required for MCP Inspector's proxy mode which uses the v1.x client SDK

Debug Logging:

  • Added --dangerous-logging-enabled CLI flag to enable verbose better-auth request/response logging
  • Disabled by default to avoid logging sensitive information (tokens, cookies)

TypeScript Configuration:

  • Disabled declaration and declarationMap in examples/shared/tsconfig.json to avoid TS4058 error with better-auth's internal MCPOptions type - it's not exported out of the better-auth package (TBD: Raise an issue on better-auth). Since we are not building and publishing this package, it should be fine to disable these for the example package.

Dependency Upgrades:

  • Upgraded better-auth to latest version
  • Upgraded better-sqlite3 to latest version

@KKonstantinov KKonstantinov requested a review from a team as a code owner January 28, 2026 07:22
@changeset-bot
Copy link

changeset-bot bot commented Jan 28, 2026

⚠️ No Changeset found

Latest commit: b24d7e7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 1 package
Name Type
@modelcontextprotocol/client Patch

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 28, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1427

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1427

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1427

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1427

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1427

commit: b24d7e7

Copy link
Member

@cliffhall cliffhall left a comment

Choose a reason for hiding this comment

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

A couple of extra headers the MCP client needs to see. And explicit "*" origin.

pcarleton
pcarleton previously approved these changes Jan 28, 2026
Copy link
Member

@pcarleton pcarleton left a comment

Choose a reason for hiding this comment

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

These changes look good to me!

wondering if an optional conformance test for "Browser client compatibility" would be helpful to help highlight when servers don't have this set

Copy link
Member

@cliffhall cliffhall left a comment

Choose a reason for hiding this comment

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

Woops. Left off a comma in the suggestion

});
authApp.use(
cors({
exposedHeaders: ['WWW-Authenticate']
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
exposedHeaders: ['WWW-Authenticate']
exposedHeaders: ['WWW-Authenticate'],

@KKonstantinov
Copy link
Contributor Author

KKonstantinov commented Jan 28, 2026

These changes look good to me!

wondering if an optional conformance test for "Browser client compatibility" would be helpful to help highlight when servers don't have this set

@pcarleton I believe so, yes! It'll be very helpful to nail these scenarios down, so they're kind of set in stone

@KKonstantinov KKonstantinov merged commit b0ef89f into modelcontextprotocol:main Jan 28, 2026
10 checks passed
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.

3 participants