Skip to content

client: preserve OAuth discovery metadata across browser redirects#1816

Open
windro-xdd wants to merge 35 commits intomodelcontextprotocol:mainfrom
windro-xdd:fix/oauth-redirect-preserve-resource-metadata
Open

client: preserve OAuth discovery metadata across browser redirects#1816
windro-xdd wants to merge 35 commits intomodelcontextprotocol:mainfrom
windro-xdd:fix/oauth-redirect-preserve-resource-metadata

Conversation

@windro-xdd
Copy link
Copy Markdown

@windro-xdd windro-xdd commented Mar 29, 2026

Summary

  • persist interactive OAuth metadata (resource_metadata URL and scope) in browser sessionStorage for both Streamable HTTP and SSE client transports
  • restore that state on transport construction so finishAuth() works after full-page redirects
  • clear persisted state after successful authorization to avoid stale auth context
  • add regression tests for transport recreation + post-redirect finishAuth() on both transports

Why

finishAuth() can fail in browser redirect flows when the original transport instance is lost and the WWW-Authenticate metadata extracted before redirect is no longer in memory. Persisting and restoring this metadata keeps token exchange on the same discovered authorization path.

Validation

  • pnpm --filter @modelcontextprotocol/client typecheck
  • pnpm --filter @modelcontextprotocol/client lint
  • pnpm --filter @modelcontextprotocol/client test -- test/client/streamableHttp.test.ts test/client/sse.test.ts

Closes #1234

@windro-xdd windro-xdd requested a review from a team as a code owner March 29, 2026 14:43
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 29, 2026

🦋 Changeset detected

Latest commit: 317fec5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/express Patch
@modelcontextprotocol/fastify Patch
@modelcontextprotocol/hono Patch
@modelcontextprotocol/node Patch

Not sure what this means? Click here to learn what changesets are.

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

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 29, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@1816

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@1816

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@1816

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@1816

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@1816

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@1816

commit: 317fec5

felixweinberger and others added 2 commits March 30, 2026 13:56
…odelcontextprotocol#1772)

Co-authored-by: jnMetaCode <147776183+jnMetaCode@users.noreply.github.com>
Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
@felixweinberger felixweinberger added the auth Issues and PRs related to Authentication / OAuth label Mar 30, 2026
wdawson and others added 17 commits March 30, 2026 18:11
Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
…protocol#1632)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
…delcontextprotocol#1652)

Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
…delcontextprotocol#1824)

Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
…extprotocol#1390)

Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
modelcontextprotocol#1825)

Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
Copy link
Copy Markdown
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.

Hi, you should be able to do this with loadDiscoveryState / saveDiscoveryState, could be in an example implementation of OAuthProvider

andyfleming and others added 4 commits March 31, 2026 13:51
Co-authored-by: Felix Weinberger <fweinberger@anthropic.com>
Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
…lcontextprotocol#1660)

Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
@km-anthropic
Copy link
Copy Markdown

@claude review

felixweinberger and others added 11 commits April 1, 2026 13:30
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…uestedSchema (modelcontextprotocol#1768)

Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
…ansport (modelcontextprotocol#1655)

Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
Co-authored-by: Felix Weinberger <fweinberger@anthropic.com>
…odelcontextprotocol#1552)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…modelcontextprotocol#1788)

Co-authored-by: Felix Weinberger <fweinberger@anthropic.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
… redirects

Add OAuthProvider class to enable stateful OAuth flows in browser-based
applications. The provider persists discovery state (resource metadata URL,
scopes) across OAuth redirects using sessionStorage with automatic 15-minute
expiry, graceful degradation when storage is unavailable, and comprehensive
error handling.

Key features:
- saveDiscoveryState/loadDiscoveryState for state persistence
- Automatic timestamp-based expiry validation
- getAuthorizationUrl for RFC 6749 OAuth 2.0 compatibility
- Createable client transport with restored state
- Graceful handling of missing sessionStorage (private browsing)
- Try-catch wrapped storage operations

Includes:
- Full implementation with JSDoc documentation
- Comprehensive test suite (state persistence, expiry, error handling)
- OAuth_REDIRECT_EXAMPLE.md with usage patterns and security notes

Fixes the issue of losing discovery state during browser redirects in
interactive OAuth flows when implementing MCP-compatible web applications.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Issues and PRs related to Authentication / OAuth

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth: Resource metadata URL lost after redirect, causing token exchange to fail