TL;DR
You don’t need to manage anything by hand. MCP-aware clients walk the full OAuth flow themselves the first time they hit the Cometly MCP endpoint:- The client sees a
401 Unauthorizedwith aWWW-Authenticateheader pointing at our OAuth discovery URL. - The client identifies itself — either via a hosted metadata document (CIMD) or by calling the registration endpoint (DCR).
- The client opens your browser to the Cometly authorization page.
- You log in, pick which Space to grant access to, and click Approve.
- The client exchanges the resulting code for an access token bound to that Space.
Authorization: Bearer <token> on every tool call.
If you’re building a custom MCP client, you have two registration paths: CIMD (preferred — no registration call required) and Dynamic Client Registration (fallback, e.g. for custom URI schemes). If you want the gritty detail, keep reading.
Endpoints
Cometly is its own authorization server. There’s no third-party identity provider in the middle.
We expose both the path-prefix (RFC 9728) and path-suffix (RFC 8414)
.well-known URL variants because different clients implement different revisions of the spec. Claude Desktop uses the prefix form; Cursor uses the suffix form. Both resolve to the same metadata.
Discovery metadata
Hitting the auth-server metadata endpoint returns:S256 is required. There’s no implicit grant, no password grant, no client-credentials grant — just authorization code with PKCE.
Client ID Metadata Document (CIMD)
CIMD is the preferred registration path for new custom MCP clients. Instead of calling/mcp/oauth/register to get a client ID, you host a JSON document at an https:// URL and use that URL itself as your client_id — no registration request needed.
Support is advertised via client_id_metadata_document_supported: true in the discovery metadata. If that field is absent or false, fall back to Dynamic Client Registration.
Metadata document
Host a JSON file at any stablehttps:// URL with a non-root path (for example, https://app.example.com/oauth/client-metadata.json). The document must include:
All other fields (
client_uri, grant_types, response_types) are accepted and recorded but not enforced.
client_name. Clients whose only redirect URIs are loopback addresses receive an advisory notice on the consent screen.
Accepted redirect_uris for CIMD clients
Each URI in the document must satisfy one of two rules:
Custom URI schemes (e.g.
cursor://, vscode://) are not accepted for CIMD clients. If your client uses a custom scheme, use Dynamic Client Registration instead — the custom-scheme allowlist applies only to DCR.
The redirect_uri you send on /authorize and /token must exactly match one of the URIs in the document (loopback port normalization per RFC 8252 applies).
Document fetching and caching
On every/authorize request with a URL-shaped client_id, Cometly fetches and validates the metadata document. The fetch is:
- SSRF-guarded — private, loopback, link-local, and cloud-metadata IPs are refused.
- TLS-verified — the certificate must be valid; redirects are not followed by default.
- Rate-limited and size-capped — oversized or excessively frequent responses are rejected.
client_id URL, honoring Cache-Control: max-age up to a 24-hour ceiling (default window 15 minutes). Deploy an updated document and wait up to 24 hours for all caches to clear, or set a shorter max-age on your server’s response.
Dynamic client registration
Dynamic Client Registration (RFC 7591) is the fallback path when CIMD isn’t suitable — for example when your client uses a custom URI scheme (cursor://, vscode://) that CIMD doesn’t accept, or when you can’t host a metadata document at a stable https URL.
POST /mcp/oauth/register with the client’s metadata. Minimal example:
client_id you’ll use for the authorization request. There is no client_secret — Cometly’s MCP server treats every client as a public client and relies on PKCE for security.
Accepted redirect_uris
The redirect URI is validated at registration. Each URI must fall into one of three accepted categories; redirect URIs that don’t match are rejected. This allowlist applies to DCR clients only — CIMD clients use a same-host rule instead.
Default allowed https hosts
These hosts are accepted for DCR clients out of the box. If you need a host that isn’t listed, contact support: support@cometly.com. (CIMD clients don’t need to be on this list — they use the same-host rule described above.)Accepted client_name
client_name is shown verbatim on the consent screen, so it’s validated to prevent impersonation and UI hijacking:
- Maximum 120 characters.
- No control characters (
\x00–\x1f,\x7f). - Names that contain
cometlyas a standalone word (case-insensitive, word/whitespace/hyphen/underscore boundaries) are rejected to keep malicious clients from passing themselves off as Cometly itself.
Rate limits
POST /mcp/oauth/register is throttled to 10 registrations per hour per IP. Legitimate clients register once per install, so this leaves plenty of headroom for retries while making it impractical to flood the registration table. Exceeded requests return 429 temporarily_unavailable with an RFC 7591 error body.
Authorization flow
This flow is the same whether yourclient_id is an opaque string from DCR or an https URL from CIMD.
-
Generate a PKCE
code_verifierand the matchingcode_challenge(SHA256(verifier), base64url, no padding). -
Redirect the user (in their browser) to:
- The user logs in (if not already), then picks the Space and clicks Approve.
-
Cometly redirects back to your
redirect_uriwith?code={code}&state={state}. -
Exchange the code:
Response:
Calling the MCP server
Once you have an access token, every JSON-RPC call to the MCP endpoint carries it:mcp_space:{id} ability against the route param on every request and returns 403 if they disagree.
Scopes
There’s a single MCP scope today:
When you click Approve in the consent UI, the token’s ability is set to exactly one
mcp_space:{id} value. There’s no broader “all spaces” scope, by design.
Revoking access
You can revoke a connected MCP client at any time:- Open Settings → API Tokens in your Cometly dashboard.
- Find the token whose name matches the MCP client (e.g.
MCP — Claude Desktop). - Click Revoke.
401 Unauthorized and the client will walk the auth flow again on next launch (or you can just remove it from the client’s MCP settings).
Removing a user from a Space also immediately revokes any MCP tokens they have for that Space — there’s no separate cleanup step.