Feedjoltdocs
DevelopersMCP

MCP Permissions

The three MCP scopes - read, write, delete - what each covers for OAuth grants and API keys, how keys created before scopes existed are grandfathered, and how to grant or change scopes.

Three scopes

OAuth grants and fjk_ API keys use the same three scopes. You pick them at consent (OAuth) or when you create/edit a key. Every MCP tool is tagged with exactly one:

ScopeCovers
readEvery list_*, get_*, and search_* tool.
writeCreate, update, move, assign, reorder, and publish.
deleteEvery irreversible removal.

delete is split out from write because it's the only class of tool that destroys data. Scopes don't stack into tiers: delete doesn't imply write, and write doesn't imply read. A key needs each scope it uses, explicitly.

Calling a tool without the scope it requires fails before any lookup or mutation runs, with an error naming what's missing and what the principal is allowed to do. See Troubleshooting for the exact message.

Choosing and changing scopes

OAuth. Pick scopes on the consent screen. read and write start checked; delete starts unchecked. A contributor cannot grant delete. To change the grant, revoke the app under Dashboard -> Developers -> MCP -> Connected apps and approve again.

API keys. Pick scopes when you create a key at Dashboard -> Developers -> API keys. You can edit a key's scopes any time from the same page - the change applies immediately, no need to reissue the key.

Default to read-only for anything that just looks things up. Add write for triage and content-creation agents. Add delete only for principals you trust to remove things permanently - most workflows never need it.

Keys created before scopes existed

The MCP server shipped before per-key scopes did. Any key created before that has no scopes stored on it, and is grandfathered to read + write, no delete - the tools it could already call keep working, and nothing gains the ability to permanently destroy data it couldn't touch before. Grandfathering never includes delete; grant it explicitly if a legacy key needs it.

On this page