Altinity / Altinity/altinity-mcp
oauth: add opt-in Cursor support in broker mode via DCR compatibility
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 38
- Forks
- 8
- Avg merge
- 6d 14h
- Merged PRs (30d)
- 8
Description
Goal
Allow Cursor users to connect to an Altinity MCP server using OAuth in broker mode.
Altinity MCP currently supports Client ID Metadata Documents (CIMD) for inbound OAuth client metadata. Cursor currently attempts Dynamic Client Registration (DCR) in the affected flow, so it cannot complete OAuth against the server: discovery does not advertise a registration_endpoint, and /oauth/register returns HTTP 410.
The implementation should add the minimum DCR compatibility needed for the verified Cursor OAuth flow without changing CIMD behavior for Claude, ChatGPT, or other CIMD-capable clients.
User experience
When an operator enables Cursor compatibility and configures the Altinity MCP URL in Cursor:
- Cursor discovers the MCP protected resource and authorization server metadata.
- Cursor dynamically registers as a public OAuth client.
- Cursor completes the authorization-code flow with PKCE
S256through the existing OAuth broker. - Cursor receives an access token and can connect to the MCP server.
The feature must be disabled by default because DCR exposes an unauthenticated client-registration and redirect-registration surface.
Proposed configuration
Add the following setting under server.oauth:
server:
oauth:
dcr_compatibility_enabled: false
Environment variable:
MCP_OAUTH_DCR_COMPATIBILITY_ENABLED
The setting is valid only when server.oauth.broker: true. Startup should reject dcr_compatibility_enabled: true when broker mode is disabled.
Do not enable this setting in Helm values, examples, or production defaults.
Required behavior
When disabled
Preserve the current behavior exactly:
- advertise
client_id_metadata_document_supported: true; - do not advertise
registration_endpoint; - return HTTP 410 from
/oauth/registerwith the existing CIMD migration response; - keep all existing CIMD flows unchanged.
When enabled in broker mode
- Continue advertising
client_id_metadata_document_supported: true. - Advertise
registration_endpointin authorization-server and OpenID Connect discovery metadata. - Accept the minimal RFC 7591 registration request used by the verified Cursor flow.
- Register Cursor as a public client using
token_endpoint_auth_method: none. - Support only the authorization-code flow with PKCE
S256; never accept PKCEplain. - Return the registration response fields Cursor requires.
- Encode the registered client metadata in an encrypted, tamper-evident, expiring client identifier so no durable client database is required.
- Use a DCR-specific, versioned HKDF/JWE context, separate from CIMD, pending authorization state, and authorization codes.
- Resolve DCR client identifiers at both
/authorizeand/token, while continuing to resolve URL-shaped CIMD client identifiers through the existing CIMD resolver. - Validate the redirect URI against the registered metadata at
/authorizeand/token. - Reject expired, malformed, or tampered DCR client identifiers.
- Do not issue or accept client secrets.
- Do not issue downstream refresh tokens in the first version of Cursor support.
Input and abuse controls
The registration endpoint is unauthenticated and must have a deliberately small attack surface:
- apply a small request-body limit;
- require JSON and reject malformed or trailing content;
- reject duplicate JSON object keys;
- bound the number and length of fields and redirect URIs;
- validate every redirect URI according to the verified Cursor fixture;
- return RFC 7591 JSON error responses without reflecting sensitive input;
- rate-limit registration attempts and return HTTP 429 when the limit is exceeded;
- log registration outcomes without logging full redirect URLs, authorization codes, tokens, or other credentials.
The documentation must explain that enabling this option allows dynamically registered clients to begin an authorization flow through the broker and is an explicit operator security decision.
Compatibility fixture
Capture and sanitize a successful Cursor registration, authorization, and token exchange before finalizing the implementation. Retain it as an automated fixture so Cursor's actual behavior—not assumptions about its OAuth implementation—is the compatibility contract.
The fixture should identify the Cursor version and surface being tested and include:
- authorization-server discovery;
- the registration request and response;
- the
/authorizerequest parameters; - the
/tokenrequest and response shape; - redirect URI values;
- client authentication method;
- PKCE method;
- requested grant types and scopes.
Tests
Add automated coverage for:
- the captured Cursor flow from discovery through token exchange;
- default/disabled metadata and the existing 410 tombstone;
- enabled discovery advertising CIMD and DCR together;
- existing CIMD flows with Cursor compatibility both disabled and enabled;
- malformed, duplicate-key, trailing, and oversized registration payloads;
- unsupported client authentication and response types;
- missing or invalid PKCE
S256at/authorizeand/token; - redirect validation and mismatch failures;
- expired, malformed, and tampered DCR client identifiers;
- isolation between DCR and the other HKDF/JWE contexts;
- registration rate limiting.
Documentation
Update the OAuth guide and changelog to explain:
- how to enable Cursor OAuth compatibility;
- that CIMD remains the preferred client-metadata mechanism;
- that DCR support is opt-in and limited to the compatibility behavior covered by the Cursor fixture;
- the security and operational implications;
- how the feature will be reassessed once Cursor's CIMD support is verified.
Acceptance criteria
- A supported Cursor client completes OAuth end-to-end and can call the MCP server in broker mode.
- Cursor compatibility is disabled by default and is rejected outside broker mode.
- Default deployments retain the existing CIMD-only discovery and 410 registration tombstone.
- Enabling Cursor compatibility advertises DCR alongside CIMD without breaking CIMD clients.
- DCR clients are public clients using authorization code and PKCE
S256; no client secret or downstream refresh token is issued. - Registered client metadata is stateless, encrypted, tamper-evident, expiring, and isolated with a DCR-specific crypto context.
- Registration input, redirect URIs, logging, and abuse controls follow the documented policy.
- A sanitized Cursor exchange is retained as an automated compatibility fixture.
- Operator documentation describes configuration, limitations, and security trade-offs.
Questions for the requester
Please answer these in a comment and attach a sanitized transcript or reproducible test where possible:
- Which Cursor surfaces must be supported: desktop IDE, CLI, web/cloud agents, or all of them? Please include the tested Cursor version for each surface.
- What exact
redirect_urisandapplication_typedoes each supported surface send during registration? - What is the exact DCR request payload, including
grant_types,response_types,scope, andtoken_endpoint_auth_method? - Which fields from the DCR response does Cursor require before it proceeds to
/authorize? - If Cursor requests
refresh_tokenoroffline_accessbut the server registers onlyauthorization_codeand issues no refresh token, does Cursor complete the initial flow and reauthorize successfully after access-token expiry? - How long does Cursor cache the returned
client_id, and does it automatically re-register after aninvalid_clientresponse caused by expiry or signing-key rotation? - Should compatibility accept only the exact Cursor redirect URIs captured above, or is general-purpose DCR for other public clients expected?
- Is a configurable registration path required, or is the existing
/oauth/registerpath sufficient?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing OAuth broker discovery, CIMD resolver, /oauth/register behavior, and related tests. Before implementation, capture and sanitize the verified Cursor registration, authorization, and token exchange as the compatibility fixture. Done means opt-in broker-only DCR support passes the listed security, compatibility, rate-limit, and documentation requirements without changing default CIMD behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- authentication, backend-api-design, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100