-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat(client): SEP-2350 scope step-up — union, retry cap, superset-gated refresh bypass #2346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
felixweinberger
merged 1 commit into
fweinberger/auth-1-sep2468-client
from
fweinberger/auth-3-sep2350-stepup
Jun 24, 2026
+904
−83
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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 |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| '@modelcontextprotocol/client': minor | ||
| '@modelcontextprotocol/core': minor | ||
| --- | ||
|
|
||
| Dynamic Client Registration hygiene for the 2026-07-28 authorization requirements (SEP-837, SEP-2207). New `resolveClientMetadata(provider)` reads `provider.clientMetadata` and applies the spec defaults — `application_type` derived from the redirect URIs (loopback or custom scheme → `'native'`, otherwise `'web'`), `grant_types: ['authorization_code', 'refresh_token']` when omitted — and `auth()` feeds the resolved document to DCR only (scope selection still reads the raw consumer-supplied `clientMetadata` so statically-registered/CIMD clients are not pushed into `offline_access` + `prompt=consent`); consumer-set values are never overwritten. DCR rejection now throws the new `RegistrationRejectedError` carrying the HTTP status, raw body, and submitted metadata — **breaking for direct `registerClient()` callers**: rejection no longer throws `OAuthError`, so update `instanceof` checks. `OAuthClientMetadata` gains a typed `application_type?: string` field (expected `'native'` / `'web'`; tolerant on parse). `OAuthErrorCode` adds `InvalidRedirectUri`. The token-exchange, refresh, and Cross-App Access (`requestJwtAuthorizationGrant` / `exchangeJwtAuthGrant`) paths now throw the new `InsecureTokenEndpointError` for a non-`https:` token endpoint (`localhost` / `127.0.0.1` / `::1` exempt), and `auth()` surfaces it on the refresh branch instead of silently re-authorizing. | ||
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
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 The PR title and description describe a SEP-2350 scope step-up feature (onInsufficientScope on the HTTP transports, exported computeScopeUnion()/InsufficientScopeError, an examples/scoped-tools story, conformance withOAuthRetry wiring, and client-auth:step-up:* e2e scenarios) that does not exist anywhere in this diff or at HEAD (52b1cfc) — the actual change is the SEP-837/SEP-2207 DCR-hygiene work described by this changeset and the HEAD commit message. Please rewrite the title/description to match the DCR-hygiene change actually contained here (or push the intended step-up commits); as-is the Motivation, How-Has-This-Been-Tested, and Breaking-Changes sections describe a different change and will mislead reviewers and the merge-commit history.
Extended reasoning...
What the mismatch is. The PR title ("feat(client): SEP-2350 scope step-up — union, retry cap, superset-gated refresh bypass") and the entire PR description claim a scope step-up feature: an
onInsufficientScopeoption on both HTTP transports, exportedcomputeScopeUnion()andInsufficientScopeError, anexamples/scoped-toolsheadless story with a hardened demo AS, conformance-fixturewithOAuthRetrywiring, andclient-auth:step-up:*e2e scenarios. None of that content is present in this PR. The diff (and this changeset,.changeset/auth-dcr-hygiene.md) implements SEP-837/SEP-2207 Dynamic Client Registration hygiene instead:resolveClientMetadata()withapplication_type/grant_typesdefaults,RegistrationRejectedError,InsecureTokenEndpointError+assertSecureTokenEndpoint(),OAuthErrorCode.InvalidRedirectUri, and the matching e2e/conformance updates.\n\nStep-by-step verification at the PR head. (1) The changeset bot reports the PR's latest commit as52b1cfca1d5a625d82aec89f373d0db4be4ffca3, which is exactly HEAD of this changeset, so this is not a stale-checkout artifact. (2) Greppingpackages/client/srcat that commit forcomputeScopeUnion,InsufficientScopeError(the transport-level class),onInsufficientScope, or_stepUpAuthorizereturns no matches. (3)examples/scoped-toolsdoes not exist, and the 18 changed files include nostreamableHttp.ts,sse.ts, ortest/conformance/srcchanges. (4) The new e2e scenarios areclient-auth:dcr:*,client-auth:token-endpoint:https-guard,client-auth:refresh:rotation-handling, andclient-auth:scope:offline-access-gate— not theclient-auth:step-up:*rows the description claims under How Has This Been Tested. (5) The expected-failures edits remove SEP-837application_typebaseline entries;auth/scope-step-upremains baselined on the 2026-07-28 leg, contradicting the description's claim that it "burns" with this change. (6) The HEAD commit message itself reads "feat(client): SEP-837/2207 — application_type heuristic, grant_types default, https token-endpoint guard", matching the diff.\n\nWhy nothing else catches it. The earlier claude[bot] review comments referencing_stepUpAuthorizeat an older head (8b2f271) indicate the branch previously carried the SEP-2350 work and was later force-pushed to the DCR-hygiene stack without updating the PR title/description. CI passes because the code that is present is internally consistent — there is no automated check that the description matches the diff.\n\nImpact. Reviewers approving this PR based on the description would be approving claims about transport behavior, breaking-change posture ("onInsufficientScopedefaults to 'reauthorize'"), and testing evidence (step-up e2e scenarios, the conformanceauth/scope-step-upburn) that the diff does not back. On squash-merge the description typically becomes the merge-commit body, permanently misdescribing what landed; future readers tracing SEP-2350 vs SEP-837/2207 history will be pointed at the wrong commit.\n\nHow to fix. Either (a) rewrite the PR title and description to describe the SEP-837/SEP-2207 DCR-hygiene change actually contained — the changeset text and the HEAD commit message are accurate starting points — including correcting the testing section to theclient-auth:dcr:*/token-endpoint:https-guardscenarios and the SEP-837 expected-failures burn-down, or (b) push the intended SEP-2350 step-up commits to this branch if this PR was meant to carry them. This is an editorial/process issue rather than a code defect, but the description-vs-diff mismatch is total and should be resolved before merge.