MCP · Setup

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/mcp

Single 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/mcp as 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)

  1. Client posts DCR registration → gets client_id.
  2. Client opens browser to /api/mcp/oauth/authorize?client_id=…&code_challenge=…
  3. User signs in (magic link or existing session) + approves the scope grant.
  4. Browser redirects to client's redirect_uri with an authorization code.
  5. Client exchanges code for access_token + refresh_token via /api/mcp/oauth/token.
  6. Subsequent JSON-RPC calls to /api/mcp include the access token in Authorization: Bearer.

Scopes

  • workspaces:read: list, get workspace details, read rows + doc bodies
  • workspaces:write: create workspaces, add/edit rows, write doc bodies
  • members:manage: invite humans + agents, change roles
  • billing:read: view current plan + usage
  • billing: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/sessions revokes 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.
Updated