OAuth + DCR
Dock's MCP server speaks OAuth 2.1 with Dynamic Client Registration (DCR). MCP-aware clients (Claude Desktop, Claude Code, Cursor, Windsurf, Cline) configure themselves automatically, no API key copy-paste, no manual client-id registration.
Endpoint
https://trydock.ai/api/mcpSingle endpoint, server-sent events for streaming responses, JSON-RPC for requests. MCP clients fetch the OAuth metadata on first connect from the two well-known URLs below.
Discovery URLs
Two metadata documents, one per RFC. Both are public, unauthenticated, edge-cached, CORS-open.
/.well-known/oauth-authorization-server, RFC 8414 authorization-server metadata. Returns the authorization endpoint, token endpoint, registration endpoint, supported scopes, grant types, and PKCE methods./.well-known/oauth-protected-resource, RFC 9728 protected-resource metadata. Names/api/mcpas the resource and points back at the authorization server.
Both endpoints accept any path suffix. ChatGPT's MCP client appends the resource segment when it discovers metadata, so it requests /.well-known/oauth-authorization-server/mcp rather than the spec-compliant root path. A wildcard child route serves the same JSON regardless of suffix, so spec-compliant clients (Claude Desktop, Cursor, Windsurf, Cline) and ChatGPT both work.
Dynamic Client Registration
Per RFC 7591. On first connect, the client POSTs to the registration endpoint with its name + redirect URIs + grant types. The server returns a client_id + client_secret. The client stores these and uses them for the OAuth flow.
For Dock, every registration is automatic, no manual approval. Each registration is bound to your user account, visible at /settings/connected-clients. Revoke any client there to immediately invalidate its tokens.
Auth flow (PKCE)
- Client posts DCR registration → gets client_id.
- Client opens browser to
/api/mcp/oauth/authorize?client_id=…&code_challenge=… - User signs in (magic link or existing session) + approves the scope grant.
- Browser redirects to client's redirect_uri with an authorization code.
- Client exchanges code for access_token + refresh_token via
/api/mcp/oauth/token. - Subsequent JSON-RPC calls to
/api/mcpinclude the access token inAuthorization: Bearer.
Scopes
workspaces:read: list, get workspace details, read rows + doc bodiesworkspaces:write: create workspaces, add/edit rows, write doc bodiesmembers:manage: invite humans + agents, change rolesbilling:read: view current plan + usagebilling:write: upgrade/downgrade/request limit increase (gated by dangerous-ops handshake)
Refresh tokens
Access tokens expire in 1 hour. Refresh tokens are valid for 30 days; using one rotates it (sliding expiry). If a refresh token is older than 30 days unused, the user must re-authorize via the browser.
Revoking access
- User-side: visit /settings/connected-clients, click revoke on the client. Effective within 60 seconds.
- Programmatic:
DELETE /api/mcp/oauth/clients/:id. - Mass-revoke (compromise scenario):
DELETE /api/me/sessionsrevokes everything in the same call (all OAuth tokens, all DCR clients, all browser sessions).
Frequently asked questions
- Does Dock support OAuth 2.1 with Dynamic Client Registration?
- Yes. Discovery at `/.well-known/oauth-authorization-server`, registration at `/api/oauth/register`, authorization at `/api/oauth/authorize`, token at `/api/oauth/token`. Spec-compliant clients (Claude Desktop, Claude Code, ChatGPT, Cursor) auto-register without manual setup.
- Where do I find Dock's OAuth discovery endpoints?
- Two of them: `https://trydock.ai/.well-known/oauth-authorization-server` (RFC 8414, returns auth endpoint, token endpoint, registration endpoint, supported scopes, grant types, PKCE methods) and `https://trydock.ai/.well-known/oauth-protected-resource` (RFC 9728, names `/api/mcp` as the resource). MCP clients hit both automatically; you only need them for custom integrations.
- Why does my MCP client request `/.well-known/oauth-authorization-server/mcp`?
- ChatGPT's MCP client appends the resource path segment to the well-known URL when it discovers OAuth metadata. The spec-compliant URL is the root path, but ChatGPT requests the suffixed one. Dock serves the same JSON at both, a wildcard child route catches the suffix and returns identical metadata. Spec-compliant clients (Claude Desktop, Cursor, Windsurf, Cline) and ChatGPT both work.
- Does Dock's OAuth flow require PKCE?
- Yes. Per OAuth 2.1, all clients (including confidential clients) must use PKCE with S256. The `code_challenge` and `code_verifier` flow is enforced server-side; clients that omit them get rejected at the authorize step.
- What scopes does Dock's OAuth server support?
- `mcp` is the single scope today (covers all MCP tool calls under the user's accessible workspaces). Per-tool scopes are on the roadmap. The user's role on each workspace is the existing access gate; OAuth doesn't add a separate scope grid.
- How does Dock's Dynamic Client Registration work?
- Clients POST to `/api/oauth/register` with their client metadata (name, redirect_uris). Dock returns a `client_id` immediately (no admin approval). The client uses that `client_id` for the rest of the OAuth flow. Reduces friction; no manual app-registration step.
- How do I refresh an expired Dock OAuth access token?
- POST to `/api/oauth/token` with `grant_type=refresh_token` and the `refresh_token` you got at the original token grant. Returns a new `access_token` (and a new `refresh_token` if rotating). Standard OAuth 2.1 refresh flow.
- Can I revoke a Dock OAuth access token?
- Yes. POST to `/api/oauth/revoke` with the token. The token's `tokensRevokedAt` field is set; subsequent requests with it return 401. The user can also revoke from Settings → Authorized apps in the dashboard, which revokes every token + the client registration. Revocation cascades: when an OAuth token is revoked, the OAuth-promoted Agent it produced (via the /oauth/token auto-promote step) is archived and its WorkspaceMember access removed in the same transaction. Explicit `dk_` API keys are NOT touched by OAuth revoke — those are revoked separately via `DELETE /api/keys/<id>`, so revoking an OAuth client doesn't kick an unrelated long-running agent.
- How long do Dock OAuth tokens live?
- Access tokens: 1 hour. Refresh tokens: 90 days, rotated on each refresh. Authorization codes: 60 seconds. Conservative defaults that match typical MCP-client expectations and minimize blast radius if a token leaks.
- Does Dock OAuth support PKCE-only public clients?
- Yes. Public clients (no client_secret) are first-class. PKCE is the security substitute. Useful for desktop apps and CLI tools that can't safely store a client_secret. Confidential clients (with secret) are also supported for server-side integrations.
- How do I debug a Dock OAuth flow that's failing?
- Check the `error` + `error_description` query params on the redirect back to your client. Common: invalid_redirect_uri (mismatch with what you registered), invalid_grant (code expired or already used), invalid_scope (Dock only supports `mcp` today). The discovery endpoint is the canonical source of supported values.
Related
- MCP overview: what MCP is + why we use it.
- Connecting clients: per-client setup steps.