MCP scopes and tokens
Issuing scoped MCP tokens and revoking them safely.
Showly MCP tokens are how agents authenticate. This page covers how to issue them, how to scope them tightly, and how to rotate or revoke them when something looks off.
Issuing a token
Workspace settings → MCP clients → New client.
You'll set five fields:
- Client name — Shows up in audit logs. Make it descriptive:
Claude Code (alice@acme)reads better thantoken-3. - Project scope — Optional. When set, the token can only see and mutate sites/deployments in that project.
- Scopes — Pick the minimum needed. Defaults to
project:read,site:read,preview:read. - TTL — How long the token is valid. Default 90 days, max 365.
- Notes — Free-text. Use it to record what the token is for.
The token is shown once on creation. Copy it; we don't store the plaintext.
Scope reference
Scopes are flat strings, not nested tiers. A token carries an explicit list and the API only honors the literal names below. The canonical list lives in [packages/shared/src/mcp-catalog.ts](https://github.com/flot/showly-platform/blob/main/packages/shared/src/mcp-catalog.ts) — this table and the catalog must stay in sync (a catalog-parity test fails the build if they drift).
| Scope | Tier | Allows |
|---|---|---|
project:read | read | list_projects — list and inspect projects this token can access |
site:read | read | list_sites, get_site_context, create_change_plan, list_site_versions, get_site_files — read site state |
site:write | write | apply_site_patch, create_site_from_template — stage edits (never deploys directly) |
site:delete | write | delete_site — two-step cascade soft-delete of a site (admin-tier) |
preview:read | read | get_preview_status — read deployment status |
preview:create | write | create_preview, create_github_preview, delete_preview — materialise / soft-delete a private preview |
checks:run | write | run_checks — read lint/typecheck/build/audit status |
publish:request | write | request_publish — open an approval row for a production publish |
publish:confirm | write | publish_site — two-step confirm-and-publish to production (in-conversation human confirmation; solo/non-approval plans) |
rollback:confirm | write | rollback_to_version — two-step roll production back to a prior version (admin-tier, direct-to-production) |
logs:read | read | get_deployment_logs — tail captured build logs; diagnose_deployment also exposes bounded client/agent diagnostics |
template:read | read | list_templates — list available site templates |
template:create | write | create_site_from_template — materialise a new site from a template |
There is no implication ladder. Granting publish:request does not grant preview:create; pick exactly the scopes a client needs. The Web UI's "MCP token" panel surfaces this list as checkboxes; the same constant powers the role builder for custom RBAC roles.
The legacyrollback_deploymentverb is not MCP-exposed regardless of scopes;publish_siteis MCP-callable only withpublish:confirmand a two-step in-conversation confirmation. See the tool reference for the rationale.
What a tightly-scoped token looks like
For a _content-only_ agent that should never touch infrastructure:
- Allowlist: only the
marketing-sitesite. - Scopes:
site:read,site:write. The agent can stage patches but cannot create previews or publish. - TTL: 30 days.
For a _deploy-bot_ in CI:
- Allowlist: only the production site it's deploying.
- Scopes:
preview:read,preview:create,checks:run,publish:request. Nosite:write— patches come from CI's checked-in workflow, not the bot. - TTL: 14 days, rotated by CI.
For a _template-driven onboarding bot_:
- Allowlist: any project the bot is invited to.
- Scopes:
project:read,template:read,template:create,site:write,preview:read,preview:create. Lets the bot pick a template, create the site, and watch the first preview build. - TTL: 7 days.
Rotation
Two paths:
- Manual — Click Rotate on a client. Old token is revoked instantly; copy the new one and update your shell config.
- Scheduled — Set a rotation cadence in Workspace settings → Token policy. Showly emails the client owner before expiry.
Revocation
Click Revoke to kill a token immediately. Any in-flight tool call using the revoked token gets a 401. The client name remains in audit logs (with a revoked flag) so historical entries still resolve.
If you think a token is compromised, revoke first, investigate second. A compromised token with publish:request scope can open a publish approval, but it still cannot bypass the human approver or the deployment-bound publish confirmation.
Audit visibility
Every tool call writes an audit row containing the client id (not the token). You can:
- Query all calls by a client:
client_id eq <id>. - Query all calls writing a verb:
action eq mcp.request_publish. - Export to your SIEM via the SIEM exporter (Enterprise).
What tokens cannot do
- Cross-tenant reads. The token is bound to one workspace.
- Bypass approvals. A
publish:requestscope grants the _ability to open_ an approval; the approval rules still apply. - Write to billing or RBAC. Those require a human + admin role + browser session.
- Invoke the legacy
rollback_deploymentverb — it is not registered with the MCP server at all. (publish_siterequires thepublish:confirmscope plus an explicit two-step confirmation.)
Direct Free/Pro publishing also uses publish:confirm, which is included in the recommended publishing-agent authorization and still requires the short-lived second-call confirmation. Destructive delete and rollback scopes remain opt-in.