Permissions and API keys
API keys are personal access tokens. Create them at Admin → API Keys (/settings/keys). The value starts with cbpat_ and is shown once. Store it outside the repo.
Issuing a token
When you create a token you set:
- a name
- one or more permission sets
- extra scopes, as individual checkboxes
- a TTL: 1 hour, 24 hours, 7 days (the form default), 30 days, or forever
Effective scopes are the union of the active sets plus the extras. That union is what the MCP server checks. You can replace set membership or edit the extras later. Revoke is immediate for new calls.
OAuth sessions do not use this token string. They use the signed-in user's effective scopes (database floor plus per-user grants). If that lookup fails, the server falls back to a read-only floor. Some writes, including files:write, schedules:write, and workflows:write, are token-only.
Permission sets
Admin → Perm Sets edits named bundles of scopes. Seeded slugs are mcp-readonly, cockpit-ops, and crm-read. You can change them after install. The scope catalog is pat_scopes. A retired scope stays in the catalog so old tokens can be understood, and it is not offered for new grants.
Attaching a set directly to a user (as opposed to a token) is gated by app_settings.feature.permission_sets_users. The default is off. Token scopes are the enforcement path to rely on.
Scope catalog
A tool runs only when the token's scopes are a superset of required_scopes in the MCP manifest. Dynamic tools check the table at call time (contacts:read versus deals:read, for example).
| Area | Scopes |
|---|---|
| CRM | accounts:read accounts:write contacts:read contacts:write deals:read deals:write campaigns:read campaigns:write projects:read projects:write |
| Activity | activities:read activities:write mentions:read mentions:write |
| Approvals and notes | approvals:read approvals:write notes:read notes:write |
| Search | rag:read |
| Tasks | tasks:read tasks:write tasks:reassign |
| Cockpit shell | cockpit:read cockpit:write comments:read comments:write |
| Work and dispatch | work:read work:write schedules:write workflows:read workflows:write graph:write |
| Files and products | files:read files:write products:read products:write |
| Goals and ICP | charters:read charters:write metrics:read icp:read icp:write |
| Cases and outcomes | cases:read cases:write engagement_outcomes:read engagement_outcomes:write |
| Agents | agent_bus:read agent_bus:write skills:read skills:write |
| Other catalog entries | analysis:write capture:write decision:write decisions:read decisions:write voice:read voice:write marketing:analytics:read marketing:ig:read marketing:tiktok:read marketing:x:read |
leads:read and leads:write are retired. Some catalog scopes have no tool on this MCP server. Holding the scope does not create a tool.
Tools with an empty required_scopes list (entity_get, entity_state_get) still require a valid token. Empty means no extra scope string, not anonymous access.
Who can approve
| Actor | Can approve |
|---|---|
| Person in Cockpit (workspace owner or admin session) | Any pending card, including human-only types |
Agent token with approvals:write | Types that are not human-only. approval_resolve stamps the actor as agent and refuses the human-only list |
Human-only types: graph_entity_merge, graph_entity_rename, graph_entity_create, graph_entity_alias, merge_proposal, stage2_identity, product_create, product_rename, engagement_outcome_achieve, workflow_cross_desk_grant.
is_admin() is user_profiles.is_admin. It is an additional database flag, used for policy checks such as extraction thresholds. It is not implied by a token scope.
Workspace membership
Member administration is not an MCP scope. It is a Cockpit session of a workspace owner or admin. See Users and members.