Implement OAuth 2.1 + Entra ID authentication for an MCP server using a lightweight AS metadata proxy — handling RFC 9728 protected resource metadata, RFC 8414 AS metadata, and a /register endpoint that eliminates client_id prompts for all MCP clients. WHEN: adding OAuth to an MCP server, MCP clients ask users to paste a client_id, authorization redirects go to the wrong endpoint, or debugging Entra DCR limitations.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Implement OAuth 2.1 + Entra ID authentication for an MCP server using a lightweight AS metadata proxy — handling RFC 9728 protected resource metadata, RFC 8414 AS metadata, and a /register endpoint that eliminates client_id prompts for all MCP clients. WHEN: adding OAuth to an MCP server, MCP clients ask users to paste a client_id, authorization redirects go to the wrong endpoint, or debugging Entra DCR limitations.
domain
security-authentication
confidence
high
source
earned
Skill: MCP OAuth + Entra ID Integration
When to invoke
Use this skill when:
Adding/debugging OAuth 2.1 authentication to an MCP server
MCP clients prompt users for a client_id that should be automatic
MCP clients redirect to the wrong /authorize endpoint (server instead of Entra)
Client → GET /mcp → 401 WWW-Authenticate: Bearer resource_metadata="..."
→ GET /.well-known/oauth-protected-resource
returns: { authorization_servers: ["..."] }
→ GET {auth_server}/.well-known/oauth-authorization-server
(or openid-configuration)
returns: { authorization_endpoint, token_endpoint, registration_endpoint? }
→ POST {registration_endpoint} ← only if client has no pre-registered client_id
returns: { client_id }
→ redirect user to authorization_endpoint with client_id + PKCE
Entra ID limitation: Does not support RFC 7591 Dynamic Client Registration (DCR) for
public clients. VS Code has a hardcoded client_id (aebc6443-996d-45c2-90f0-388ff96faa56)
and does not need DCR. Other MCP clients (Claude Desktop, Cline, custom) do not, so they
ask the user to paste a client_id.
Solution pattern: OAuth Proxy
Run PoshMcp itself as a lightweight AS metadata proxy:
X-Forwarded-* headers — Azure Container Apps sets X-Forwarded-Proto=https and
X-Forwarded-Host={fqdn}. Always use these when building absolute URLs in endpoints.
Otherwise the issuer and registration_endpoint will show http:// instead of https://.
Entra tenant URL format — Use https://login.microsoftonline.com/{tenant}/v2.0 as
the Entra issuer, NOT https://login.microsoftonline.com/{tenant} (the /v2.0 suffix is
required for modern tokens and the correct /.well-known/openid-configuration endpoint).
Entra client authorization — Any client_id returned by /register must be pre-authorized
in the Entra app registration under Expose an API → Authorized client applications.
Without this, Entra returns AADSTS65001 ("User or administrator has not consented").
VS Code built-in client_id = aebc6443-996d-45c2-90f0-388ff96faa56.
This must be added to Authorized client applications in the Entra app registration.
OAuth proxy vs pointing directly to Entra — Pointing AuthorizationServers directly
to Entra works for VS Code but not for generic MCP clients (no DCR). The proxy approach
handles both via the /register fallback.
StringValues.FirstOrDefault() — In ASP.NET Core, Request.Headers["X-Forwarded-Proto"]
returns StringValues, not string. Call (string?)req.Headers["X-Forwarded-Proto"]
or add using System.Linq and use .FirstOrDefault().