Skip to content

Conversation

@cbcoutinho
Copy link
Contributor

Summary

Implements SEP-985 to align OAuth 2.0 Protected Resource Metadata discovery with RFC 9728. This update makes WWW-Authenticate headers optional and adds support for well-known URI fallback, enabling more flexible server deployment models.

Changes

  • Discovery State Management: Added discovery_urls and discovery_index fields to OAuthContext to track fallback URL attempts
  • Multi-Step Discovery: Implemented _build_protected_resource_discovery_urls() to generate ordered list of discovery URLs:
    1. WWW-Authenticate header resource_metadata parameter (if present)
    2. Path-based well-known URI: /.well-known/oauth-protected-resource/{path}
    3. Root-based well-known URI: /.well-known/oauth-protected-resource
  • Fallback Logic: Updated async_auth_flow() to loop through discovery URLs until one succeeds or all are exhausted
  • Response Handling: Modified _handle_protected_resource_response() to return boolean indicating success, enabling automatic fallback on 404 or validation errors

Test Coverage

Added comprehensive TestSEP985Discovery test class with three scenarios:

  • Path-based well-known URI fallback when WWW-Authenticate header is absent
  • Root-based well-known URI fallback when path-based returns 404
  • WWW-Authenticate header priority over well-known URIs

All existing tests pass (92 passed, 1 xfailed as expected).

Motivation

SEP-985 addresses deployment challenges in large-scale, multi-tenant environments where injecting WWW-Authenticate headers from backend services is complex due to separation of concerns. By making headers optional and requiring well-known URI support, servers can choose the discovery mechanism that best fits their architecture.

Test Plan

  • Run client auth tests: pytest tests/client/test_auth.py
  • Run server auth tests: pytest tests/server/auth/
  • Verify all SEP-985 specific tests pass
  • Confirm no regressions in existing tests
  • Test backward compatibility with servers using only WWW-Authenticate headers

References

cbcoutinho and others added 3 commits October 30, 2025 14:43
Add support for multiple discovery mechanisms when WWW-Authenticate header
is absent, aligning with RFC 9728 requirements. Clients now try discovery
URLs in order: WWW-Authenticate header resource_metadata parameter,
path-based well-known URI, then root-based well-known URI.

Changes:
- Add discovery state tracking to OAuthContext (discovery_urls, discovery_index)
- Implement _build_protected_resource_discovery_urls() to generate ordered URL list
- Update _discover_protected_resource() to support multi-step discovery
- Modify _handle_protected_resource_response() to return success/failure boolean
- Update async_auth_flow() to loop through discovery URLs with fallback logic
- Add comprehensive test coverage for all three discovery mechanisms

This enables servers to choose between WWW-Authenticate headers and
well-known URIs based on their deployment architecture, reducing
integration complexity for large-scale, multi-tenant environments.

Github-Issue: modelcontextprotocol#1341

Co-Authored-By: Claude <[email protected]>
@pcarleton pcarleton requested a review from maxisbey October 30, 2025 15:56
@pcarleton
Copy link
Member

thanks @cbcoutinho ! I added a few tweaks to be more similar to OAuth Authorization Server metadata discovery (step 3) and eliminate additions to context.

@maxisbey maxisbey merged commit 3390e49 into modelcontextprotocol:main Nov 5, 2025
18 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.

Implement SEP-985: Align OAuth 2.0 Protected Resource Metadata with RFC 9728

3 participants