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:
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.
- 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.
- 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.
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:
Three issues break this flow:
DCRRequestSerializer.redirect_urisuses aURLFieldchild, 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 ownvalidate_redirect_uripolicy runs. The policy inoauth2_metadata/services.pyalso enforces https-or-localhost, so custom schemes are rejected at both layers._rfc7591_error_responseinoauth2_metadata/views.pycrashes withKeyError: 0— DRF returns list-child errors as a dict keyed by index, and the code doesmessages[0]assuming a list. The client gets a 500 instead of a cleaninvalid_redirect_uri400. This is surfaced in the Sentry issue.error_descriptionis 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.