Skip to content

Remove the deprecated RFC7523OAuthClientProvider#3169

Merged
maxisbey merged 2 commits into
mainfrom
remove-rfc7523-provider
Jul 25, 2026
Merged

Remove the deprecated RFC7523OAuthClientProvider#3169
maxisbey merged 2 commits into
mainfrom
remove-rfc7523-provider

Conversation

@maxisbey

Copy link
Copy Markdown
Contributor

Removes RFC7523OAuthClientProvider and its JWTParameters model from mcp.client.auth.extensions.client_credentials, ahead of v2.

Motivation and Context

RFC7523OAuthClientProvider implemented the RFC 7523 §2.1 jwt-bearer authorization grant with an SDK-minted or prebuilt JWT (plus a hybrid authorization_code + private_key_jwt mode). It landed in #1247, then was deprecated five weeks later in #1663 once the client-credentials extension (SEP-1046) settled on the client_credentials grant with §2.2 private_key_jwt client authentication instead — the flow PrivateKeyJWTOAuthProvider implements. It has warned on construction since 1.23.0 (Dec 2025).

No MCP auth extension specifies the flow it implements, no other SDK ships an equivalent, and nearly all of its flow methods were # pragma: no cover. Every mode has a purpose-built replacement:

  • client secret → ClientCredentialsOAuthProvider
  • private_key_jwt (§2.2) → PrivateKeyJWTOAuthProvider with SignedJWTParameters / static_assertion_provider
  • ID-JAG under jwt-bearer (SEP-990) → IdentityAssertionOAuthProvider

The one sanctioned future use of a bare §2.1 grant, SEP-1933 Workload Identity Federation, is still a draft and wants a different shape (platform-provisioned assertion, no dynamic registration or interactive base class), so it will get its own provider rather than a resurrection of this one.

How Has This Been Tested?

Removed the tests for the deleted classes; the remaining client_credentials.py module stays at 100% coverage and strict-no-cover is clean. Confirmed at the package boundary that the removed names raise ImportError, the surviving providers still construct as httpx2.Auth under -W error, and every module in the package imports cleanly.

Breaking Changes

Yes — RFC7523OAuthClientProvider and JWTParameters are gone. docs/migration.md maps each mode to its replacement.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

AI Disclaimer

The provider implemented the RFC 7523 §2.1 jwt-bearer authorization grant
with an SDK-minted or prebuilt JWT, which no MCP auth extension specifies,
and has been deprecated since 1.23.0 in favour of ClientCredentialsOAuthProvider,
PrivateKeyJWTOAuthProvider, and IdentityAssertionOAuthProvider. Drop it and its
JWTParameters model ahead of v2, with a migration entry mapping each of its
modes to a replacement.
@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation preview

Preview https://pr-3169.mcp-python-docs.pages.dev
Deployment https://6436c972.mcp-python-docs.pages.dev
Commit 05dad48
Triggered by @maxisbey
Updated 2026-07-25 21:39:51 UTC

@maxisbey
maxisbey marked this pull request as ready for review July 25, 2026 20:05

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/migration.md Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — a clean, deletion-only removal of an already-deprecated provider, with the migration guide mapping every mode to its replacement. The one inline comment is adjacent cleanup in oauth2.py (the now-dead token_data hook), not a defect in this PR, and can be handled here or in a follow-up.

Extended reasoning...

Overview

The PR deletes RFC7523OAuthClientProvider and JWTParameters from mcp.client.auth.extensions.client_credentials, removes their tests (including the docs test that existed only to explain why the docs page did not count the deprecated provider), and adds a migration-guide section mapping each of the provider's three modes to its purpose-built replacement. No surviving code is modified — the diff is pure deletion plus docs.

Security risks

None introduced: this is code removal in the OAuth client extensions, and the surviving providers (ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider) are untouched. I grepped the whole repo and found no remaining references to the deleted names in src/, tests/, docs/ (other than the new migration entry), or .github/actions/conformance/client.py — nothing can break at import time. The only residue is the now-dead token_data hook parameter in OAuthClientProvider._exchange_token_authorization_code (src/mcp/client/auth/oauth2.py:386-396), flagged inline; I verified it is harmless today because the or {} guard replaces the shared mutable default before any mutation.

Level of scrutiny

Although this touches the auth package, it is a deletion-only change of a class deprecated since 1.23.0 (warning on construction), which cannot alter the behavior of any remaining auth flow. The repo's branching model expects intentional breaking changes on main (the V2 rework) documented in docs/migration.md, and that requirement is met — including an explicit note that the hybrid authorization_code + private_key_jwt mode is intentionally dropped with no replacement. That design decision was effectively made when the provider was deprecated in #1663; this PR executes it.

Other factors

The remaining module keeps its tests intact (ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, SignedJWTParameters, static_assertion_provider all still covered), and the PR description reports 100% coverage and a clean strict-no-cover run. The single finding is a nit in a file the PR does not touch, so it does not block approval.

Comment thread src/mcp/client/auth/extensions/client_credentials.py
The keyword-only token_data parameter on
OAuthClientProvider._exchange_token_authorization_code existed only so
RFC7523OAuthClientProvider could inject a client assertion into the
authorization-code exchange. With that provider gone it had no callers and
carried a mutable {} default, so build the request body as a local dict
instead. Also spell the migration guide's constructor examples with keyword
arguments so they run as written.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — the deprecated RFC7523OAuthClientProvider/JWTParameters removal is clean, and the follow-up commit that also removed the now-dead token_data hook from _exchange_token_authorization_code resolves my earlier inline comment.

What was reviewed:

  • Confirmed no remaining references to the removed names in src/ or docs/ outside the migration guide; SignedJWTParameters (the survivor) is unaffected.
  • Verified the oauth2.py signature simplification is behavior-preserving — all remaining callers (the internal flow call and six tests in tests/client/test_auth.py) pass only (auth_code, code_verifier), and the locally-built dict has identical contents.
  • Checked the migration guide's replacements exist (ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, IdentityAssertionOAuthProvider) and that both prior reviewer comments (cubic's kwargs nit, my token_data nit) were addressed.
Extended reasoning...

Overview

The PR removes the long-deprecated RFC7523OAuthClientProvider and its JWTParameters model from mcp.client.auth.extensions.client_credentials, deletes their tests, adds a migration-guide section mapping each of the provider's three modes to its replacement, and (in a follow-up commit responding to review feedback) removes the token_data hook parameter from OAuthClientProvider._exchange_token_authorization_code in oauth2.py — the deleted provider was that hook's sole consumer.

Security risks

The diff touches OAuth client code, but it is almost entirely deletion. The one behavioral file change, oauth2.py, replaces a mutable-default parameter plus dict.update() with a locally-built dict containing the identical keys; I verified every remaining call site (internal call at oauth2.py:314 and six tests in tests/client/test_auth.py) passes only positional (auth_code, code_verifier), so no caller breaks and no request content changes. Removing the shared-mutable-default hook is a small security improvement rather than a risk: it eliminates a latent path for form fields (auth codes, client secrets) to leak between token exchanges if the guard line were ever refactored away.

Level of scrutiny

This is a breaking removal on the v2 branch, where AGENTS.md explicitly expects intentional breaking changes documented in docs/migration.md — which this PR does, including an explicit note that the hybrid authorization_code+private_key_jwt mode is dropped without replacement and an invitation to open an issue. The removed provider warned on construction since 1.23.0, implemented a flow no MCP auth extension specifies, and was mostly # pragma: no cover. The remaining scrutiny needed is mechanical (dangling references, caller breakage), which I checked directly.

Other factors

Both prior reviewer comments were addressed by subsequent commits: cubic's migration-snippet kwargs fix and my own inline comment about the leftover token_data hook (fixed in 05dad48 exactly as suggested). The bug hunting system found no issues this run. Surviving providers (ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, SignedJWTParameters, static_assertion_provider) retain their full test coverage, and docs/client/oauth-clients.md plus its doc-tests were updated consistently (the test asserting the deprecated provider warns was removed along with the provider).

@maxisbey
maxisbey merged commit 7163d82 into main Jul 25, 2026
38 checks passed
@maxisbey
maxisbey deleted the remove-rfc7523-provider branch July 25, 2026 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant