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
- 主要言語
- 言語のデータがありません
- スター
- 471
- フォーク
- 76
- PR マージ指標
- 30日以内にマージされた PR はありません
説明
### 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_
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
評価
この issue はまだ評価されていません。