SEP-2207: Refresh token guidance #1523
Draft
+265
−1
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.
Implement OIDC-flavored refresh token guidance (modelcontextprotocol/modelcontextprotocol#2207) in the Python SDK client.
Motivation and Context
MCP clients interacting with OIDC-flavored Authorization Servers often don't receive refresh tokens because they aren't requesting
offline_access. This leads to poor UX (frequent re-authentication). SEP-2207 provides guidance for how MCP clients should handle this.The SDK currently expects the caller to supply the supported
grant_typesfor the client. The example already shows providingrefresh_token, and callers are encouraged to do so as well.This PR:
determineScope()helper that follows the MCP Scope Selection Strategyoffline_accessto the authorization request scope when the AS advertises it inscopes_supportedand the client'sgrant_typesincludesrefresh_tokenNo changes are needed on the server side — the SDK's example AS already includes
offline_accessin itsscopes_supported, and the example middleware already omits it fromWWW-Authenticate(both compliant with the SEP).How Has This Been Tested?
determineScope()covering:scopes_supported,clientMetadata.scopefallback, omit)offline_accesswhen conditions met)clientMetadata.scopeor non-compliant PRM, whengrant_typesomitsrefresh_token, whengrant_typesis undefined, when no scopes are present)Breaking Changes
None. The
offline_accessaugmentation only activates when:offline_accessinscopes_supportedgrant_typesincludesrefresh_tokenClients that don't set
grant_typesor don't includerefresh_tokenare unaffected. Authorization Servers that don't recognizeoffline_accesswill simply ignore it per OAuth 2.1. The newly exporteddetermineScope()function is additive.Types of changes
Checklist
Additional context
determineScope()now encodes the MCP Scope Selection Strategy as a testable, exported function. It acceptsrequestedScope,resourceMetadata,authServerMetadata, andclientMetadata, and returns the effective scope string (orundefinedto omit the parameter).startAuthorization()already handles addingprompt=consentwhenoffline_accessis in scope, per the OIDC Core spec. No changes were needed there.grant_typesdefaulting was intentionally not added at the SDK level. TheOAuthClientMetadatatype is shared between client creation (DCR) and server-side parsing (CIMD), so schema-level defaults would violate OAuth spec defaults for CIMD. The example clients already includerefresh_tokeningrant_types.insufficient_scopehandler instreamableHttp.tsalready passes scope through toauth(), which now delegates todetermineScope()— no additional changes needed for step-up authorization flows.