Remote MCP OAuth: prompt=consent hardcoded on every authorize request breaks Entra tenants with user-consent disabled
Summary
Claude Code 2.1.109's remote HTTP MCP transport hardcodes prompt=consent on every OAuth authorize request. This forces Microsoft Entra ID to show the consent UI on every sign-in, regardless of whether admin consent has already been granted tenant-wide.
In Entra tenants where user consent is disabled (a common enterprise policy), non-admin users are routed into the admin consent request workflow ("This app requires your admin's approval" + "Enter justification") on every connection attempt — even after an admin has explicitly granted tenant-wide consent on the app registration. There is no "Accept" button; the user is blocked.
Reproduction
- Set up a .NET MCP server with Entra JWT Bearer auth +
ModelContextProtocol.AspNetCoreMCP authentication scheme (RFC 9728 protected resource metadata) - Create a public client Entra app registration with PKCE,
access_as_userscope, admin consent granted tenant-wide - Ensure the Entra tenant has Enterprise applications → Consent and permissions → User consent settings set to "Do not allow user consent" (common in enterprise/MSP tenants)
- Add the MCP server to Claude Code:
``bash``
claude mcp add --transport http --client-id <app-reg-id> --callback-port 6274 my-server https://my-server.example.com/mcp
/mcp→ Authenticate
Expected: Since admin consent is already granted, Entra should skip the consent prompt and issue tokens directly.
Actual: The authorize URL contains &prompt=consent, which forces Entra to show the consent UI. With user consent disabled at the tenant level, Entra shows the admin-approval-required form instead of an Accept button. Non-admin users are blocked indefinitely.
The authorize URL Claude generates
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
?response_type=code
&client_id=<app-reg-id>
&code_challenge=<pkce>
&code_challenge_method=S256
&redirect_uri=http://localhost:6274/callback
&scope=https://my-server.example.com/mcp/access_as_user+offline_access
&prompt=consent ← this is the problem
&resource=https://my-server.example.com/mcp
Impact
Any Entra tenant with user consent disabled (standard enterprise security posture) cannot use Claude Code's remote MCP transport without one of these workarounds:
- Change the tenant's consent policy — flip to "Allow user consent for apps". Works but requires a Global Admin to weaken the tenant-wide policy for all apps, not just this one.
- Manually edit the auth URL — strip
&prompt=consentfrom the URL Claude opens in the browser, then paste the modified URL. Per-sign-in manual step; not scalable. - Sign in as a Global Admin — admins see a "Consent on behalf of organization" checkbox. Works for the admin themselves but not for regular users.
Suggested fix
Either:
- A) Don't send
prompt=consentat all — let Entra decide whether to show the prompt based on the existing consent state. If consent hasn't been granted yet, Entra will prompt automatically on first sign-in. - B) Send
prompt=consentonly on the first sign-in for a given server (when no cached tokens exist), not on reconnections or token refreshes. - C) Make
prompt=consentconfigurable — e.g. a--no-prompt-consentflag onclaude mcp add, or an MCP server config option.
Option A is the simplest and matches the behavior of other OAuth clients (Azure CLI, VS Code, etc.) that work fine with Entra tenants that have user consent disabled.
Environment
- Claude Code: v2.1.109
- OS: Ubuntu 22.04 (WSL2)
- Identity provider: Microsoft Entra ID (Azure AD), single-tenant
- MCP SDK: ModelContextProtocol.AspNetCore 1.2.0
- Server: ASP.NET Core .NET 10
References
- Microsoft docs on
prompt=consent: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#request-an-authorization-code
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗