Nenjo Docs
API

Scopes

Complete reference for Nenjo's scope system covering API keys, platform scopes, and mode escalation.

Scopes

Scopes control what actions an API key, agent role, or mode session can perform. They apply consistently across the MCP server, worker execution, and mode system.

Scope Format

Scopes follow the pattern resource:permission:

projects:read
projects:write
agents:read

Each MCP resource family has a :read and :write scope.

Scopes stay coarse even when the MCP API exposes subresources. For example, agent prompt and agent MCP assignment operations still use agents:read and agents:write, not agents:prompt:read.

Complete Scope Reference

ScopeDescription
agents:readRead agents and agent subresources like prompt, scopes, abilities, context blocks, and MCP assignments
agents:writeModify agents and agent subresources
projects:readRead projects plus project-scoped tasks, documents, executions, and graph queries
projects:writeModify projects plus project-scoped tasks, documents, and executions
routines:readRead routines plus steps, edges, and councils
routines:writeModify routines plus steps, edges, and councils
mcp_servers:readRead MCP server configurations
mcp_servers:writeModify MCP server configurations
chat:readRead chat sessions and messages
chat:writeSend chat notifications and other write-side chat actions
models:readRead model configurations
models:writeModify model configurations

Total: 12 scopes across 6 resource groups.

Scope Rules

Write Implies Read

A :write scope automatically grants the corresponding :read scope for the same resource. If a key has projects:write, it can also perform projects:read operations without explicitly listing both.

Empty Scopes = Full Access

An API key or role with an empty scopes array has unrestricted access to all resources. This is the default when creating a key without specifying scopes.

Scope Checking Logic

The scope check follows this logic:

  1. If the scopes array is empty, access is granted (full access).
  2. If the exact scope is present, access is granted.
  3. If the requested scope is :read and the corresponding :write scope is present, access is granted.
  4. Otherwise, access is denied.

Where Scopes Apply

Scopes are used in three contexts with consistent behavior:

API Key Scopes

When you create an API key, the scopes field restricts which MCP tools are accessible. The tools/list response only includes tools whose scope is satisfied by the key's scopes.

{
  "name": "Read-only Key",
  "scopes": ["projects:read", "routines:read", "models:read"]
}

This key can see the projects, routines, and models MCP tools, but not their write operations.

Subresources Do Not Add New Scope Names

Nenjo's MCP API may require an explicit subresource for some calls, especially under agents, but the scope check still happens at the top-level resource.

Examples:

  • reading an agent prompt uses resource = "agents", subresource = "prompt", action = "get", and still requires agents:read
  • assigning an MCP server to an agent uses resource = "agents", subresource = "mcp", action = "assign", and still requires agents:write

Platform Scopes (Agent Roles)

Each agent role has a platform_scopes field (TEXT[] in the database) that controls which MCP tools the worker makes available when building the agent's tool set. These scopes are checked at agent build time and work identically to API key scopes.

Platform scopes are configured per role and are seeded with sensible defaults for system roles.

Mode Additional Scopes

Modes can temporarily escalate an agent's platform scopes for the duration of a mode session through the additional_scopes field in the mode's ModeToolConfig:

{
  "additional_scopes": ["projects:write", "agents:write"]
}

When a mode session is active, the worker merges these additional scopes with the role's base platform_scopes before filtering MCP tools. This allows modes like /the-creator to grant write access that the role does not normally have.

Worker Filtering

For Nenjo's built-in MCP tools, the worker relies primarily on server-side filtering via tools/list(agent_scopes=...). Those tools do not need per-tool scope strings because the backend enforces access dynamically from the MCP request arguments.

Legacy or external tools may still include explicit per-tool scopes, and the worker can use those when present.

Examples

Minimal read-only key

curl -X POST \
  -H "Authorization: Bearer <clerk-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dashboard Reader",
    "scopes": ["projects:read", "routines:read", "models:read"]
  }' \
  https://your-instance/api/v1/api-keys

Full-access key (no scopes)

curl -X POST \
  -H "Authorization: Bearer <clerk-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Worker Full Access"
  }' \
  https://your-instance/api/v1/api-keys

Write-only for a specific resource

curl -X POST \
  -H "Authorization: Bearer <clerk-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Project Manager",
    "scopes": ["projects:write"]
  }' \
  https://your-instance/api/v1/api-keys

This key can read and write the projects MCP family (:write implies :read) but has no access to any other resource family.

On this page