Entra ID OIDCProxy¶
Deploying the Zscaler MCP Server with Microsoft Entra ID as the OIDCProxy IdP. This is the deployment pattern for Microsoft-shop customers who want enterprise SSO for the MCP client (Claude Desktop, Cursor, etc.) without rolling Auth0 or Okta.
Why a dedicated guide¶
Entra ID’s OIDC behavior differs from Auth0 / Okta in one critical way: the aud (audience) claim in ID tokens is set to the client_id, not to a separate API identifier. Most OIDCProxy examples assume Auth0 semantics, where audience is a separate API resource. Configuring Entra ID with an Auth0-style audience value causes immediate 401 failures with confusing error messages.
This guide gives you the exact Entra ID values that work.
Prerequisites¶
Microsoft Entra ID tenant (any Entra ID Free, P1, or P2 tier)
Permission to register an application in Entra ID
A running MCP server reachable at an HTTPS URL (Cloud Run, Container Apps, ECS, your own ingress, etc.)
Step 1 — Register an Entra ID application¶
In the Azure portal:
Entra ID → App registrations → New registration
Name:
Zscaler MCP ServerSupported account types: usually “Accounts in this organizational directory only (Single tenant)”
Redirect URI: pick Public client/native (mobile & desktop) with the URI
http://localhost:6274/callbackThis is the redirect URI that the
mcp-remoteCLI uses by default. Don’t change it unless you’ve also overridden it in the client config.
Click Register.
On the application overview page, note the Application (client) ID and Directory (tenant) ID — you’ll need both.
Step 2 — Enable the device code flow¶
OIDCProxy delegates the auth flow to the MCP client. For mcp-remote, that flow is the OAuth authorization-code flow with PKCE.
Authentication → Add a platform → Mobile and desktop applications (if not already added)
Check the box for the
http://localhost:6274/callbackredirect URI you registeredUnder Advanced settings, enable Allow public client flows (set to Yes)
Save
Step 3 — Configure API permissions¶
The token Entra ID issues needs to carry at least the openid and profile scopes.
API permissions →
Microsoft Graphis added by default withUser.Read. Leave it.API permissions → Add a permission → Microsoft Graph → Delegated permissions → check openid and profile → Add permissions.
Step 4 — Deploy the MCP server with OIDCProxy¶
Set the OIDCProxy environment variables on your MCP server deployment:
# Entra ID values
export OIDCPROXY_AUTH_ISSUER="https://login.microsoftonline.com/<TENANT_ID>/v2.0"
export OIDCPROXY_AUTH_AUTHORIZATION_ENDPOINT="https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/authorize"
export OIDCPROXY_AUTH_TOKEN_ENDPOINT="https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token"
export OIDCPROXY_AUTH_JWKS_URI="https://login.microsoftonline.com/<TENANT_ID>/discovery/v2.0/keys"
# The key Entra ID difference: audience MUST equal client_id
export OIDCPROXY_AUTH_AUDIENCE="<CLIENT_ID>"
# Standard OIDC scopes
export OIDCPROXY_AUTH_SCOPES="openid profile offline_access"
# MCP server settings (HTTP transport + auth disabled, since OIDCProxy is the auth)
export ZSCALER_MCP_AUTH_ENABLED=false
export ZSCALER_MCP_ALLOW_HTTP=true # if TLS is terminated upstream (Cloud Run, etc.)
Replace <TENANT_ID> with your Entra ID directory ID and <CLIENT_ID> with the application’s client ID from Step 1.
The Entra-specific gotcha¶
Warning
OIDCPROXY_AUTH_AUDIENCE must be exactly equal to the client_id, not a separate API identifier. Entra ID issues ID tokens whose aud claim is the client_id. If you set OIDCPROXY_AUTH_AUDIENCE to anything else, every token validation fails with a misleading invalid_audience error.
This is the inverse of the Auth0 convention, where audience is a distinct API identifier and the client_id is not the right value.
Step 5 — Configure the MCP client¶
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"zscaler-mcp-server": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://your-mcp-server.example.com/mcp"
]
}
}
}
Cursor (~/.cursor/mcp.json): same config — Cursor and Claude Desktop use the same mcp-remote flow for OIDCProxy auth.
Restart the MCP client. On the first MCP call, mcp-remote opens your browser to the Entra ID sign-in page; after consent, the client caches the refresh token and won’t prompt again until it expires.
Verification¶
Once configured, the server’s startup banner should show:
[SECURITY] transport=streamable-http auth=OIDCProxy (issuer=https://login.microsoftonline.com/<TENANT_ID>/v2.0)
And the first tool call from the MCP client should succeed without an additional credential prompt (after the initial browser-based sign-in).
Common errors¶
Symptom |
Likely cause |
|---|---|
401 |
|
400 |
The user signing in is in a different Entra ID tenant than the app registration. Verify the supported account types in Step 1. |
Browser redirect fails to |
The redirect URI in the Entra ID app doesn’t match the URI |
403 from the MCP server after Entra ID sign-in succeeds |
The auth middleware is still trying to validate the original Entra token. Make sure |
See also¶
MCP Client Authentication — the full set of authentication modes, including JWT and api-key alternatives.
Azure Deployment — deploying the server to Azure Container Apps / VM / AKS.
Process Lifecycle Management — credential rotation without container restart.