prompt=consent hardcoded on every MCP OAuth authorize request breaks Entra tenants with user consent disabled — affects Claude Code, claude.ai web connector and desktop alike (#49722 was closed without a fix)

Status Open
Maintainer reply None cached
Activity 2 comments · opened Sep 16, 2026

Summary

#49722 was closed as completed on 2026-06-02, but the behaviour is unchanged. It affects every Claude MCP client — Claude Code CLI, the claude.ai web connector and the desktop app alike — because it lives in the shared MCP TypeScript SDK auth layer, not in any single client.

Every MCP OAuth authorize request that includes offline_access carries a hardcoded prompt=consent. In Microsoft Entra ID tenants where user consent is disabled (Microsoft's recommended enterprise default), every non-admin user is routed into the "admin approval required" workflow (AADSTS90095) on every connect, even though tenant-wide admin consent for the app is already granted. Approving the resulting admin consent requests changes nothing; the next connect triggers the next request. Admin users get the full consent dialog on every connect.

Reproduced on 2026-09-16 with the claude.ai web connector (Settings → Connectors → Connect). The authorize URL matches the pattern reported for Claude Code in #49722 and #64013 exactly.

Setup (generic — any OIDC authorization server in front of Entra will do)

  • Client: claude.ai web connector; identical behaviour reported for Claude Code CLI in #49722 / #64013
  • MCP server: FastMCP RemoteAuthProvider — publishes protected-resource metadata only, has no authorize endpoint and cannot influence the parameter
  • Authorization server: OIDC-compliant IdP federating to Microsoft Entra ID (passes prompt through to the upstream IdP, as the spec allows)
  • Entra: user consent disabled; admin consent for the app granted tenant-wide

Reproduction (browser DevTools → Console → "Navigated to")

  1. Claude → authorization server:
https://<authorization-server>/oauth2/authorize
  ?response_type=code
  &client_id=<client-id>
  &redirect_uri=https%3A%2F%2Fclaude.ai%2Fapi%2Fmcp%2Fauth_callback
  &code_challenge=…&code_challenge_method=S256&state=…
  &scope=openid+email+profile+offline_access
  &resource=https%3A%2F%2F<mcp-server>%2Fmcp
  &prompt=consent
  1. Authorization server → upstream Entra (parameter forwarded 1:1):
https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize
  ?client_id=<entra-app-id>&prompt=consent&scope=openid+profile+email&…
  1. Non-admin user → AADSTS90095 + justification form. Admin user → consent dialog. Every time.

The server's protected-resource metadata advertises only scopes_supported: ["openid","email","profile"]. Both offline_access and prompt=consent are added client-side. Removing offline_access from the authorization server's discovery document does not change the request either — verified.

Root cause — unchanged in SDK main today

packages/client/src/client/auth.ts (modelcontextprotocol/typescript-sdk, main, 2026-09-16):

  • L1093–1103: offline_access is appended when the AS advertises it (SEP-2207)
  • L2114–2118:

``ts
if (scope?.split(' ').includes('offline_access')) {
// ... set the prompt to "consent" to ensure the user is prompted to grant offline access
authorizationUrl.searchParams.append('prompt', 'consent');
}
``

Introduced by modelcontextprotocol/typescript-sdk#681 (July 2025). OIDC Core §11 requires the authorization server to ensure the user is prompted for offline access — it does not require the client to force prompt=consent. A compliant AS prompts when it needs to; forcing it client-side overrides the tenant's consent policy on every request.

Why the existing issues don't resolve this

| Issue | State | Note |
|---|---|---|
| #49722 | closed completed 2026-06-02 | no linked commit or PR; behaviour identical today |
| #64013 | closed not_planned | marked duplicate of #49722 → circular |
| modelcontextprotocol/typescript-sdk#1958 | open since 2026-04 | only de-duplicates the prompt parameter, does not remove it |
| #60152, #64482, #64636 | closed | same symptom family on the hosted M365 connector |

Impact

Every enterprise Entra tenant with user consent disabled is affected, on every Claude surface. The workarounds discussed in #49722 (editing the URL by hand, an interception proxy) are not viable for an org-wide rollout.

Expected

One of:

  • do not send prompt=consent unless explicitly requested by the user/organization, or
  • make it configurable per server (client metadata / connector settings), or
  • omit prompt when the AS is OIDC-compliant and let it prompt when it actually needs to.

Please reopen #49722 or track here. Further captures (HAR, tokens redacted) available on request.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗