Skip to content

feat: expose oauth discovery metadata source#1041

Merged
DaleSeo merged 2 commits into
mainfrom
fix/oauth-discovery-metadata-source
Jul 24, 2026
Merged

feat: expose oauth discovery metadata source#1041
DaleSeo merged 2 commits into
mainfrom
fix/oauth-discovery-metadata-source

Conversation

@DaleSeo

@DaleSeo DaleSeo commented Jul 24, 2026

Copy link
Copy Markdown
Member

Closes #1037

Motivation and Context

The previous AuthorizationManager::discover_metadata() method fell back to the legacy default endpoints, /authorize, /token, and /register, based on the base URL when discovery returned nothing. This fallback is required for the auth/2025-03-26-oauth-endpoint-fallback conformance scenario. However, it made a successful fallback look the same as metadata that the server actually published. As a result, callers could not tell whether OAuth metadata was discovered or synthesized for compatibility. That behavior was originally introduced in #507 and changed by #960.

This replaces that method with AuthorizationManager::resolve_metadata(), which returns AuthorizationMetadataResolution containing both the AuthorizationMetadata and its AuthorizationMetadataSource. “Resolve” reflects that the method may either discover server-published metadata or synthesize legacy endpoints. The source distinguishes protected resource metadata, authorization server metadata, and the legacy endpoint fallback; is_discovered() reports whether the server published metadata.

Because v3 is still in beta, this makes provenance part of the primary metadata-resolution contract now instead of adding a parallel method that would need to be retained long-term. Internal SDK and conformance call sites explicitly extract .metadata; the discovery order, legacy endpoint synthesis, and conformance behavior remain unchanged.

How Has This Been Tested?

Unit tests cover all three sources

Breaking Changes

AuthorizationManager::discover_metadata() has been renamed to resolve_metadata() and now returns Result<AuthorizationMetadataResolution, AuthError> instead of Result<AuthorizationMetadata, AuthError>.

Callers must use the new method and extract the metadata field when they need AuthorizationMetadata directly:

// Before
let metadata = manager.discover_metadata().await?;
manager.set_metadata(metadata);

// After
let resolution = manager.resolve_metadata().await?;
manager.set_metadata(resolution.metadata);

Callers can inspect resolution.source or call resolution.source.is_discovered() before consuming the metadata.

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

@github-actions github-actions Bot added T-core Core library changes T-transport Transport layer changes labels Jul 24, 2026
@DaleSeo DaleSeo self-assigned this Jul 24, 2026
@DaleSeo
DaleSeo marked this pull request as ready for review July 24, 2026 03:31
@DaleSeo
DaleSeo requested a review from a team as a code owner July 24, 2026 03:31
jamadeo
jamadeo previously approved these changes Jul 24, 2026
/// Nothing was discovered; the endpoints were synthesized from the base
/// URL (`/authorize`, `/token`, `/register`) for compatibility with the
/// 2025-03-26 MCP spec's default-endpoint fallback. The server gave no
/// evidence that it supports OAuth.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would include something here if we're going to have a descriptive comment that metadata discovery is now mandatory in newer versions of the spec, and there is no endpoint-synthesis fallback any more.

https://modelcontextprotocol.io/specification/draft/basic/authorization/authorization-server-discovery#protected-resource-metadata-discovery-requirements

@github-actions github-actions Bot added the T-documentation Documentation improvements label Jul 24, 2026
@DaleSeo
DaleSeo force-pushed the fix/oauth-discovery-metadata-source branch 3 times, most recently from 4dc5ebc to 42b7fc8 Compare July 24, 2026 15:49
@github-actions github-actions Bot added the T-examples Example code changes label Jul 24, 2026
@DaleSeo
DaleSeo force-pushed the fix/oauth-discovery-metadata-source branch from 42b7fc8 to 3283594 Compare July 24, 2026 15:53
@DaleSeo
DaleSeo requested review from alexhancock and jamadeo July 24, 2026 16:46
@DaleSeo
DaleSeo merged commit 60a7a75 into main Jul 24, 2026
22 checks passed
@DaleSeo
DaleSeo deleted the fix/oauth-discovery-metadata-source branch July 24, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-core Core library changes T-documentation Documentation improvements T-examples Example code changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth discovery should distinguish discovered authorization metadata from synthesized legacy endpoints

3 participants