Skip to content
Merged
Changes from 6 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f348481
Improved supported for ProtectedResourceMetadata
yannj-fr Aug 4, 2025
39e7576
formatting
pcarleton Aug 4, 2025
e3c1eef
Add test for ProtectedResourceMetadata parsing
yannj-fr Aug 4, 2025
e4de61b
typo fix
yannj-fr Aug 4, 2025
2b5cc94
Merge branch 'main' into feature/expose-protected-resource-metadata
yannj-fr Aug 4, 2025
12eddcc
fix precommit hook
yannj-fr Aug 4, 2025
e8bfe35
Update tests/shared/test_auth.py
yannj-fr Aug 5, 2025
79e1b16
Update tests/shared/test_auth.py
yannj-fr Aug 5, 2025
0967a9e
Merge branch 'main' into feature/expose-protected-resource-metadata
Kludex Aug 5, 2025
32151a6
Add test for protected resources through .well-known/oauth-protected-…
yannj-fr Aug 6, 2025
dd22d76
remove prints in the entire file
yannj-fr Aug 6, 2025
149f752
remove prints and change test class, use snapshot
yannj-fr Aug 6, 2025
1fea1f3
removing uneeded assert on response code
yannj-fr Aug 6, 2025
154b754
separate test in a new file
yannj-fr Aug 6, 2025
69238ad
fix pre check commit
yannj-fr Aug 6, 2025
23fa8d4
Merge branch 'main' into feature/expose-protected-resource-metadata
yannj-fr Aug 6, 2025
82852be
Update tests/server/auth/test_protected_resource.py
yannj-fr Aug 6, 2025
0826232
Update tests/server/auth/test_protected_resource.py
yannj-fr Aug 6, 2025
0b800fe
remove uneeded test and rename methods
yannj-fr Aug 6, 2025
f791a82
Merge branch 'main' into feature/expose-protected-resource-metadata
yannj-fr Aug 9, 2025
1994475
Merge branch 'main' into feature/expose-protected-resource-metadata
felixweinberger Sep 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion tests/shared/test_auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tests for OAuth 2.0 shared code."""

from mcp.shared.auth import OAuthMetadata
import pytest
from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata


class TestOAuthMetadata:
Expand Down Expand Up @@ -37,3 +38,84 @@ def test_oidc(self):
"userinfo_endpoint": "https://example.com/oauth2/userInfo",
}
)


class TestProtectedResourceMetadataInvalid:
"""Tests for ProtectedResourceMetadata parsing."""

def test_invalid_metadata(self):
"""Should throw when parsing invalid metadata."""
with pytest.raises(ValueError):
ProtectedResourceMetadata.model_validate(
{
"resource": "Not a valid URL",
"authorization_servers": ["https://example.com/oauth2/authorize"],
"scopes_supported": ["read", "write"],
"bearer_methods_supported": ["header"],
}
)

def test_valid_metadata(self):
"""Should not throw when parsing protected resource metadata."""

ProtectedResourceMetadata.model_validate(
{
"resource": "https://example.com/resource",
"authorization_servers": ["https://example.com/oauth2/authorize"],
"scopes_supported": ["read", "write"],
"bearer_methods_supported": ["header"],
}
)

def test_valid_with_resource_metadata(self):
"""Should not throw when parsing metadata with resource_name and resource_documentation."""

ProtectedResourceMetadata.model_validate(
{
"resource": "https://example.com/resource",
"authorization_servers": ["https://example.com/oauth2/authorize"],
"scopes_supported": ["read", "write"],
"bearer_methods_supported": ["header"],
"resource_name": "Example Resource",
"resource_documentation": "https://example.com/resource/documentation",
}
)

def test_valid_witn_invalid_resource_documentation(self):
"""Should throw when parsing metadata with resource_name and invalid resource_documentation."""
with pytest.raises(ValueError):
ProtectedResourceMetadata.model_validate(
{
"resource": "https://example.com/resource",
"authorization_servers": ["https://example.com/oauth2/authorize"],
"scopes_supported": ["read", "write"],
"bearer_methods_supported": ["header"],
"resource_name": "Example Resource",
"resource_documentation": "Not a valid URL",
}
)

def test_valid_full_protected_resource_metadata(self):
"""Should not throw when parsing full metadata."""

ProtectedResourceMetadata.model_validate(
{
"resource": "https://example.com/resource",
"authorization_servers": ["https://example.com/oauth2/authorize"],
"jwks_uri": "https://example.com/.well-known/jwks.json",
"scopes_supported": ["read", "write"],
"bearer_methods_supported": ["header"],
"resource_signing_alg_values_supported": ["RS256"],
"resource_name": "Example Resource",
"resource_documentation": "https://example.com/resource/documentation",
"resource_policy_uri": "https://example.com/resource/policy",
"resource_tos_uri": "https://example.com/resource/tos",
"tls_client_certificate_bound_access_tokens": True,
# authorization_details_types_supported is a complext type
# so we use an empty list for simplicity
# see RFC9396
"authorization_details_types_supported": [],
"dpop_signing_alg_values_supported": ["RS256", "ES256"],
"dpop_signing_access_tokens": True,
}
)
Loading