Skip to content

fix: ensure DCR always registers both redirect URIs#1173

Merged
cliffhall merged 1 commit into
modelcontextprotocol:mainfrom
asoorm:fix/930-redirect-uri-mismatch
Apr 2, 2026
Merged

fix: ensure DCR always registers both redirect URIs#1173
cliffhall merged 1 commit into
modelcontextprotocol:mainfrom
asoorm:fix/930-redirect-uri-mismatch

Conversation

@asoorm
Copy link
Copy Markdown
Contributor

@asoorm asoorm commented Apr 2, 2026

Disclaimer: Claude Code was used to assist with investigating this issue, writing the root cause analysis, and drafting this PR.

Summary

Fixes a redirect_uri mismatch between Dynamic Client Registration and the authorize request, caused by the redirect_uris getter using a polymorphic this.redirectUrl that the debug subclass overrides.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Refactoring (no functional changes)
  • Test updates
  • Build/CI improvements

Changes Made

The redirect_uris getter in InspectorOAuthClientProvider used this.redirectUrl, which DebugInspectorOAuthClientProvider overrides to return /oauth/callback/debug. This caused Set deduplication to collapse both URIs into one during DCR, so only /oauth/callback/debug was registered. The normal connection flow then sent redirect_uri=/oauth/callback in the authorize request — which was never registered — causing spec-compliant OAuth servers to reject it.

The fix references the base callback URLs directly instead of going through the polymorphic getter, ensuring both /oauth/callback and /oauth/callback/debug are always registered.

Related Issues

Fixes #930

Testing

  • Tested in UI mode
  • Tested in CLI mode
  • Tested with STDIO transport
  • Tested with SSE transport
  • Tested with Streamable HTTP transport
  • Added/updated automated tests
  • Manual testing performed

Test Results and/or Instructions

  1. Run npm run dev
  2. Point inspector at an OAuth-enabled MCP server with a strict OAuth authorization server (one that enforces redirect URI validation)
  3. Open the Auth Debugger tab and initiate the guided OAuth flow
  4. Verify the DCR payload contains both redirect URIs: /oauth/callback and /oauth/callback/debug
  5. Verify the authorize request's redirect_uri matches one of the registered URIs
  6. Verify no duplicate URIs in the DCR payload (regression check for Duplicate redirect URIs generated by DebugInspectorOAuthClientProvider cause DCR failure #825)

Checklist

  • Code follows the style guidelines (ran npm run prettier-fix)
  • Self-review completed
  • Code is commented where necessary
  • Documentation updated (README, comments, etc.)

Breaking Changes

None.

Additional Context

This was introduced by the fix for #825 (duplicate redirect URIs). That fix correctly deduplicated, but didn't account for the polymorphic override collapsing both URIs into one. See root cause analysis comment.

The `redirect_uris` getter used `this.redirectUrl`, which is overridden
by `DebugInspectorOAuthClientProvider` to return `/oauth/callback/debug`.
This caused the `Set` deduplication to collapse both URIs into one,
so DCR only registered `/oauth/callback/debug`. The normal connection
flow then sent `/oauth/callback` in the authorize request, which was
never registered — causing spec-compliant OAuth servers to reject it.

Use the base callback URLs directly instead of the polymorphic getter
so both URIs are always registered regardless of which subclass
initiates DCR.

Fixes modelcontextprotocol#930
Copy link
Copy Markdown
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.

LGTM! 👍

I don't really like it, but we're moving away from DCR anyway. IMO, the real fix would be to manage local storage differently for debug vs non-debug runs.

@BobDickinson something to watch out for on V2.

@cliffhall cliffhall merged commit 94d98ec into modelcontextprotocol:main Apr 2, 2026
5 checks passed
@asoorm
Copy link
Copy Markdown
Contributor Author

asoorm commented Apr 2, 2026

we're moving away from DCR anyway.

Is that in favour of CIMD?

https://www.ietf.org/archive/id/draft-parecki-oauth-client-id-metadata-document-00.html

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.

MCP Inspector starts Authorization Code Flow with wrong redirect_uri

2 participants