anthropics / anthropics/claude-ai-mcp
Custom MCP connector fails with "Failed to start MCP authorization" before any request reaches the server (PKCE-only, no client_secret)
- Linguagem predominante
- Sem dados de linguagem
- Estrelas
- 471
- Forks
- 76
- Métricas de merge de PRs
- Nenhum PR com merge em 30d
Descrição
### What happened?
## Summary
Connecting a custom MCP connector fails at the very start of the OAuth flow. The client-side console shows `Failed to start MCP authorization` and a `400 Bad Request` on an internal `claude.ai/api/organizations/.../...` call — before any network request is ever sent to our MCP server. We've independently verified our server-side OAuth/MCP implementation is fully spec-compliant and working (details below), which points to a bug in Claude's connector/authorization client itself.
## Environment
- MCP server URL: `https://conpoc.graniteshares.com/mcp`
- Connector config: custom connector, "Individual sign-in" method
- OAuth Client ID / Client Secret fields: left blank (relying on Dynamic Client Registration + PKCE)
- Tested via: claude.ai in Edge (browser), and Claude Desktop (same failure in both)
- Underlying MCP server: Microsoft Data API Builder (DAB) 2.0.9, fronted by a custom Node/Express OAuth shim (auth server + reverse proxy)
## What we verified works correctly (server-side)
1. `/.well-known/oauth-protected-resource` — returns valid RFC 9728 metadata, `resource` matches the `/mcp` endpoint, `authorization_servers` populated correctly.
2. `/.well-known/oauth-authorization-server` and `/.well-known/openid-configuration` — both return consistent metadata with `token_endpoint_auth_methods_supported: ["none"]` (public client, PKCE-only).
3. `POST /register` (Dynamic Client Registration, RFC 7591) — accepts a registration request and returns a spec-compliant response (client_id, echoed redirect_uris, token_endpoint_auth_method: "none").
4. `GET /authorize` → user approval → redirect to `https://claude.ai/api/mcp/auth_callback?code=...&state=...` — confirmed working via manual browser test, correct `code` and `state` passed through.
5. `POST /token` — correctly validates the PKCE `code_verifier` against the stored `code_challenge` (S256), issues and persists a Bearer access token. Verified directly via curl with a real authorization code and works correctly, returning `invalid_grant` for garbage codes as expected.
6. `GET/POST /mcp` — correctly enforces auth, returning `401` with a proper `WWW-Authenticate: Bearer resource_metadata="https://conpoc.graniteshares.com/.well-known/oauth-protected-resource"` header when no/invalid token is present.
7. The underlying MCP server (DAB) correctly implements the MCP `initialize` handshake — verified directly via curl with a valid JSON-RPC `initialize` request, returns a proper `2024-11-05` protocol response with `serverInfo`, `capabilities`, and a `Mcp-Session-Id` header.
Server-side (IIS + Node) logs confirm: during real connect attempts from Claude, **no requests at all reach our server** — not even the initial discovery fetch. Manual curl tests to every endpoint above succeed; only Claude-initiated attempts fail silently before leaving the browser/backend.
## Console error captured during a failed connect attempt (claude.ai, Edge)
```
GET https://claude.ai/api/organizations//...
400 (Bad Request)
[REACT_QUERY_CLIENT] QueryClient error:
ye: Failed to start MCP authorization
at we (shared-0-B6nQ_22V.js:1:3925)
at shared-0-B6nQ_22V.js:1:124260
at async Object.mutationFn (shared-2-DxokTDcv.js:2:225608)
```
This error fires immediately on clicking "Connect" — before any request to our domain (`conpoc.graniteshares.com`) appears in the Network tab. It appears the failure originates in Claude's own backend/frontend, at the step that should initiate the OAuth authorization request.
## UI-facing error
> Couldn't register with Azure Sql Mcp's sign-in service. You can try again, or add an OAuth Client ID in the connector settings. If this persists, share this reference with support: "ofid_..."
Reference IDs collected across multiple attempts:
- `ofid_8f0488db9eae43a8`
- `ofid_9aca44551e7027a8`
- `ofid_ebf0fa70e2b4c621`
- `ofid_b617af81e7f2e506`
When a Client ID is manually supplied (copied from a prior `/register` response) instead of left blank, the error changes to:
> Couldn't connect to the server. Check that the URL points to a valid MCP server.
(Also with an `ofid_...` reference, `ofid_9aca44551e7027a8`.)
## Steps to reproduce
1. Add a custom connector with URL `https://conpoc.graniteshares.com/mcp`, leave OAuth Client ID and Client Secret blank, "Individual sign-in" enabled.
2. Click "Connect".
3. Observe: UI shows "Couldn't register with [connector]'s sign-in service", with an `ofid_...` reference.
4. Open browser DevTools Console during the attempt: see `Failed to start MCP authorization` and a `400` on an internal `claude.ai/api/organizations/...` endpoint, with zero requests to the connector's domain in the Network tab.
## Expected behavior
Given the server implements RFC 9728 (protected resource metadata), RFC 8414 (authorization server metadata), RFC 7591 (dynamic client registration), and PKCE (RFC 7636) correctly and completely — verified via direct manual testing of every endpoint — the connector should be able to complete the full discovery → registration → authorize → token exchange flow.
## Suspicion
Possibly a bug specific to connectors configured with **no manually-provided Client ID/Secret** (i.e., relying entirely on Dynamic Client Registration with `token_endpoint_auth_method: "none"`), where Claude's client-side authorization-initiation code may be hitting an error before making any outbound request — plausibly related to how the organization-scoped `/api/organizations/.../...` call is constructed or validated.
### What did you expect to happen?
Given the server implements RFC 9728 (protected resource metadata), RFC 8414 (authorization server metadata), RFC 7591 (dynamic client registration), and PKCE (RFC 7636) correctly and completely — verified via direct manual testing of every endpoint — the connector should be able to complete the full discovery → registration → authorize → token exchange flow.
Suspicion
Possibly a bug specific to connectors configured with no manually-provided Client ID/Secret (i.e., relying entirely on Dynamic Client Registration with token_endpoint_auth_method: "none"), where Claude's client-side authorization-initiation code may be hitting an error before making any outbound request — plausibly related to how the organization-scoped /api/organizations/.../... call is constructed or validated.
### Steps to reproduce
Steps to reproduce
Add a custom connector with URL https://conpoc.graniteshares.com/mcp, leave OAuth Client ID and Client Secret blank, "Individual sign-in" enabled.
Click "Connect".
Observe: UI shows "Couldn't register with [connector]'s sign-in service", with an ofid_... reference.
Open browser DevTools Console during the attempt: see Failed to start MCP authorization and a 400 on an internal claude.ai/api/organizations/... endpoint, with zero requests to the connector's domain in the Network tab.
### Area
MCP Connector (adding/managing servers)
### MCP Server (if applicable)
MS SQL MCP
### Error messages or logs
```shell
```
### Additional context
_No response_
Guia de contribuição
Nenhum guia de contribuição indexado para este repositório
Avaliação
Esta issue ainda não foi avaliada.