Skip to content

fix(ai): follow MCP protected-resource OAuth discovery - #1591

Open
sethkarten wants to merge 2 commits into
mainfrom
feat/mcp-oauth-discovery
Open

fix(ai): follow MCP protected-resource OAuth discovery#1591
sethkarten wants to merge 2 commits into
mainfrom
feat/mcp-oauth-discovery

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Context

Fixes the path-scoped persistent MCP OAuth discovery failure reported in Discussion #1574 and tracked in ENG-5416.

Prime Agent previously reduced every MCP resource URL to its origin and selected root authorization-server metadata. For Plane’s /http/mcp resource, that produces a token for the legacy /sse audience and the MCP endpoint rejects it.

Changes

  • Discover credential-free RFC 9728 protected-resource metadata from WWW-Authenticate or the exact path-and-query well-known URL.
  • Resolve pathful RFC 8414 authorization-server metadata, with OIDC discovery only when the RFC 8414 document is absent.
  • Require exact protected-resource and issuer bindings and fail closed instead of downgrading to a root issuer.
  • Include the RFC 8707 resource indicator in authorization, code exchange, and refresh requests for protected-resource flows.
  • Persist endpoint, resource, issuer, token endpoint, and client identity with OAuth credentials.
  • Revalidate discovery and credential bindings before sending a refresh token.
  • Reject redirects and non-HTTPS metadata, registration, authorization, and token endpoints.
  • Preserve legacy root authorization-server discovery only when protected-resource metadata is absent.

ACP-provided session MCP credentials remain out of scope.

Validation

  • npm run check
  • cd packages/ai && npx tsx ../../node_modules/vitest/dist/cli.js --run test/mcp-oauth.test.ts — 14 passed
  • Independent security review of discovery, downgrade, redirect, endpoint-binding, and refresh behavior

Note

High Risk
Changes OAuth discovery, token exchange, and refresh binding (HTTPS-only endpoints, no redirects, exact issuer/resource matching). Incorrect validation could leak tokens or block legitimate MCP logins.

Overview
MCP OAuth no longer collapses every resource URL to origin-level metadata. Discovery now prefers RFC 9728 protected-resource metadata (from WWW-Authenticate or the path-and-query well-known URL), then pathful RFC 8414/OIDC authorization-server metadata, so path-scoped servers like Plane /http/mcp get the correct audience instead of a root /sse token.

Login and refresh send the RFC 8707 resource indicator when PRM is present, persist resource/issuer with credentials, and fail closed if endpoint, resource, issuer, discovery mode, or token endpoint no longer match. Fetches reject redirects, require HTTPS endpoints, and validate JSON metadata. Origin-only discovery remains only when PRM is absent.

Reviewed by Cursor Bugbot for commit 3d23df3. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix MCP OAuth to follow RFC 9728 protected-resource discovery

  • Login now performs path-scoped protected-resource metadata (PRM) discovery, selects the matching authorization server, and includes resource in authorization and token requests. Returned credentials are bound to endpoint, resource, and issuer.
  • Refresh validates stored binding invariants: checks that credentials match the configured endpoint, that resource/issuer are present together, and that current discovery metadata still matches stored binding. Carries resource on refresh when bound.
  • Authorization server discovery now supports pathful issuers via both RFC 8414 and OIDC metadata URLs, with issuer consistency and content-type validation.
  • Token exchange and metadata fetches now reject HTTP redirects and no longer include response bodies in error messages.
  • McpCredentials gains optional resource and issuer fields; AuthServerMetadata.issuer is now required.
  • Behavioral Change: refresh will fail if stored credentials are not bound to the configured endpoint, have incomplete or mismatched resource/issuer binding, or if discovery mode/metadata changed since login.
📊 Macroscope summarized 3d23df3. 1 file reviewed, 1 issue evaluated, 1 issue filtered, 0 comments posted

🗂️ Filtered Issues

packages/ai/src/mcp/oauth.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 206: When path-scoped protected-resource metadata returns 404, this returns undefined immediately and never probes the required root /.well-known/oauth-protected-resource fallback. MCP permits a path endpoint to publish its metadata at the root; for such a server this falls through to origin authorization-server discovery instead of using the resource's advertised authorization server, so OAuth login obtains the wrong token or fails. [ Out of scope (triage) ]

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2a499d2. Configure here.

Comment thread packages/ai/src/mcp/oauth.ts Outdated
Comment thread packages/ai/src/mcp/oauth.ts Outdated
Comment thread packages/ai/src/mcp/oauth.ts
@sethkarten
sethkarten requested review from Apocrathia and snimu August 20, 2026 22:00
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.

1 participant