DocSpace Docs

Scopes and roles

Every MCP tool call made with an agent key passes one check before the tool runs:

scope ∧ role: the key must hold the tool's scope, and the key's role must be at least the scope's minimum role.

Both halves are needed. A key with pages:write but the Viewer role cannot create pages; a key with the Editor role but only read scopes cannot either. The check is the same on every tool, and a tool that is missing from the scope map is denied for every key (fail closed).

Agent keys

Scopes

Scope Minimum role Custom-role permission Tools
pages:read viewer CONTENT_READ get_context, search, get_mentions, list_pages, get_page, get_backlinks, get_graph
pages:write editor CONTENT_WRITE create_page, append_block
boards:read viewer BOARDS_READ list_boards, get_board
boards:write editor BOARDS_WRITE create_board, add_row, set_cell, create_automation
catalog:read viewer BOARDS_READ list_services, get_service, get_ownership_graph
catalog:write editor BOARDS_WRITE create_service, update_service
scorecards:read viewer BOARDS_READ list_scorecards, get_scorecard
planner:read viewer BOARDS_READ list_work_items, get_work_item, get_item_git_refs, list_sprints
planner:write editor BOARDS_WRITE create_work_item, update_work_item, start_sprint, close_sprint
sync:write editor CONTENT_WRITE sync_from_github
artifacts:write editor CONTENT_WRITE publish_artifact, update_artifact
scorecards:write editor SCORECARDS_WRITE none yet (reserved)
ask:query viewer ASK_BRAIN none yet (reserved)

The per-tool view of the same data, with each tool's parameters, is the tool reference, which is generated from the server's registry.

Two tools look at more than one scope:

Presets

The key dialog offers two presets:

Preset Scopes Allowed roles
Read only every scope whose minimum role is viewer (pages:read, boards:read, catalog:read, scorecards:read, planner:read, ask:query) Viewer, Commenter, Editor
Full write every scope Editor only

Roles

System roles are ordered guest < viewer < commenter < editor < admin < owner. A key's role must be at least the minimum role of the scope. With a custom role, the role must include the custom-role permission listed for the scope instead.

Page-level rules still apply on top: on a page whose access list gives the creator less than Editor, append_block answers page.forbidden even for an Editor key.

Rate limits

Limit Applies to Window Over the limit
120 tool calls per key every tools/call over HTTP (a batch counts each call) 60 s HTTP 429, Retry-After: 60, mcp.rate_limited; the calls do not run
20 writes per key and space create_service, update_service, create_work_item, update_work_item, start_sprint, close_sprint, sync_from_github 60 s the tool returns { "error": "Rate limited: …" }
10 uploads per user publish_artifact, update_artifact (shared with the REST upload route) 60 s artifact.rate_limited

Counters are kept in memory per server process. Treat the numbers as upper bounds, not as a budget to spend.

Security FAQ

What is logged when an agent calls a tool? Every call made with an agent key writes exactly one audit row and one security (SIEM) event: the key, the tool, the scope, the result (ok, denied or error), the error code if any, the latency, the target id (for example page:12) and a redacted summary of the arguments. The summary keeps ids, enum values and the shape of other arguments (type and length), never free text, page content or secrets. Space administrators see this in Agents and keys → Activity.

Is the agent key logged? No. The key travels in the Authorization header, is compared against a stored hash in constant time, and is never written to logs, audit rows or error messages.

What can an agent never do?

Does the agent see encrypted spaces? Yes, in clear text, exactly like a member using the app with the same role: decryption happens on the server. Spaces with the strict protection level do not support term counting (get_mentions answers mentions.unavailable_encrypted).

Does anything reach the internet? Only sync_from_github, which fetches a file from GitHub (it is annotated openWorldHint: true). Every other tool only touches your space.

How do I cut an agent off? Revoke its key in Agents and keys. The next request with that key gets 401 mcp.unauthorized.