MCP
Permissions and scopes
The capability vocabulary, the consent presets, the project roles that cap every connection, and how the two are intersected on each call.
Reblog answers two questions on every MCP call, independently, and the call proceeds only if both say yes.
| Question | Answered by | Changes when |
|---|---|---|
| What was this app allowed to ask for? | The grant's scopes, chosen on the consent screen. | You revoke the connection or reconnect with a different level. |
| What is this person allowed to do here? | Your role on the target project, re-read live. | Immediately, when your role changes -- no token to revoke. |
The effective capability is the intersection. A connection can never do more than the person who authorized it.
Denied tools are absent, not broken
A tool that fails both gates is not advertised at all: it never appears in tools/list, so an agent is never tempted to try it. That is why "the tool does not exist" usually means "you were not granted it".
Consent presets#
The consent screen offers three shorthand levels plus a custom mode. A preset expands against the live vocabulary every time it is evaluated, so it stays current; a custom grant is frozen at exactly what you ticked.
| Preset | Grants |
|---|---|
| Read-onlyread | articles.readagents.readassets.readaccount.projects.read |
| Read + create/edit articleseditor | articles.readarticles.createarticles.editagents.readagents.runassets.readassets.createaccount.projects.read |
| Full accessfull | articles.readarticles.createarticles.editarticles.deleteagents.readagents.runassets.readassets.createassets.deleteaccount.projects.read |
Sensitive capabilities are never in a preset
Some capabilities can only be granted by an explicit, itemized consent -- not even by "Full access". Automation routines are one today, because a routine publishes on its own and spends credits on a schedule. Billing, project deletion, membership management and integration secrets are reserved the same way, ahead of the features existing, so they can never arrive silently in an old grant.
The scope vocabulary#
Each scope is a capability, not a place. Which projects a connection reaches is a separate choice made at consent time.
| Scope | What it allows | Access | Tools | In presets |
|---|---|---|---|---|
articles.read | View your articles | read | 14 | read, editor, full |
articles.create | Create articles and add ideas to the backlog | write | 2 | editor, full |
articles.edit | Edit articles, and publish, schedule or unpublish them | write | 16 | editor, full |
articles.delete | Delete articles | delete | 1 | full |
agents.read | See your AI agents and their job queue | read | 4 | read, editor, full |
agents.run | Launch agent runs and change how the agents are configured: write articles, translate them, generate images (spends AI credits) | write | 10 | editor, full |
assets.read | See the images and files in your projects | read | 1 | read, editor, full |
assets.create | Add images and files to your projects | write | 1 | editor, full |
assets.delete | Delete images and files, including ones your published articles use | delete | 1 | full |
automation.managesensitive | Manage automation routines: list, run, pause (a routine can publish articles autonomously and spends credits) | write | 3 | custom consent only |
account.projects.read | See which projects and workspaces this app can access | read | 3 | read, editor, full |
Project roles#
Your role on a project is the ceiling. The table shows the most a connection can ever do on a project for each role, no matter what the app was granted.
| Scope | contributor | publisher | editor | advanced editor | administrator |
|---|---|---|---|---|---|
articles.read | yes | yes | yes | yes | yes |
articles.create | yes | yes | yes | yes | yes |
articles.edit | no | no | yes | yes | yes |
articles.delete | no | no | no | yes | yes |
agents.read | no | no | no | yes | yes |
agents.run | no | no | no | yes | yes |
assets.read | no | no | yes | yes | yes |
assets.create | yes | yes | yes | yes | yes |
assets.delete | no | no | no | yes | yes |
automation.manage | no | no | no | yes | yes |
Same rules as the dashboard
Each tool is mapped to the permission the equivalent dashboard action requires, and an unmapped tool falls back to administrator-only. So an MCP connection can do exactly what you could do by clicking, never more.
API keys map onto the same vocabulary#
A project API key has two coarse levels instead of per-capability scopes. They translate as follows, on the single project the key belongs to.
| Level | Name | Equivalent scopes |
|---|---|---|
2 | Read-only | articles.readagents.readassets.readaccount.projects.read |
3 | Read + write | articles.readarticles.createarticles.editarticles.deleteagents.readagents.runassets.readassets.createassets.deleteaccount.projects.read |
Ask the server what you have#
get_my_capabilities returns the resolved answer for the connection making the call: the granted scopes, the reachable projects with your role on each, and which tools that combination actually allows. It is the fastest way to diagnose a refusal.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": { "name": "get_my_capabilities", "arguments": {} }
}Seeing what a connection did#
Settings -> Connected apps shows what each app *may* do. Settings -> MCP activity shows what it *did*: every call with its tool, project, arguments, outcome and duration, including refusals and rejected credentials. Narrow a grant and the next tools/list in the log immediately reports a smaller catalogue -- the permission model is observable, not just documented.