MCP OAuth client requests offline_access scope regardless of server's scopes_supported
Description
Claude Code's MCP OAuth client requests offline_access scope during the authorization flow regardless of whether the OAuth Authorization Server (AS) advertises it in scopes_supported. This causes authentication to fail with strict OIDC providers that reject unknown or unpermitted scopes.
Error
invalid_scope: The requested scope is invalid, unknown, or malformed.
The OAuth 2.0 Client is not allowed to request scope 'offline_access'.
Reproduction
- Configure an MCP server that uses an OIDC provider (e.g. Authelia) as its OAuth AS
- The MCP server's
/.well-known/oauth-authorization-servermetadata advertisesscopes_supported: ["openid", "profile"]— nooffline_access - The OIDC client registration only permits
openidandprofilescopes - Claude Code initiates the OAuth flow and requests
offline_accessin the scope parameter - The AS rejects the request with
invalid_scope
Expected behaviour
Per SEP-2207 (merged into the MCP spec) and its SDK implementation, the client should only append offline_access when:
- The AS metadata includes
offline_accessinscopes_supported, and - The client supports
refresh_tokengrants
If the AS doesn't advertise offline_access, the client should not request it.
Actual behaviour
Claude Code requests offline_access unconditionally, ignoring the AS metadata.
Workaround
Add offline_access to the OIDC client's permitted scopes and refresh_token to its grant types on the AS side. This works but shouldn't be necessary when the server explicitly doesn't advertise the scope.
Related issues
- #4540 — Missing
scopeparameter in Dynamic Client Registration and Authorization Requests - #7744 — Claude Code MCP client ignores
scopes_supportedfrom OAuth protected resource metadata - #34371 — Slack MCP plugin fails with
invalid_scopeduring OAuth
Environment
- Claude Code (latest, via CLI)
- MCP server using Authelia 4.39.x as OAuth AS
- OAuth flow: Authorization Code + PKCE (public client)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗