anthropics / anthropics/claude-ai-mcp
Custom connector: mcp_token_exchange_failed against Entra ID, while the identical exchange succeeds manually
- Lingua principale
- Nessun dato sulla lingua
- Stelle
- 471
- Fork
- 77
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
## Summary
An organization-level custom connector (individual sign-in) against a self-hosted MCP
server protected by Microsoft Entra ID consistently fails at the token exchange. The
authorization leg completes; the exchange never yields a token and the browser ends on
`/new?error_code=mcp_token_exchange_failed`.
The identical exchange — same client ID, client secret, redirect URI, scope, and the
RFC 8707 `resource` parameter — **succeeds when performed by hand** against the same
Entra tenant, and the resulting token is accepted by the MCP server.
## Reference IDs
- Latest attempt: `ofid_5f0a1ff30010f6aa`
- Earlier attempts: `ofid_bab1fa6ed1fc22f3`, `ofid_874c902c7f8af90b`
- Entra trace IDs shown in the connector error banner:
`963315dd-eae0-4fb4-b8e4-88de75480300`, `697696c1-5c84-4395-838c-39491e6a0f00`
- Support conversation ID: `215475359536447`
## Environment
- claude.ai, organization-level custom connector, *Individual sign-in* enabled
- MCP server: self-hosted on Azure Container Apps, Streamable HTTP, public HTTPS with a
managed certificate (URL available on request)
- Authorization server: Microsoft Entra ID, single-tenant app registration
- Edge on Windows 11
## What the server logs show during a Connect attempt
```
POST /mcp 401 Unauthorized
GET /.well-known/oauth-protected-resource 200 OK
POST /mcp 401 Unauthorized
… nothing further — no request ever arrives carrying a token
```
The 401 responses carry
`WWW-Authenticate: Bearer error="missing_token", …, resource_metadata="/.well-known/oauth-protected-resource"`.
`/.well-known/oauth-protected-resource` returns 200 with:
```json
{
"resource": "",
"authorization_servers": ["https://login.microsoftonline.com//v2.0"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["api:///access_as_user"]
}
```
## The identical exchange succeeds manually
```
POST https://login.microsoftonline.com//oauth2/v2.0/token
client_id=
client_secret=
grant_type=authorization_code
code=
redirect_uri=
scope=api:///access_as_user
resource=/mcp
```
→ HTTP 200 with an access token. Claims: `aud=`,
`iss=https://login.microsoftonline.com//v2.0`, `scp=access_as_user`.
The MCP server accepts that token — `initialize` returns `serverInfo`.
Also verified to succeed with `offline_access` added to the scope alongside `resource`.
## App registration state
- Platform **Web** only — no SPA redirect URIs, no public-client redirect URIs,
`isFallbackPublicClient` unset
- `requestedAccessTokenVersion: 2`
- Two Application ID URIs: `api://` and the full MCP endpoint URL ending in
`/mcp`, no trailing slash
- The client is pre-authorized for its own `access_as_user` scope, so no interactive
consent is required
- All redirect URIs registered, including `https://claude.ai/api/mcp/auth_callback`
## What we already tried
- Deleted and recreated the connector from scratch with a freshly created client secret
- Rotated the client secret
- Changed `requestedAccessTokenVersion` from `null` to `2`. This was a real bug on our
side: v1 tokens carry `iss=https://sts.windows.net//`, which our server
rejects. Fixed, but it did not change the connector symptom.
- Added the full MCP URL as an additional Application ID URI, on support's advice. This
fixed `AADSTS9010010 invalid_target` for the *manual* exchange with `resource`, but
did not change the connector symptom.
The symptom is unchanged in every case.
## What would help
The verbatim response Entra returned to the connector's token request for the trace IDs
above, or the exact parameter set the connector sends on the token request. Every
parameter combination we can construct by hand succeeds, so we cannot reproduce the
failure outside the connector.
Happy to supply the server URL, tenant ID and client ID privately if that helps the
server-side trace.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Direzione di ricerca
Start by tracing the custom connector OAuth flow from the /mcp 401 and /.well-known/oauth-protected-resource response to the Microsoft Entra /oauth2/v2.0/token request, using the listed trace IDs. Compare the connector's exact parameters and response with the successful manual exchange; done means the connector receives an access token and the MCP initialize request succeeds.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- azure
- Ambito
- api, authentication
- Tipo di issue
- Bug
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Tranquilla
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 35/100