FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Rename scopes= to scope= on the client-credentials OAuth providers by maxisbey · Pull Request #3166 · modelcontextprotocol/python-sdk · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .md  (2) .py  (5) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
2 changes: 1 addition & 1 deletion docs/client/oauth-clients.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ A nightly job, a CI step, another service. There is no browser and nobody to cli
What changed:

* No `OAuthClientMetadata`, no handlers. You pass `client_id` and `client_secret`; the provider builds a minimal `client_credentials` registration around them and skips dynamic registration entirely.
* `scopes` is a space-separated string, the OAuth wire format.
* `scope` is a space-separated string, the OAuth wire format.
* Everything downstream is identical: the same `TokenStorage`, the same `httpx2.AsyncClient(auth=...)`, the same `streamable_http_client`.

By default the secret travels as HTTP Basic auth on the token request (`client_secret_basic`). Pass `token_endpoint_auth_method="client_secret_post"` to put it in the form body instead. Some authorization servers only accept one of the two.
Expand Down
16 changes: 16 additions & 0 deletions docs/migration.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,22 @@ async def callback_handler() -> AuthorizationCodeResult:

Forward the `iss` query parameter from the redirect so the validation can run: omitting it makes the flow fail with `OAuthFlowError` against servers that advertise `authorization_response_iss_parameter_supported`, and silently skips the check for servers that send `iss` without advertising it.

### `scopes=` renamed to `scope=` on the client-credentials providers

`ClientCredentialsOAuthProvider` and `PrivateKeyJWTOAuthProvider` took the requested scope as a keyword named `scopes`, even though the value is a single space-separated string, not a list. The parameter is now `scope`, matching the RFC 6749 wire parameter, `OAuthClientMetadata.scope`, and the newer `IdentityAssertionOAuthProvider`.

**Before (v1):**

```python
ClientCredentialsOAuthProvider(..., scopes="read write")
```

**After (v2):**

```python
ClientCredentialsOAuthProvider(..., scope="read write")
```

### Client rejects authorization server metadata with a mismatched `issuer`

During OAuth discovery, `OAuthClientProvider` now validates that the authorization server
Expand Down
2 changes: 1 addition & 1 deletion docs_src/oauth_clients/tutorial002.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async def set_client_info(self, client_info: OAuthClientInformationFull) -> None
storage=InMemoryTokenStorage(),
client_id="reporting-agent",
client_secret="...",
scopes="user",
scope="user",
)


Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def build_auth(_http: httpx2.AsyncClient) -> httpx2.Auth:
storage=InMemoryTokenStorage(),
client_id=DEMO_CLIENT_ID,
client_secret=DEMO_CLIENT_SECRET,
scopes=DEMO_SCOPE,
scope=DEMO_SCOPE,
)


Expand Down
16 changes: 8 additions & 8 deletions src/mcp/client/auth/extensions/client_credentials.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(
client_id: str,
client_secret: str,
token_endpoint_auth_method: Literal["client_secret_basic", "client_secret_post"] = "client_secret_basic",
scopes: str | None = None,
scope: str | None = None,
) -> None:
"""Initialize client_credentials OAuth provider.

Expand All @@ -57,14 +57,14 @@ def __init__(
client_secret: The OAuth client secret.
token_endpoint_auth_method: Authentication method for token endpoint.
Either "client_secret_basic" (default) or "client_secret_post".
scopes: Optional space-separated list of scopes to request.
scope: Optional space-separated list of scopes to request.
"""
# Build minimal client_metadata for the base class
client_metadata = OAuthClientMetadata(
redirect_uris=None,
grant_types=["client_credentials"],
token_endpoint_auth_method=token_endpoint_auth_method,
scope=scopes,
scope=scope,
)
super().__init__(server_url, client_metadata, storage, None, None, 300.0)
# Store client_info to be set during _initialize - no dynamic registration needed
Expand All @@ -74,7 +74,7 @@ def __init__(
client_secret=client_secret,
grant_types=["client_credentials"],
token_endpoint_auth_method=token_endpoint_auth_method,
scope=scopes,
scope=scope,
)

async def _initialize(self) -> None:
Expand Down Expand Up @@ -258,7 +258,7 @@ def __init__(
storage: TokenStorage,
client_id: str,
assertion_provider: Callable[[str], Awaitable[str]],
scopes: str | None = None,
scope: str | None = None,
) -> None:
"""Initialize private_key_jwt OAuth provider.

Expand All @@ -271,14 +271,14 @@ def __init__(
`SignedJWTParameters.create_assertion_provider()` for SDK-signed JWTs,
`static_assertion_provider()` for pre-built JWTs, or provide your own
callback for workload identity federation.
scopes: Optional space-separated list of scopes to request.
scope: Optional space-separated list of scopes to request.
"""
# Build minimal client_metadata for the base class
client_metadata = OAuthClientMetadata(
redirect_uris=None,
grant_types=["client_credentials"],
token_endpoint_auth_method="private_key_jwt",
scope=scopes,
scope=scope,
)
super().__init__(server_url, client_metadata, storage, None, None, 300.0)
self._assertion_provider = assertion_provider
Expand All @@ -288,7 +288,7 @@ def __init__(
client_id=client_id,
grant_types=["client_credentials"],
token_endpoint_auth_method="private_key_jwt",
scope=scopes,
scope=scope,
)

async def _initialize(self) -> None:
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ async def test_init_with_scopes(self, mock_storage: MockTokenStorage):
storage=mock_storage,
client_id="test-client-id",
client_secret="test-client-secret",
scopes="read write",
scope="read write",
)

await provider._initialize()
Expand Down Expand Up @@ -240,7 +240,7 @@ async def test_exchange_token_client_credentials(self, mock_storage: MockTokenSt
storage=mock_storage,
client_id="test-client-id",
client_secret="test-client-secret",
scopes="read write",
scope="read write",
)
provider.context.oauth_metadata = OAuthMetadata(
issuer=AnyHttpUrl("https://api.example.com"),
Expand Down Expand Up @@ -268,7 +268,7 @@ async def test_exchange_token_client_secret_post_includes_client_id(self, mock_s
client_id="test-client-id",
client_secret="test-client-secret",
token_endpoint_auth_method="client_secret_post",
scopes="read write",
scope="read write",
)
await provider._initialize()
provider.context.oauth_metadata = OAuthMetadata(
Expand Down Expand Up @@ -296,7 +296,7 @@ async def test_exchange_token_client_secret_post_without_client_id(self, mock_st
client_id="placeholder",
client_secret="test-client-secret",
token_endpoint_auth_method="client_secret_post",
scopes="read write",
scope="read write",
)
await provider._initialize()
provider.context.oauth_metadata = OAuthMetadata(
Expand Down Expand Up @@ -386,7 +386,7 @@ async def mock_assertion_provider(audience: str) -> str:
storage=mock_storage,
client_id="test-client-id",
assertion_provider=mock_assertion_provider,
scopes="read write",
scope="read write",
)
provider.context.oauth_metadata = OAuthMetadata(
issuer=AnyHttpUrl("https://auth.example.com"),
Expand Down
4 changes: 2 additions & 2 deletions tests/interaction/auth/test_lifecycle.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ async def test_client_credentials_provider_obtains_a_token_without_an_authorize_
storage=InMemoryTokenStorage(),
client_id="m2m-client",
client_secret="m2m-secret",
scopes="mcp",
scope="mcp",
)

with anyio.fail_after(5):
Expand Down Expand Up @@ -423,7 +423,7 @@ async def assertion_provider(audience: str) -> str:
storage=InMemoryTokenStorage(),
client_id="m2m-jwt-client",
assertion_provider=assertion_provider,
scopes="mcp",
scope="mcp",
)

with anyio.fail_after(5):
Expand Down
Loading

Back | FazBrowse Home | New Git URL