Claude OAuth requires dynamic client registration, making Azure AD/Entra ID integration complex
## Issue Description:
I've been working on implementing an MCP server with OAuth 2.1 authentication using Azure Entra ID (formerly Azure AD).
### With VS Code Desktop - Simple and Working
VS Code's implementation is straightforward:
- MCP server provides
/.well-known/oauth-protected-resource:
```json
{
"resource": "https://my-mcp-function.azurewebsites.net",
"authorization_servers": ["https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/v2.0"],
"bearer_methods_supported": ["header"]
}
2. VS Code reads this and redirects user to Azure AD login
3. User authenticates, VS Code receives token, sends it in Authorization header
4. It just works - No extra endpoints needed, uses standard Azure AD OAuth flow
With Claude Apps - Complex Workarounds Required
To make the same MCP server work with Claude (Code/Desktop/ai), I had to:
1. Implement a fake authorization server endpoint at /.well-known/oauth-authorization-server
2. Create a dynamic client registration endpoint at /register that returns:
```json
{
"client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"client_name": "Claude Code (test)",
"redirect_uris": ["http://localhost:64236/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "none",
"application_type": "native",
"scope": "openid profile email offline_access"
}
- Handle the fact that Azure AD URLs need /oauth2 in the path:
- VS Code works with: https://login.microsoftonline.com/{tenant}/v2.0/authorize
- Claude needs: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
- Deal with dynamic redirect URIs - Claude uses random ports (54212, 56619, 57411, 59306, 64236, etc.) requiring constant Azure AD app updates
- Even after all this, still getting errors:
AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid.
The Problem
Azure AD (and many enterprise OAuth providers) don't support dynamic client registration. They require pre-registered applications with fixed redirect URIs and client IDs.
Creating fake registration endpoints and trying to proxy the OAuth flow adds significant complexity compared to VS Code's approach, and still doesn't fully work due to how Claude constructs the authorization requests.
I believe this client oauth2 implementation is also causing github's official remote MCP server to be incompatible with Claude apps https://github.com/github/github-mcp-server/issues/549
This issue has 14 comments on GitHub. Read the full discussion on GitHub ↗