Authentication
Waydock's MCP server accepts two credentials: OAuth 2.1 access tokens, for MCP clients that support one-click connect, and per-user bearer API keys, for scripts and self-hosted automation. Both are checked at the same endpoint and carry the same scope catalog, and every call is audited either way. New here? Start with the Quickstart.
For agents: the machine-readable version of this page is /auth.md. To connect over OAuth, fetch
/.well-known/oauth-protected-resource(an unauthenticated call to the MCP endpoint returns it in theWWW-Authenticatechallenge) and follow the flow. To use a key instead, sendAuthorization: Bearer wdmcp_...on every request tohttps://waydock.ai/api/mcp/stream.
Connecting over OAuth 2.1
Waydock runs its own authorization server for MCP, so a client can connect without the user ever handling a secret. Authorization code flow with PKCE (S256 required), public clients supported, and dynamic client registration is open, which is what makes one-click connect work in Claude, ChatGPT, VS Code, and Cursor.
The flow, in order:
- Register.
POST /api/oauth/register(RFC 7591) with your client metadata, and get aclient_idback. - Authorize. Send the user to
/oauth/authorize. They see a consent screen naming your client and the exact permissions asked for, with anything that can reach another person spelled out on its own line. Consent is not all-or-nothing: each row is a checkbox, and the user grants only what they leave ticked. Scopes that can reach a third party (write:mail.send,write:teams.send) start unticked and are never granted implicitly, the same bar thefull-accessAPI-key preset applies. On approval you get a single-use code, valid for two minutes. - Exchange.
POST /api/oauth/tokenwith the code and your PKCE verifier. The token response'sscopefield is authoritative: read it, because the user may have granted less than you asked for. Access tokens (wdat_) last one hour; refresh tokens (wdrt_) last 30 days and rotate on every use. - Call. Send
Authorization: Bearer wdat_...to the MCP endpoint, refreshing before the hour is up.
Do not paste a wdat_ token into a config file. An Authorization header written into an mcpServers entry is not an OAuth client: nothing there refreshes, so the connection dies within the hour. If your client cannot store and refresh tokens, and its config holds only static headers, use an API key instead. It is long-lived, revocable, and carries the same scopes.
Tokens are audience-bound to https://waydock.ai/api/mcp/stream, so a token minted for Waydock's MCP server cannot be replayed at another resource.
Either side can end the connection. A client calls POST /api/oauth/revoke (RFC 7009), which kills the whole grant rather than the single token presented. The user sees every connected app under Settings → Account → MCP, with the scopes it holds and a one-click revoke.
The rest of this page covers the API-key path.
The key
A Waydock MCP key looks like this:
wdmcp_a1b2c3d4_9f8e7d6c5b4a39281706f5e4d3c2b1a0
The wdmcp_ prefix, a short public segment, and a long random secret. The key is shown once at creation. Waydock stores only a SHA-256 hash of it, never the key itself, and verifies with a constant-time comparison.
Issuing a key
- Sign in and open Settings → Account → MCP (/settings/account/mcp).
- Click Create key and choose a scope preset (Read & message myself or Full access) or a custom scope set. See Scopes & presets.
- Name the key after the agent that will use it (for example
claude-desktop,cursor,nightly-brief-bot). The name appears in your audit log next to every call. - Copy the key. It is not shown again.
You can hold up to 3 live keys on Free and 5 on Pro. New keys are read-only by default.
Sending the key
Pass the key as a bearer token on every MCP request:
Authorization: Bearer wdmcp_xxxxxxxx
The X-API-Key: wdmcp_xxxxxxxx header is also accepted. Keys created before a past rename may start with the legacy ddmcp_ prefix; those still authenticate.
Optional restrictions per key
Each key can be locked down further, all enforced at authentication time:
- Expiry. Set an expiry date; the key stops authenticating the moment it passes.
- IP allowlist. Restrict a key to one or more CIDR ranges. A call from an address outside the list is rejected before any tool runs.
- Tool denylist. Block specific tools for a key regardless of its scopes. Useful to hand an agent broad read scopes but withhold, say,
waydock_send_email.
Lifecycle
- Rotate. Generate a fresh secret for an existing key without changing its id or scopes. The old secret stops working immediately, and the new one is shown once. Use this if a key may have leaked.
- Revoke. Delete a key instantly. Because the app UI and the MCP endpoint read the same key record, revoking stops both in the same moment.
- History. Every key keeps a change log (create, update, rotate, revoke, re-consent), and every call is written to the audit log with the agent name, tool, outcome, and latency.
Re-consent when scopes are added
Each key is stamped with the scope catalog version it was created under. When Waydock adds new optional scopes to the catalog, an existing key does not silently gain them. The key is flagged as pending re-consent, and the owner explicitly acknowledges the new version to pick up any new scopes they want. Existing grants are never changed without the owner's action.
Rate limits and idempotency
- Daily call ceiling follows the plan: 500 per day on Free, 25,000 on Pro, plus a per-IP window. Call
waydock_quota(no scope required) for your remaining budget. - Idempotency. Send an
Idempotency-Keyheader (orX-Idempotency-Key) on a write request and Waydock returns the cached response for a repeat of the same key, so a retried send does not fire twice.
Discovery endpoints
| Endpoint | Auth | Purpose |
|---|---|---|
GET /.well-known/mcp/server-card.json | public | Server discovery card |
GET /.well-known/oauth-protected-resource | public | Protected resource metadata (RFC 9728) |
GET /.well-known/oauth-authorization-server | public | Authorization server metadata (RFC 8414) |
GET /api/mcp/manifest | public | Full tool + scope catalog |
GET /auth.md | public | This authentication guide, as Markdown |
GET /api/mcp/health | key | Liveness |
GET /api/mcp/whoami · /me · /limits | key | Identity, key details, budget |
Security properties
- Keys are stored as a SHA-256 hash, never in plaintext, and compared in constant time.
- Outbound send is wildcard-proof: a key cannot send to third parties unless its scope list contains the literal
write:mail.send. No preset or wildcard satisfies it. - Every call is scope-checked and, for paid write scopes, entitlement-checked at call time.
- All access is logged to one audit trail shared by the app and the agent endpoint.
See also
- Quickstart for client configs
- Tool reference for tools, scopes, and presets
- Security for the outbound-safety contract