The token is the user. There are no API scopes and no second access list, and every tool call checks the acting user’s Statamic permissions. To restrict an agent, give it its own user and role. You manage it all in the Control Panel’s roles UI, and the only MCP-specific permission is Access MCP.
Try a role#
Pick a recipe, or tick permissions yourself. Click a tool to see the exact answer it gives. The rules behind this were checked against the real server, using a sample site with a blog collection, tags taxonomy, settings global set, main navigation, images container, and contact form.
How authorization works#
Every request is authenticated as a real Statamic user. Then four gates apply.
- Read-only switch.
read_onlyhides all write and delete tools, and a client that still has the old tool list getsTool [x] not found.Handlers also check the switch themselves.entries_previewstays, because a preview link changes no content. - Exposure allowlist.
resourcesdecides what exists as far as MCP is concerned. A handle that exists but isn’t exposed reads as not found, on purpose. Stored values stay: a raw read returns an entry id, term slug, or asset path outside it,navigations_getreturns a linked entry’s id and any title set on the branch, and opening that id answers not found.entries,terms, andlinkfields don’t check it, so writes can store a value outside it. - Statamic permissions on every call. The user’s roles decide, using the same permissions the Control Panel checks. Denials name the missing permission and the remedy.
- Deletes off by default. The delete tools aren’t registered unless you opt in.
Both a config switch and a role can block a tool. The delete tools need both to open: deletes on, and the matching delete permission.
Which permission each tool needs#
| Tool | Permission |
|---|---|
entries_list, entries_get | view {collection} entries |
entries_create | create {collection} entries |
entries_update, entries_preview | edit {collection} entries |
entries_update with parent | reorder {collection} entries, next to edit |
entries_localize | edit {collection} entries for the origin, plus access {site} site for the target |
entries_publish, entries_unpublish | publish {collection} entries |
entries_delete | delete {collection} entries |
terms_list, terms_get | view {taxonomy} terms |
terms_create, terms_update, terms_delete | create, edit, or delete {taxonomy} terms |
globals_get, globals_update | edit {global} globals |
navigations_get | view {nav} nav |
navigations_update | edit {nav} nav |
assets_list, assets_get | view {container} assets |
assets_upload | upload {container} assets |
assets_update | edit {container} assets |
assets_delete | delete {container} assets |
submissions_list, submissions_get | view {form} form submissions, or configure forms |
submissions_delete | delete {form} form submissions, or configure forms |
blueprints_get | Follows the resource: view entries, view terms, edit globals, view nav, or view submissions |
statamic_overview | None beyond Access MCP. It lists the resources the user may view, and every site, with can_access marking the ones they may use. |
Statamic 6 has no view permission for globals, so edit {global} globals is the only gate on them. On multi-site installs, most tools also need access {site} site. Multi-site has the exact list.
A denial is an HTTP 200 with isError: true, written for the agent to act on.
requires 'publish blog entries' — grant it to a role of [email protected] in the Control Panel The author rule#
When a collection’s blueprint has an author field, Statamic’s author rules apply, as they do in the Control Panel. An entry with no author counts as someone else’s.
| Action on someone else’s entry | Permission |
|---|---|
| Edit, preview, or move | edit other authors {collection} entries |
| Publish or unpublish | publish other authors {collection} entries |
| Delete | delete other authors {collection} entries |
entries_create makes the acting user the author unless data names one. Naming anyone else, and changing an entry’s author with entries_update, needs edit other authors {collection} entries.
statamic_overview reports the other-authors permissions per collection, as can_edit_other_authors, can_publish_other_authors, and can_delete_other_authors, plus the acting user’s id, so an agent can tell which entries are its own.
Recipes#
A drafting agent#
No publishing, no deleting.
- In the Control Panel, go to Users → Roles and create a role
content-agentwith Access MCP, View blog entries, Edit blog entries, and Create blog entries. - Create the user
[email protected]with that role. - Issue its token.
php please mcp:token [email protected] --name="Blog agent" Entries this agent creates are drafts. It can’t publish, delete, or even see other collections in statamic_overview. It can preview its drafts, because previews need only the edit permission.
Its edits to entries that are already live depend on the collection. With revisions enabled, an edit becomes a working copy and the live entry stays unchanged until someone publishes it. Without revisions, the edit saves straight to the live entry.
If the blog blueprint has an author field, this agent can only edit and preview entries it’s an author of, which includes every entry it creates. Add Edit other authors blog entries to let it edit and preview everyone’s.
A read-only analyst#
Either set 'read_only' => true server-wide, or give the agent’s role only Access MCP and View entries permissions. Use the role when other agents on the same server still need write access. With read_only on, a role that keeps edit permissions can still create preview links. View permissions alone rule that out.
A publishing agent#
Add Publish blog entries to the role. entries_publish and entries_unpublish now work, on revision-enabled collections too, where they promote or apply the working copy the way the Control Panel does. With an author field, that covers the agent’s own entries. Add Publish other authors blog entries for everyone else’s.
A menu agent#
Add View Main navigation and the Edit navigation permission under it to the role. navigations_update can then replace the Main navigation’s tree. The tools check these per-navigation permissions and ignore Configure Navigation. The Control Panel treats that one as access to every navigation and hides the per-navigation checkboxes while it’s ticked, so untick it to grant them.
An agent that restructures pages#
Add Reorder entries under View pages entries to the role, next to Edit entries. entries_update can then move pages with parent. A move is live at once, even on revision-enabled collections, so leave Reorder entries off the role of an agent whose changes must wait for a person.
Creating a page under a parent needs only Create entries, as in the Control Panel. If the pages blueprint has an author field, the agent can only move pages it’s an author of. Reorder entries covers the whole collection, so add Edit other authors pages entries to let it move everyone’s.
A cleanup agent that may delete#
Set 'deletes' => true in the config and add Delete blog entries to the role. Both gates must open. With an author field, deleting other people’s entries also needs Delete other authors blog entries.
Multi-site agents#
Multi-site has recipes for scoping an agent to one site and for translation.
Three switches for every user at once#
| Config key | Effect |
|---|---|
read_only | Hides all write and delete tools. |
resources | Limits which collections, taxonomies, global sets, asset containers, navigations, and forms MCP can reach. |
deletes | The delete tools don’t exist until this is true. |
Configuration has a builder for all three.