Skip to content

Commit f2d2789

Browse files
add client_id_metadata_document_supported flag
1 parent d3133ae commit f2d2789

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

src/mcp/server/auth/routes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ def build_metadata(
172172
op_tos_uri=None,
173173
introspection_endpoint=None,
174174
code_challenge_methods_supported=["S256"],
175+
client_id_metadata_document_supported=(
176+
client_registration_options.client_id_metadata_document_supported
177+
),
175178
)
176179

177180
# Add registration endpoint if supported

src/mcp/server/auth/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class ClientRegistrationOptions(BaseModel):
66
client_secret_expiry_seconds: int | None = None
77
valid_scopes: list[str] | None = None
88
default_scopes: list[str] | None = None
9+
client_id_metadata_document_supported: bool = False
910

1011

1112
class RevocationOptions(BaseModel):

tests/client/test_auth.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,7 @@ def test_build_metadata(
13521352
"revocation_endpoint": Is(revocation_endpoint),
13531353
"revocation_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
13541354
"code_challenge_methods_supported": ["S256"],
1355+
"client_id_metadata_document_supported": Is(bool)
13551356
}
13561357
)
13571358

tests/server/mcpserver/auth/test_auth_integration.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,32 @@ async def auth_code(
303303

304304

305305
class TestAuthEndpoints:
306+
@pytest.mark.anyio
307+
async def test_metadata_endpoint_with_client_id_metadata_document_supported(self):
308+
"""Test metadata endpoint when client_id_metadata_document_supported is enabled."""
309+
mock_provider = MockOAuthProvider()
310+
auth_routes = create_auth_routes(
311+
mock_provider,
312+
AnyHttpUrl("https://auth.example.com"),
313+
AnyHttpUrl("https://docs.example.com"),
314+
client_registration_options=ClientRegistrationOptions(
315+
enabled=True,
316+
valid_scopes=["read", "write"],
317+
client_id_metadata_document_supported=True,
318+
),
319+
revocation_options=RevocationOptions(enabled=True),
320+
)
321+
app = Starlette(routes=auth_routes)
322+
323+
async with httpx.AsyncClient(
324+
transport=httpx.ASGITransport(app=app), base_url="https://mcptest.com"
325+
) as client:
326+
response = await client.get("/.well-known/oauth-authorization-server")
327+
assert response.status_code == 200
328+
329+
metadata = response.json()
330+
assert metadata["client_id_metadata_document_supported"] is True
331+
306332
@pytest.mark.anyio
307333
async def test_metadata_endpoint(self, test_client: httpx.AsyncClient):
308334
"""Test the OAuth 2.0 metadata endpoint."""
@@ -318,6 +344,7 @@ async def test_metadata_endpoint(self, test_client: httpx.AsyncClient):
318344
assert metadata["revocation_endpoint"] == "https://auth.example.com/revoke"
319345
assert metadata["response_types_supported"] == ["code"]
320346
assert metadata["code_challenge_methods_supported"] == ["S256"]
347+
assert metadata["client_id_metadata_document_supported"] is False
321348
assert metadata["token_endpoint_auth_methods_supported"] == ["client_secret_post", "client_secret_basic"]
322349
assert metadata["grant_types_supported"] == [
323350
"authorization_code",

0 commit comments

Comments
 (0)