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 registers itself dynamically (RFC 7591).
- 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 want the gritty detail — or you’re building a custom MCP client — keep reading.
Endpoints
Cometly is its own authorization server. There’s no third-party identity provider in the middle.| Endpoint | URL |
|---|---|
| Protected resource metadata (RFC 9728) | https://app.cometly.com/.well-known/oauth-protected-resource/{path} |
| Authorization server metadata (RFC 8414) | https://app.cometly.com/.well-known/oauth-authorization-server/{path} |
| Dynamic client registration | POST https://app.cometly.com/mcp/oauth/register |
| Authorization (browser) | GET https://app.cometly.com/mcp/oauth/authorize |
| Token exchange | POST https://app.cometly.com/mcp/oauth/token |
| MCP server (resource) | https://app.cometly.com/mcp/{space_id}/public-api |
.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.
Dynamic client registration
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.
| Category | Examples | Use case |
|---|---|---|
| Loopback | http://127.0.0.1:33333/callback, http://localhost/cb | Native desktop clients |
https:// to an allowed host | https://claude.ai/api/mcp/auth_callback | Hosted web clients — see Default allowed https hosts below |
| Well-known custom scheme | cursor://..., vscode://..., claude-desktop://..., com.example.app:/oauth2redirect | Desktop and native apps |
Default allowed https hosts
The following hosts are accepted out of the box. If you need a host that isn’t listed, contact support: support@cometly.com.| Host(s) | Client |
|---|---|
claude.ai, claude.com | Anthropic Claude (web, desktop, mobile) |
chatgpt.com, chat.openai.com | OpenAI ChatGPT |
cursor.com, www.cursor.com | Cursor web agents |
vscode.dev, insiders.vscode.dev | VS Code for the Web / github.dev (desktop VS Code uses loopback + vscode://) |
grok.com | xAI Grok |
gemini.google.com | Google Gemini |
perplexity.ai, www.perplexity.ai | Perplexity |
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
-
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:| Scope | What it grants |
|---|---|
mcp_space:{id} | Call any read-only tool against Space {id}. The Space ID is bound into the scope string — a token approved for Space 42 cannot read Space 43. |
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.
Common errors
| Status | Meaning | Recovery |
|---|---|---|
401 | No / invalid / expired token. | Walk the OAuth flow again. The WWW-Authenticate header includes the discovery URL. |
403 | Token’s mcp_space:{id} doesn’t match the URL’s Space ID, or the user no longer has API permission in that Space. | Re-authorize with the correct Space. |
403 (subscription) | The Space’s team doesn’t have an active Public API subscription. | Reach out to your Cometly admin or contact sales. |
429 | Rate limit exceeded. | Back off. See Rate Limits & Errors. |