anthropics / anthropics/claude-ai-mcp
Custom connector: DCR fails against GitLab.com MCP server (mcp_registration_failed) while Claude Code and manual registration both succeed
- Vorherrschende Sprache
- Keine Sprachdaten
- Sterne
- 471
- Forks
- 77
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
### MCP server URL or name
https://gitlab.com/api/v4/mcp;
### How are you connecting to this server?
From a custom connector URL I entered manually
### Where does the issue occur?
In the authorization screen
### When did you last reproduce this?
2026-08-04 20:30
### Browser and OS
Chrome 150.0.7871.187 (Official Build) (arm64); MacOS 26.4.1
### Describe the issue
# Custom connector: DCR fails against GitLab.com MCP server (`mcp_registration_failed`) while Claude Code and manual registration both succeed
## Summary
Adding `https://gitlab.com/api/v4/mcp` as a **custom connector** (Web, Individual sign-in, no
pre-configured OAuth client) fails at the dynamic client registration step with
`oauth_error=mcp_registration_failed`, before the user ever reaches GitLab's consent screen.
The same endpoint registers successfully via **Claude Code**'s own DCR, and via a hand-rolled
`curl` request to GitLab's `registration_endpoint`. Only the claude.ai connector flow fails,
which isolates the problem to the registration payload claude.ai sends.
The error message suggests supplying an OAuth Client ID instead. **That workaround is not
available on GitLab.com** — see "Why the suggested workaround is impossible" below — so on
GitLab SaaS this bug leaves no working path to a GitLab custom connector.
## Environment
| | |
|---|---|
| Plan | Claude Team |
| Added via | Admin settings → Connectors → Add custom connector → Web |
| Connection method | Individual sign-in |
| OAuth Client ID / Secret | left blank (expecting DCR) |
| Request headers | not available on this org |
| MCP server | GitLab.com SaaS, MCP server (beta, GitLab 18.6) |
| Endpoint | `https://gitlab.com/api/v4/mcp` |
Flow references: `ofid_1c2adc4b167923a0`, `ofid_e05b3890a0ee457a`
## What happens
UI error:
> Couldn't register with GitLab'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_1c2adc4b167923a0"
Redirect URL:
```
https://claude.ai/desktop/connected/new?&mcp_auth_source=settings_connect
&server=&step=start_error&flow_id=ofid_e05b3890a0ee457a
&oauth_error=mcp_registration_failed
```
## Discovery chain is fully spec-compliant on GitLab's side
**1. Endpoint returns a correct challenge with a resource metadata pointer**
```
$ curl -s -o /dev/null -D - -X POST https://gitlab.com/api/v4/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}'
HTTP/2 401
www-authenticate: Bearer realm="GitLab",
resource_metadata="https://gitlab.com/.well-known/oauth-protected-resource/api/v4/mcp"
```
**2. Protected resource metadata advertises exactly one scope**
```
$ curl -s https://gitlab.com/.well-known/oauth-protected-resource/api/v4/mcp
{
"resource": ["https://gitlab.com/api/v4/mcp"],
"authorization_servers": ["https://gitlab.com"],
"scopes_supported": ["mcp"]
}
```
**3. Authorization server metadata advertises DCR — and 26 unrelated scopes**
```
$ curl -s https://gitlab.com/.well-known/oauth-authorization-server
issuer: https://gitlab.com
authorization_endpoint: https://gitlab.com/oauth/authorize
token_endpoint: https://gitlab.com/oauth/token
registration_endpoint: https://gitlab.com/oauth/register
code_challenge_methods_supported: ["plain", "S256"]
scopes_supported: ["api", "read_api", "read_user", "create_runner",
"manage_runner", "k8s_proxy", "self_rotate", "mcp", "mcp_orbit", "read_repository",
"write_repository", "read_registry", "write_registry", "read_virtual_registry",
"write_virtual_registry", "read_observability", "write_observability", "ai_features",
"sudo", "admin_mode", "read_service_ping", "openid", "profile", "email",
"ai_workflows", "user:*"]
```
**4. Manual registration against that endpoint succeeds**
```
$ curl -s -X POST https://gitlab.com/oauth/register \
-H 'Content-Type: application/json' \
-d '{"client_name":"Claude","redirect_uris":["https://example.test/cb"]}'
HTTP 201
{
"client_id": "",
"redirect_uris": ["https://example.test/cb"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code"],
"require_pkce": true,
"client_name": "[Unverified Dynamic Application] Claude",
"scope": "mcp",
"dynamic": true
}
```
Note GitLab issues dynamic clients with **`scope: "mcp"`, and only that scope**.
**5. Claude Code registers against the same endpoint without issue**
A Claude Code user-scope entry of `{"type": "http", "url": "https://gitlab.com/api/v4/mcp"}`
with no headers and no env completes DCR + OAuth and has been working. So the endpoint, the
DCR implementation, and the SSO-backed sign-in are all functional.
## Probable cause
GitLab restricts dynamically registered ("unverified") clients to the `mcp` scope. There is an
existing report that Claude's remote-MCP OAuth client requests **every** scope listed in the
authorization server's `scopes_supported` rather than the scopes advertised by the *protected
resource* metadata — anthropics/claude-code#55954. On gitlab.com that means requesting all 26
scopes above, including `api`, `sudo`, and `admin_mode`, which GitLab rejects for a dynamic
client.
Per RFC 9728, the scope set for a resource should come from the protected resource metadata —
here unambiguously `["mcp"]` — not from the authorization server's full catalogue.
Secondary possibility: GitLab's `client_name` limit. GitLab prepends a 32-character
`[Unverified Dynamic Application] ` prefix and rejects the result above roughly 150–200
characters with `{"error":"invalid_client_metadata","error_description":"client_name is too
long"}`. If claude.ai composes a long `client_name`, that would also produce a registration
failure.
## Why the suggested workaround is impossible on GitLab.com
The error text advises supplying an OAuth Client ID. On GitLab SaaS there is no way to create
an OAuth application that can carry the `mcp` scope:
- GitLab documents the shared/pre-configured OAuth application path under
`Offering: GitLab Self-Managed, GitLab Dedicated` only, created via instance
**Admin → Applications**, which SaaS customers cannot access.
- Group-level and user-level application forms on gitlab.com omit `mcp` from the selectable
scope list entirely (also absent: `self_rotate`, `mcp_orbit`, `ai_workflows`, `user:*`).
So DCR is the only available authentication path on GitLab.com, and this bug blocks it.
## Suggested fix
Derive the requested scope from the protected resource metadata's `scopes_supported` (falling
back to omitting `scope` entirely, which RFC 7591 permits and which GitLab now defaults to
`mcp` — see gitlab-org/gitlab!208967) rather than from the authorization server's
`scopes_supported`.
## References
- anthropics/claude-code#55954 — remote MCP OAuth requests every scope from
`oauth-authorization-server.scopes_supported`, causing `invalid_scope` on GitLab
- gitlab-org/gitlab#585699 — MCP Server OAuth flow fails for all scope requests on GitLab.com
- gitlab-org/gitlab!208967 — default OAuth scope to `mcp` for dynamic client registration
- GitLab MCP server docs — https://docs.gitlab.com/user/model_context_protocol/mcp_server/
### Error details
```shell
Couldn't register with GitLab's sign-in service. You can try again, or add an Auth Client ID in the connector settings. If this persists, share this reference with support:
"ofid_1c2adc4b167923a0"
```
### Expected behavior
Connection was successful.
### Additional context
_No response_
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Start with the custom connector authorization flow and compare its dynamic client registration request with the successful curl request to GitLab's registration_endpoint and the Claude Code flow. Check how scopes are selected from the protected resource metadata versus the authorization server metadata, and verify the client_name length. Done means the GitLab.com connector completes registration and reaches the consent screen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- gitlab
- Bereich
- api, authentication
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Ruhig
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 48/100