-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: implement SEP-991 URL-based client ID (CIMD) support #1652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add support for Client ID Metadata Documents (CIMD) as defined in SEP-991. When a server advertises client_id_metadata_document_supported=true and the client provides a valid client_metadata_url, the URL is used as the client_id instead of performing dynamic client registration. Changes: - Add client_metadata_url parameter to OAuthClientProvider - Add helper functions in utils.py: is_valid_client_metadata_url, should_use_client_metadata_url, create_client_info_from_metadata_url - Update auth flow to use CIMD when conditions are met - Validate client_metadata_url at initialization time (must be HTTPS with non-root pathname) Github-Issue:#1538
Update simple-auth-client to demonstrate using client_metadata_url parameter for SEP-991 CIMD support.
Add comprehensive unit tests for the Client ID Metadata Document (CIMD) functionality including: - URL validation tests for is_valid_client_metadata_url - Tests for should_use_client_metadata_url logic - Tests for create_client_info_from_metadata_url - OAuthClientProvider initialization tests with client_metadata_url - Auth flow tests verifying CIMD is used when server supports it - Auth flow tests verifying fallback to DCR when CIMD not supported
c56ff46 to
f32cdad
Compare
Add tests to cover the fallback path in create_client_registration_request when auth_server_metadata is None or lacks a registration_endpoint. Mark the exception handler in is_valid_client_metadata_url as pragma: no cover since urlparse rarely throws exceptions and this is purely defensive code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| raise OAuthRegistrationError(f"Invalid registration response: {e}") | ||
|
|
||
|
|
||
| def is_valid_client_metadata_url(url: str | None) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open to a different break down of helper functions here, this seemed like a reasonably flexible combo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems appropriate to me
Add MCP_CLIENT_METADATA_URL environment variable support to the simple-auth-client example, allowing users to specify their own client metadata URL for CIMD (SEP-991) instead of using a hardcoded value. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
src/mcp/client/auth/oauth2.py
Outdated
| redirect_handler: Callable[[str], Awaitable[None]] | None | ||
| callback_handler: Callable[[], Awaitable[tuple[str, str | None]]] | None | ||
| timeout: float = 300.0 | ||
| client_metadata_url: str | None = None # SEP-991: URL-based client ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: personally think we shouldn't litter comments with references to SEP numbers, hard to keep up-to-date.
| raise OAuthRegistrationError(f"Invalid registration response: {e}") | ||
|
|
||
|
|
||
| def is_valid_client_metadata_url(url: str | None) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems appropriate to me
Remove temporary SEP number references from code comments since these are difficult to maintain and can become outdated. The CIMD (Client ID Metadata Document) terminology is kept as it's a meaningful acronym.
src/mcp/client/auth/utils.py
Outdated
| try: | ||
| parsed = urlparse(url) | ||
| return parsed.scheme == "https" and parsed.path not in ("", "/") | ||
| except Exception: # pragma: no cover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why no cover?
Add test case with malformed IPv6 URL to cover the exception branch, removing the pragma: no cover comment.
a96218d to
efd73df
Compare
Summary
Implements support for Client ID Metadata Documents (CIMD) as defined in SEP-991. When a server advertises
client_id_metadata_document_supported=truein its OAuth metadata and the client provides a validclient_metadata_url, the URL is used as theclient_idinstead of performing dynamic client registration (DCR).This allows clients to use HTTPS URLs as client identifiers where the URL points to a JSON document containing client metadata, enabling servers to implement flexible trust policies for URL-based client registration without requiring pre-coordination.
Changes
client_metadata_urlparameter toOAuthClientProviderutils.py:is_valid_client_metadata_url()- validates CIMD URLs (must be HTTPS with non-root pathname)should_use_client_metadata_url()- determines if CIMD should be used based on server supportcreate_client_info_from_metadata_url()- creates client info with URL as client_idclient_metadata_urlat initialization timesimple-auth-clientexample to demonstrate CIMD usageTest plan
auth/basic-cimdscenario)Closes #1538