diff --git a/src/mcp/server/auth/routes.py b/src/mcp/server/auth/routes.py index 08f735f36..4ef15eb86 100644 --- a/src/mcp/server/auth/routes.py +++ b/src/mcp/server/auth/routes.py @@ -172,6 +172,7 @@ def build_metadata( op_tos_uri=None, introspection_endpoint=None, code_challenge_methods_supported=["S256"], + client_id_metadata_document_supported=client_registration_options.client_id_metadata_document_supported, ) # Add registration endpoint if supported diff --git a/src/mcp/server/auth/settings.py b/src/mcp/server/auth/settings.py index 1649826db..ec8017561 100644 --- a/src/mcp/server/auth/settings.py +++ b/src/mcp/server/auth/settings.py @@ -6,6 +6,7 @@ class ClientRegistrationOptions(BaseModel): client_secret_expiry_seconds: int | None = None valid_scopes: list[str] | None = None default_scopes: list[str] | None = None + client_id_metadata_document_supported: bool = False class RevocationOptions(BaseModel): diff --git a/tests/client/test_auth.py b/tests/client/test_auth.py index 7ad24f2df..fc1d63a4a 100644 --- a/tests/client/test_auth.py +++ b/tests/client/test_auth.py @@ -1352,6 +1352,33 @@ def test_build_metadata( "revocation_endpoint": Is(revocation_endpoint), "revocation_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"], "code_challenge_methods_supported": ["S256"], + "client_id_metadata_document_supported": Is(False), + } + ) + + metadata = build_metadata( + issuer_url=AnyHttpUrl(issuer_url), + service_documentation_url=AnyHttpUrl(service_documentation_url), + client_registration_options=ClientRegistrationOptions( + enabled=True, valid_scopes=["read", "write", "admin"], client_id_metadata_document_supported=True + ), + revocation_options=RevocationOptions(enabled=True), + ) + + assert metadata.model_dump(exclude_defaults=True, mode="json") == snapshot( + { + "issuer": Is(issuer_url), + "authorization_endpoint": Is(authorization_endpoint), + "token_endpoint": Is(token_endpoint), + "registration_endpoint": Is(registration_endpoint), + "scopes_supported": ["read", "write", "admin"], + "grant_types_supported": ["authorization_code", "refresh_token"], + "token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"], + "service_documentation": Is(service_documentation_url), + "revocation_endpoint": Is(revocation_endpoint), + "revocation_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"], + "code_challenge_methods_supported": ["S256"], + "client_id_metadata_document_supported": Is(True), } ) diff --git a/tests/server/mcpserver/auth/test_auth_integration.py b/tests/server/mcpserver/auth/test_auth_integration.py index a78a86cf0..074603157 100644 --- a/tests/server/mcpserver/auth/test_auth_integration.py +++ b/tests/server/mcpserver/auth/test_auth_integration.py @@ -318,6 +318,7 @@ async def test_metadata_endpoint(self, test_client: httpx.AsyncClient): assert metadata["revocation_endpoint"] == "https://auth.example.com/revoke" assert metadata["response_types_supported"] == ["code"] assert metadata["code_challenge_methods_supported"] == ["S256"] + assert metadata["client_id_metadata_document_supported"] is False assert metadata["token_endpoint_auth_methods_supported"] == ["client_secret_post", "client_secret_basic"] assert metadata["grant_types_supported"] == [ "authorization_code",