Authentication
Platica's MCP server accepts two Bearer credentials. Both travel in the same header; what changes is who issues them and what authority they carry.
Authorization: Bearer <credential> | Credential | Prefix | Who uses it | Authority |
|---|---|---|---|
| OAuth 2.1 | pl_at_ | Cursor, Claude, VS Code, and any MCP client that speaks the spec | You: the workspaces you authorized and your role's permissions |
| API Key | pl_key_ | Scripts, CI, Postman, and clients without OAuth | The key's workspace, with full access to its modules |
Every MCP tool internally makes the same authenticated call you would make to the corresponding REST endpoint. Rate limits, validation, and errors are identical. There is no separate "MCP mode".
For Cursor, Claude, or VS Code, use OAuth. You don't need to generate or paste an API Key: the client opens Platica sign-in and you pick the workspaces.
OAuth 2.1
This is the method recommended by the MCP authorization spec . Platica is both the resource server (POST /mcp) and the authorization server that issues tokens for it.
How the connection works
Paste the URL — In your MCP client, set
https://api.platica.mx/mcpwithout anAuthorizationheader. See Setup .The client discovers on its own — The first call to
/mcpreturns401with aWWW-Authenticateheader pointing at the discovery documents. The client reads the authorization server, registers itself (Dynamic Client Registration), and opens the browser.Sign in to Platica — Authorize with the same account you use in the dashboard. If you already have a session, you won't type a password again.
Pick workspaces — Choose which ones this connection can reach. The client stores the tokens and refreshes them on its own.
You don't register an OAuth App by hand. The client registers itself the first time; a client_id grants nothing until a person approves the connection.
Scopes
| Scope | What it allows |
|---|---|
platica:read | Reads (GET). The minimum to get in the door. |
platica:write | Creates, updates, and deletes. Without it, those tools return 403 with an insufficient_scope challenge so the client can step up. |
offline_access | Refresh token. The client uses it to renew the access token without asking you to consent again. |
If the client omits scope, Platica grants platica:read and platica:write. Modern MCP clients usually also request offline_access.
Role permissions
Scopes open the door; your role in the workspace decides what's behind it. An operator who connects Claude does not become an admin: if they can't manage integrations in the product, connect_mcp_server returns the same 403.
That lookup is live. If you're removed from a workspace on Monday, the token stops reaching it on the next call — nothing has to be revoked by hand.
An API Key is different: it's a service credential an admin deliberately issued, and it still grants full module access to its workspace for as long as the owner remains a member.
Workspaces
At consent you pick one or more workspaces. The model doesn't know those IDs: the first tool it should call is list_workspaces .
- A single workspace: the other tools infer the ID. You don't need to pass
workspace. - Several workspaces: write tools require
workspace: "<id>". If you omit it, they respond400 Must specify a valid workspace...so the model can correct itself.
The same workspace argument exists in REST as ?workspace=.
Tokens
| Token | Prefix | Lifetime |
|---|---|---|
| Access token | pl_at_ | 1 hour |
| Refresh token | pl_rt_ | 60 days of inactivity; every use extends it |
The client stores and rotates them. Don't copy them into a config or paste them into a header by hand: if the access token expires, the client refreshes it; if you paste a stale one, you get 401.
The access token also works as a Bearer on the REST API (/v1/*). It still carries your role and scopes, not the full access of an API Key.
How access is cut off
- Disconnect the server in the MCP client. Clients that follow the spec call
POST /oauth/revoke. - Leaving a workspace in Platica cuts that workspace on the next request.
- A read-only token cannot write: the client must re-authorize requesting
platica:write.
API Key management (create / revoke) is not exposed as an MCP tool. A model cannot trade an OAuth session for a permanent key.
Discovery, per RFC 9728 and RFC 8414. Clients try both path spellings:
GET https://api.platica.mx/.well-known/oauth-protected-resource
GET https://api.platica.mx/.well-known/oauth-protected-resource/mcp
GET https://api.platica.mx/.well-known/oauth-authorization-server
GET https://api.platica.mx/.well-known/oauth-authorization-server/mcp The canonical resource — the resource value on authorize/token — is https://api.platica.mx/mcp. The bare origin (https://api.platica.mx) is also accepted. Any other audience is rejected.
| Endpoint | Use |
|---|---|
GET /oauth/authorize | Authorization Code + PKCE S256. A response_type other than code is not supported. |
POST /oauth/token | authorization_code and refresh_token. Accepts form-urlencoded or JSON. |
POST /oauth/register | Dynamic Client Registration (RFC 7591). Open: a client_id grants no access. |
POST /oauth/revoke | Revocation (RFC 7009). Answers 200 even if the token does not exist. |
PKCE is required and only S256 is advertised (plain is not offered: OAuth 2.1 forbids it). MCP clients are public (token_endpoint_auth_method: none); if you registered a secret, you must present it.
The 401 from /mcp with no credential carries the challenge that starts the flow:
WWW-Authenticate: Bearer resource_metadata="https://api.platica.mx/.well-known/oauth-protected-resource/mcp", scope="platica:read platica:write" Redirect URIs allowed at registration: https, loopback (http://127.0.0.1, localhost, [::1]), or a private scheme (cursor://…). Public-host http and any URI with a fragment are rejected.
API Key
Still valid. Use it for cron, CI, curl, and any client that doesn't speak OAuth.
API Keys are created from the dashboard, not from the MCP server:
Open settings — In the dashboard, Settings → API Keys.
Create a Key — Give it a descriptive name (e.g.
cursor-personalorci-prod).Copy it — Format
pl_key_KEY_ID_SECRET. It's shown only once.Paste it in the client —
Authorization: Bearer pl_key_...in the config. See Setup .
The API Key does not rotate on its own. If you suspect it leaked, revoke it in the dashboard. Creating or revoking keys is not an MCP tool.
The key covers the workspace it was created in (or the ones assigned to it, if it's multi-workspace) with access to every module. It does not inherit the role of whoever created it.
Multi-workspace
| Credential | How the workspace is chosen |
|---|---|
| OAuth with one workspace | Inferred. Don't pass workspace. |
| OAuth with several | Call list_workspaces and pass workspace on every write tool. |
| Single-workspace API Key | Inferred. |
| Multi-workspace API Key | Same: if you omit workspace on a write, 400 Must specify a valid workspace.... |
list_workspaces also tells you whether the credential is oauth or apiKey, which scopes it has, and which modules your role can reach in each workspace. Call it first when the client has just connected.