Skip to content

OAuth dynamic client registration fails for Claude Desktop #8113

Description

@sentry

Sentry Issue: FLAGSMITH-API-5P9

Claude Desktop cannot connect to mcp.flagsmith.com. When the user clicks Connect, Claude Desktop shows "Couldn't register with Flagsmith's sign-in service".

Repro, no Claude Desktop needed:

curl -X POST https://api.flagsmith.com/o/register/ -H 'Content-Type: application/json' \
  -d '{"client_name":"Claude Desktop","redirect_uris":["http://localhost:65432/callback","claude://oauth/callback"]}'
# HTTP 500

Three issues break this flow:

  1. DCRRequestSerializer.redirect_uris uses a URLField child, whose Django URLValidator only accepts http/https/ftp/ftps. Private-use scheme redirect URIs, which native apps register per RFC 8252 §7.1, are rejected as "Enter a valid URL" before our own validate_redirect_uri policy runs. The policy in oauth2_metadata/services.py also enforces https-or-localhost, so custom schemes are rejected at both layers.
  2. When the first invalid URI is not at index 0, _rfc7591_error_response in oauth2_metadata/views.py crashes with KeyError: 0 — DRF returns list-child errors as a dict keyed by index, and the code does messages[0] assuming a list. The client gets a 500 instead of a clean invalid_redirect_uri 400. This is surfaced in the Sentry issue.
  3. When the invalid URI is at index 0, the 400's error_description is the raw repr [ErrorDetail(string='Enter a valid URL.', code='invalid')] rather than the message text.

The fix that unblocks customers is accepting private-use scheme redirect URIs for DCR clients (exact match, no wildcards, as today), alongside the crash and error-message fixes.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions