You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e9bfdfd
Browse filesBrowse the repository at this point in the historyBrowse files
Merge branch 'v1.x' into claude/oauth-tokens-null-fields-v1x
Resolves conflicts with the #2888 issuer-binding backport, which added
a client-only issuer member to OAuthTokensSchema and parsed wire
responses through local OAuthTokensSchema.omit({ issuer: true })
schemas. The resolution folds that omission into
OAuthTokenResponseSchema itself: the exported wrapper now validates
against the issuer-less wire shape, so an authorization server can
neither slip null-valued optional members past validation nor inject
the issuer value the client binds stored credentials to. The three
parse sites (executeTokenRequest and both proxy provider exchanges)
keep using OAuthTokenResponseSchema, and the now-redundant local
TokenResponseSchema constants are removed. The exported
OAuthTokensSchema remains byte-identical to v1.x. Both test additions
are kept: this branch's null-optional-field proxy provider suite and
v1.x's issuer-forwarding rejection cases.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXnNnp3fxQYR5HF9BUVhYP
Bind stored OAuth client credentials to the authorization server that issued them. `auth()` adds an `issuer` property to what it passes to `saveClientInformation()` / `saveTokens()` and does not reuse a stored value with a different authorization server: the client registers or
6
+
authorizes again, or `auth()` throws when the credentials cannot be re-created by registering. `OAuthTokensSchema` and `OAuthClientInformationSchema` accept the optional `issuer`. `ClientCredentialsProvider`, `PrivateKeyJwtProvider` and `StaticPrivateKeyJwtProvider` accept
Preserve the exact OAuth resource indicator from protected resource metadata when building authorization and token requests. Previously a pathless `resource` such as `https://example.com` was normalized to `https://example.com/` via `URL.href`, which breaks authorization servers
6
+
that require the `resource` parameter to match the published value exactly (Microsoft Entra ID rejects it with `AADSTS9010010`). The exported OAuth helpers (`startAuthorization`, `exchangeAuthorization`, `refreshAuthorization`, `fetchToken`) now also accept a `string` for
7
+
`resource`; `selectResourceURL` still returns a `URL`, and a provider's `validateResourceURL` result is used unchanged. Fixes #1968.
Copy file name to clipboardExpand all lines: docs/client.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -46,6 +46,11 @@ For OAuth-secured MCP servers, the client `auth` module exposes:
46
46
-`PrivateKeyJwtProvider`
47
47
-`StaticPrivateKeyJwtProvider`
48
48
49
+
Pass `expectedIssuer` (the issuer URL of the authorization server the credentials were registered with) to each of these. `auth()` then only presents the credentials to that authorization server and throws if the MCP server advertises a different one. Omitting it is deprecated.
50
+
51
+
If you implement `OAuthClientProvider` yourself, store the objects passed to `saveClientInformation()` and `saveTokens()` unchanged: they carry an `issuer` property naming the authorization server they came from, and `auth()` does not reuse them with a different one. If
52
+
`clientInformation()` returns pre-registered credentials, include `issuer` yourself.
0 commit comments