anthropics / anthropics/claude-ai-mcp
Custom connector completes DCR + authorize + /token (200) then never contacts the MCP endpoint — "Authorization with <connector> failed"
- Langage dominant
- Aucune donnée de langage
- Étoiles
- 471
- Forks
- 76
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Description
## Summary
A custom remote MCP connector completes the **entire** OAuth flow against our server — dynamic client registration, authorize redirect, Google sign-in, and `POST /token` returning **200** — and then claude.ai's backend never sends another request. The UI shows *"Authorization with `` failed. You can check your credentials and permissions."*
Two other Anthropic clients complete the identical flow against the **same server on the same day** and go on to call tools: **Claude Code 2.1.172** and the **official MCP Python SDK** (`OAuthClientProvider` + `streamablehttp_client`). Anthropic support reviewed our server-side logs and suggested filing here with the `ofid_` references so the connector's post-token behavior can be traced server-side.
Hostname redacted here for privacy; it is on file with support under the references below and can be shared privately.
## Support references
`ofid_d30d22f2f2b51ff5`, `ofid_cc2e9efecfc9736b`, `ofid_7d77761a334a1c52`
## Server
- MCP endpoint: `https://mcp./sse` — serves **both** Streamable HTTP (`POST`) and legacy HTTP+SSE (`GET`).
- Self-hosted OAuth 2.1 authorization server at `https://mcp.` (same origin), discovered via RFC 9728: unauthenticated `POST /sse` → `401` with `WWW-Authenticate: Bearer resource_metadata="https://mcp./.well-known/oauth-protected-resource", scope="mcp"`.
- PRM: `{"resource":"https://mcp./sse","authorization_servers":["https://mcp."]}` — `resource` equals the connector URL exactly (lowercase, no trailing slash).
- AS metadata: `authorization_code` + `refresh_token`; PKCE `S256` only; `token_endpoint_auth_methods_supported: ["none"]`; `scopes_supported: ["mcp"]`; `authorization_response_iss_parameter_supported: true`.
- DCR (RFC 7591) issues public clients (`token_endpoint_auth_method: none`, no client secret).
- Tokens: JWTs with `aud` = `https://mcp./sse` (exactly the RFC 8707 `resource` the connector sends) and `iss` = the AS issuer; `expires_in: 3600`; refresh tokens issued; token responses carry `Cache-Control: no-store` / `Pragma: no-cache`.
- No redirects on the HTTPS endpoint (GET/POST/HEAD, trailing slash, mixed case all answer directly). `/token` latency ~4 ms.
- CDN bot protection ruled out: the connector's own discovery/registration/token requests all reach the origin; non-browser HTTP clients from residential and cloud egress reach the origin too.
## What the connector does (every attempt, all 2026-09-01 UTC)
1. `POST /sse` (no token) → 401 + `WWW-Authenticate` as above
2. `GET /.well-known/oauth-protected-resource` → 200; `GET /.well-known/oauth-authorization-server` → 200
3. `POST /register` → 201, **twice**, ~1 s apart (`client_name: "Claude"`, `redirect_uris: ["https://claude.ai/api/mcp/auth_callback"]`, `token_endpoint_auth_method: "none"`, `grant_types: ["authorization_code","refresh_token"]`, `scope: "mcp"`)
4. Browser: `GET /authorize?response_type=code&client_id=…&redirect_uri=https://claude.ai/api/mcp/auth_callback&code_challenge=…&code_challenge_method=S256&state=…&scope=mcp&resource=https://mcp./sse` → 302 to Google
5. Google sign-in succeeds → our callback issues a code → 302 to `https://claude.ai/api/mcp/auth_callback?code=…&state=…&iss=…`
6. `POST /token` from `python-httpx/0.28.1` with fields `client_id, code, code_verifier, grant_type, redirect_uri, resource` (`resource=https://mcp./sse`, no client authentication, `Accept: application/json`) → **200** `{"access_token":"…","token_type":"Bearer","expires_in":3600,"refresh_token":"…","scope":"mcp"}`
7. **Nothing further.** No `POST /sse`, no `GET /sse`, no refresh — the token is never used. UI reports the authorization failure.
| Attempt window (UTC) | DCR `client_id` used at /authorize | `/token` |
|---|---|---|
| 19:41:23 – 19:41:28 | `mcp-943c9dda6b80478390b65fff91f65814` | 200 |
| 19:43:23 – 19:43:27 | `mcp-2e2fe9b9a647456a952b89e924f9794b` | 200 |
| 20:12:31 – 20:12:35 | `mcp-f76d6d2fbd1d4411b34f0bab6c27203a` | 200 |
| 20:13:29 – 20:13:32 | `mcp-451dee42a36c46c99e2b585d51369aa0` | 200 |
| 20:13:59 – 20:14:02 | `mcp-c4cd436dcbca4da6aaf945ba2573fcc2` | 200 |
| 20:25:43 – 20:25:47 | `mcp-fe25e98dcc404ff49b98be7366cd27eb` | 200 |
## Controls (same server, same day)
- **Claude Code 2.1.172**, 20:27:22–20:27:27 UTC, `client_id mcp-d5210083dce6426191cb8f9b036cb111`, `redirect_uri http://localhost:3118/callback`: identical discovery → DCR → authorize → Google → `/token` 200, then immediately `POST /messages/` (legacy SSE transport) and `ListToolsRequest` — **works**.
- **Official MCP Python SDK** (`OAuthClientProvider` with `streamablehttp_client`, `token_endpoint_auth_method: none`, redirect `https://claude.ai/api/mcp/auth_callback`, only the Google screen stubbed): DCR → authorize → `/token` 200 → `initialize` (protocol 2025-11-25) → `tools/list` → `tools/call` — **works**.
## Ask
Please trace what the claude.ai connector backend does after receiving the 200 token response for the client IDs / timestamps above. Possibly related: #215, #690.
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Évaluation
Cette issue n'a pas encore été évaluée.