The developerz.ai MCP server is live at mcp.developerz.ai. Connect it from
Claude Code, Claude Desktop, or any MCP-capable client
using a personal access token from the dashboard.
Trust model
Every MCP call is bound by the same rules as the rest of the platform:
- The bot always discloses. Every action it takes is labelled as automated, it never impersonates a human.
- Thin orchestrator, BYOK. Coding runs in your own agent; inference uses your own provider key. We never proxy or resell tokens.
- Audit-first. Every tool call is written to the append-only audit log. If it isn't logged, it didn't happen.
Connecting
// .claude/settings.json (Claude Code)
{
"mcpServers": {
"developerz": {
"command": "mcp-remote",
"args": ["https://mcp.developerz.ai"],
"env": { "MCP_BEARER_TOKEN": "dev_pat_…" }
}
}
}
Or direct HTTP (JSON-RPC 2.0 over POST /v1/mcp):
curl https://api.developerz.ai/v1/mcp \
-H "Authorization: Bearer dev_pat_…" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","id":1,"params":{"name":"whoami","arguments":{}}}'
Scopes are on the wire, not just on this page
Every row tools/list returns carries its own gate, so a client never has to
read this page or pattern match a description:
{
"name": "box",
"annotations": { "readOnlyHint": false, "destructiveHint": true, "idempotentHint": false },
"_meta": {
"developerz.ai/scopes": {
"kind": "action",
"actions": { "list": "read:runners", "revoke": "write:runners" }
}
}
}
A flat tool publishes {"kind": "tool", "scope": "write:tasks"} instead, with
"scope": null when it gates on nothing. Pair it with whoami, which returns
the scopes your token actually holds, and you can tell before you call which
verbs are open to you and which need a wider token. annotations is the MCP
standard triple: readOnlyHint is claimed only when every one of a tool's
actions is a read.
The tables below are the same information, rendered for humans. They are
generated from the catalog the server enforces, so the two cannot drift.
Flat, hot-path tools available to every authenticated account. No action field.
| Tool |
Scope |
Description |
whoami |
(none) |
Return caller account, MCP tier, granted scopes, and the platform-access rungs behind them (approved | Terms accepted | capped). |
next_steps |
(none) |
WHAT DO I DO NEXT: the ordered preconditions between this credential and a first plan_start, each with the fact observed and where it clears (cleared_by, of which only here names a verb you can call). Optional repo narrows the same ladder to one repository. No scope required. |
repo_ask |
read:repos |
Grounded repo Q&A with citations, refuses rather than guessing when no citable evidence exists. |
kb_search |
read:kb |
Search the repo knowledge base (agent-maintained wiki), page slugs, scores, previews. |
kb_page_get |
read:kb |
Read one KB wiki page verbatim by slug, body, cross-links, provenance. |
kb_page_upsert |
write:kb |
Create or replace one KB wiki page by slug, the post-task write-back so learnings compound. |
task_create |
write:tasks |
Dispatch a scoped task to a sink (linear | gh | direct). Returns {task_id, sink, url} or an escalation. |
task_reassign |
write:tasks |
Self-service unblock: pull one of your OWN in-flight tasks off its box back to pending so the assigner re-claims it elsewhere. Account-scoped, idempotent on a pending/terminal task. The consumer door onto the same impl as the operator task reassign action. |
plan_start |
write:tasks |
Start a scout planning session over a repo: hand it a raw ask and a box authors a plan (groups → tasks). Returns {task_id}. The session run id is minted by the box when it claims the work, so read run_id off that task (task list / GET /v1/tasks/:id, null until it starts) and steer the live scout with message. Refuses no_scout_capacity when the account has no online box able to hold a live session. |
message |
write:sessions |
Send a message to a live interactive run (scout/setup) and await the agent reply. |
help |
(none) |
List available tools, compact and role-filtered. |
Resource tools, one tool name, dispatched by an action field. That collapse is
what keeps the catalog readable: one tools/list entry per resource instead of
one per action. Each entry is complete, its JSON Schema naming every action and
the arguments that action takes, so any MCP client can call any of them straight
from the catalog. There is no second call to make and no extension to install.
Consumer-or-absent. A tool only appears in tools/list when its backing
service is configured. All tools below are available on platform-managed accounts.
Box
| Action |
Scope |
Description |
list |
read:runners |
List fleet boxes. |
get |
read:runners |
Get one box + live presence. |
fleet_status |
read:runners |
Aggregated fleet status (counts + per-box line). |
versions |
read:runners |
Fleet dz-runner build spread, box count per version. |
releases |
read:runners |
Release-ledger rows per build target, what CI published (NOT the installed-build spread versions reports). A tenant sees the INSTALLABLE view: version/channel/target/published_at, the rows box update may pin. An operator holding admin:releases sees the full ledger, including yanked rows, commit_sha and signing-key provenance; the response names which view it answered. |
logs |
read:runners |
The box's own process log: boot, enrolment, self-update, NATS. Excerpt plus a presigned archive url. Unlike task.run_tail it answers for a box with no run. |
add |
write:runners |
Mint a one-time enrollment token. |
enroll_ssh |
write:runners |
Enroll by SSH-pull: we dial the box; no token leaves the platform. |
drain |
write:runners |
Evacuate box; re-enqueue in-flight tasks. Reversible: the box stays enrolled. |
revoke |
write:runners |
KILL a box: free its seat and cascade its tokens dead. Not reversible. |
reissue_creds |
write:runners |
Operator-initiated credential re-issue for a healthy box (#2547). Convenience, not recovery: a locked-out box is systemctl restart dz-runner. |
set_owner |
write:runners |
Retarget a box shared | org | user (the runner-ownership model). |
set_prompt |
write:runners |
Set/clear the box's concise briefing (what this VPS runs, ≤2000 chars). |
update |
write:runners |
Start a staged dz-runner self-update rollout of this account’s fleet (canary → soak → waves; halts + rolls back on failure). |
attest_isolation |
admin:runner:isolation |
Platform-operator attestation that this box runs every coding job in its own container. The ONE thing that widens its claim past a single tenant, so it takes only the box id: no box-reported evidence of its own containment is admissible. |
withdraw_isolation |
admin:runner:isolation |
Retract that attestation. The box is single-tenant again on the assigner's next pass. |
unyank |
admin:releases |
Restore a halted release to its channel’s installable read (channel required, never defaulted). Reports the artifact count cleared, 0 when it was not yanked. |
Project
| Action |
Scope |
Description |
list |
read:repos |
List account repositories with enabled state. |
get |
read:repos |
One repo's full row (policy validity, warnings, last activity). |
add |
write:repos |
Enable an installed (but disabled) repo. |
set_donations_enabled |
write:repos |
Consent to receive donated boxes/keys for a repo. |
create |
write:repos |
One-step create+scaffold of a brand-new gold-standard repo. ORG accounts only, since the App holds no administration: write on a personal one (advertised only when backed). |
setup |
write:tasks |
The advertised path for a NEW repo: you create it on GitHub, project add, then a box scaffolds it. Also re-establishes the base on an existing repo (advertised only when backed). |
policy_get |
read:repos |
Stored .maintainer.yml policy snapshot for one enabled repo. |
policy_validate |
write:repos |
Pure .maintainer.yml check, nothing stored. |
overview |
read:repos |
Activity rollup for one enabled repo (repo-detail tab). |
settings |
read:repos |
Settings view for one enabled repo (repo-detail tab). |
Task
| Action |
Scope |
Description |
list |
read:tasks |
List fleet task queue (supports filters.status, per_page). |
stalls |
read:tasks |
Why is nothing moving: every reason holding a pending task, with a fix for each. |
reassign |
write:tasks |
Pull in-flight task off its box → pending. |
cancel |
write:tasks |
STOP a task: cancelled, and the box holding it is interrupted. Idempotent on a terminal task (kind: "already_terminal"). A PR-review task is REFUSED, because stopping it would release the merge gate's review hold. |
run_status |
read:tasks |
One-row pulse for a task's run. |
run_tail |
read:tasks |
Durable run events after since_seq, capped. Takes EXACTLY ONE address: run_id (from a task list row) or task_id (what plan_start / task_create hand back). Addressed by task it resolves to whichever run a box mints, so it works BEFORE the run exists ({run_id: null, events: [], next_since_seq: null} means re-send the same call, not an error) and picks up a run that starts mid-wait. Add wait_ms (up to 25 000) to WATCH rather than poll: the call is held open until the first new event lands, so one request covers what 25 would. An empty page after a wait is not an error, re-send the same cursor. A run that has already ended settles the wait at once, so an instant empty page means run_status and stop. |
Blocker
| Action |
Scope |
Description |
list |
read:tasks |
Answerable holds a human still owes (open: false for the closed record). |
answer |
write:tasks |
Supply what was missing. Closes the blocker and mints the resumption. Give the LOCATION of a credential, never the credential itself: the answer is stored and copied into the raw task verbatim. |
withdraw |
write:tasks |
Retire an open blocker whose ask went away. |
Plan
| Action |
Scope |
Description |
list |
read:tasks |
The account's plans (epics) newest-first, id, repo, lead-slice title, merged/total. |
get |
read:tasks |
One plan's full projection, the group → task → PR chain (mirrors GET /v1/plans/:planId). |
rollup |
read:tasks |
Per-conversation_ref rollup (#2681): tasks that carried the ref, the plan groups whose task carried it (sibling groups filtered out), open blockers on those task ids, and a deployVerdict field stating unknown when no verdict is recorded (rather than an omitted line). Tenant-isolated: a second account reading the same ref gets null. |
cancel |
write:tasks |
STOP the epic: every non-terminal child cancels and its box is interrupted. Answers three id lists: stopped, already finished, and the PR-review children the merge-gate carve-out refused. |
approve |
write:tasks |
RELEASE a held plan (the one plan_start produced when require_approval: true). Flips every held group back to dispatched and mints its tasks in one transaction. Idempotent on re-approve (the second call reports already_approved). |
Audit
| Action |
Scope |
Description |
tail |
read:sessions |
Recent maintainer-visible audit events, newest-first. |
Session
What the maintainer agent actually did on one repo, and what a different policy
would have done. The live SSE tail stays REST-only because holding a connection
open is not a JSON-RPC shape: events pages the same audit rows behind an opaque
cursor, so an agent polls it until finished is true.
| Action |
Scope |
Description |
list |
read:sessions |
One enabled repo's agent sessions, newest-first, filterable by trigger / entity_kind / outcome. |
get |
read:sessions |
One session header: repo, triggering entity, model, outcome, start and finish. |
events |
read:sessions |
Page one session's audit rows behind an opaque cursor. Poll it, feeding back next_cursor, until finished is true, the live SSE tail stays REST-only. |
replay |
read:sessions |
Re-decide a stored session against a candidate .maintainer.yml and return the decisions DIFF. Executes nothing, stores nothing. |
Template
| Action |
Scope |
Description |
list |
read:runners |
List agent templates. |
get |
read:runners |
Get one agent template by name. |
set |
write:runners |
Create-or-replace (full upsert) an agent template. |
delete |
write:runners |
Delete agent template (idempotent). |
Config
Scoped prompt-var KV, #{{key}} interpolation into agent prompts.
| Action |
Scope |
Description |
get |
read:runners |
Read one prompt var (account | repo | template scope, specific wins). |
set |
write:runners |
Set a prompt var (#{{key}} interpolation). |
delete |
write:runners |
Clear one prompt var (idempotent). |
list |
read:runners |
List prompt vars for a scope. |
onboarding_state |
read:account |
Where this account is in the install funnel + what fires next. |
onboarding_advance |
write:account |
Fire one install-funnel transition you WITNESSED (auth_completed, plan_selected, repos_selected, yml_requested, yml_retried). The four the platform observes about you (key_set, gh_app_installed, yml_validated, yml_invalid) are refused from every state, naming the act that causes each. |
Prompt
The authored prose layers of the system-prompt cascade (platform, then org, repo
and your own). A set replaces that layer; a get on an unauthored one answers
prompt: null. The personal layer belongs to the caller: no action names a user,
and a machine token, which has no human behind it, is refused.
| Action |
Scope |
Description |
org_get |
write:prompts |
Read the org-wide system-prompt layer. |
org_set |
write:prompts |
Set it (replaces the layer). |
org_clear |
write:prompts |
Clear it. |
repo_get |
write:prompts |
Read one repo’s layer (repo uuid). |
repo_set |
write:prompts |
Set it; the repo layer refines the org one. |
repo_clear |
write:prompts |
Clear it. |
self_get |
write:self:prompt |
Read your OWN layer (needs a user-bound credential). |
self_set |
write:self:prompt |
Set it, over your own dispatched work only. |
self_clear |
write:self:prompt |
Clear it. |
User
| Action |
Scope |
Description |
approve |
admin:users |
Approve a waitlisted user for the closed beta (operator PAT only). |
suspend |
admin:users |
Clear approval, return the user to the waitlist (idempotent). |
approve_by_id |
admin:users |
Approve one specific user row by id. The escape hatch when approve refuses a login as ambiguous: users.login is not unique, so a handle can name more than one row and only one of them is the one that signs in. |
suspend_by_id |
admin:users |
Clear approval on one specific user row by id. The suspend half of the ambiguity escape hatch, so a duplicated login can still be revoked. |
invite |
admin:users |
Invite an EMAIL that need not have signed up yet. Mints or re-arms the one live platform invitation for that address, mails it, and returns the accept link ONCE: it is a single-use bearer token, and no later read can show it again. |
invites |
admin:users |
List platform invitations with their derived status (pending, accepted, revoked, expired). Never returns an accept link. |
revoke_invite |
admin:users |
Withdraw one invitation by id. Answers a named reason (unknown, already revoked, already accepted) when it changed nothing. |
Account
| Action |
Scope |
Description |
me |
read:account |
The /v1/me identity view: the scopes this credential holds, user, memberships, active account. |
active_account_switch |
write:account |
Repoint the live user session at a member account. |
platform_overview |
admin:read:platform |
Platform radar rollup (staff read). |
orgs_list |
admin:read:orgs |
All org accounts (staff read). |
users_list |
admin:read:users |
All users (staff read). |
account_detail |
admin:read:orgs |
One org in detail, with its member roster (staff read). |
platform_audit |
admin:read:platform |
The PLATFORM-wide audit tail (staff read). |
oss_queue |
admin:read:orgs |
The OSS-verified review queue (staff read). |
set_tier |
admin:accounts |
Operator override: set an account's tier by id. |
set_seats |
admin:accounts |
Operator override: set an account's seat count. |
set_spend_cap |
admin:accounts |
Operator override: set an account's spend cap. |
oss_verify_decide |
admin:accounts |
Rule on a queued OSS-verified application, approve (also re-tiers the account to oss_verified) or reject with a note. |
keys_list |
write:self:keys |
List YOUR OWN personal BYOK keys, masked (the org pool is billing.keys_list). |
key_add |
write:self:keys |
Add one of YOUR OWN personal BYOK keys, sealed at capture and never echoed. Ranked ahead of the org pool for your own dispatched work. Takes the picked model plus an optional per-model lane tier (fast | general | smart | heavy). |
provider_models |
write:self:keys |
List a provider’s real model ids for a raw key, BEFORE capture, so account key_add picks an id instead of guessing one. Stores nothing: the key is used for one outbound GET and never sealed, echoed or audited. |
key_verify |
write:self:keys |
Verify one of YOUR OWN personal keys against its provider (live probe). An invalid result is data, not an error. |
key_rotate |
write:self:keys |
Swap the material of one of YOUR OWN personal keys. Verify-first, so a refused probe writes nothing and the old key stays live. |
key_delete |
write:self:keys |
Revoke one of YOUR OWN personal keys. |
key_kind_set |
write:self:keys |
Set the billing kind (metered or subscription) of one of YOUR OWN personal keys. The audit trail carries both the previous and the next value. |
llm_pref_get |
write:self:keys |
YOUR model default, or null when unset ("the org key, but this model"). |
llm_pref_set |
write:self:keys |
Set YOUR model default, optionally pinned to one provider. |
llm_pref_clear |
write:self:keys |
Clear YOUR model default. |
accept_tos |
read:account |
Record YOUR consent to the current terms version (needs a user session). |
Grant
Audited entitlement overrides, free capacity on top of what an account pays for,
granted to an account (all four kinds) or to a user (unlimited_fleet /
concurrency only, the two the person-level fleet gates read).
Issuing and revoking are operator-only (admin:grants, a scope no role ceiling
and no self-minted token can hold); the listing rides the platform-staff read
scope, so a radar session can see who holds free capacity without being able to
hand any out. Every grant carries a stated reason and an issuing human, and is
revoked rather than edited, the row parks so the decision stays legible.
| Action |
Scope |
Description |
list |
admin:read:orgs |
A subject's grant history, newest-first. Revoked and expired rows included, each with its resolved active (staff read). |
issue |
admin:grants |
Operator only: give an account or a user free capacity (unlimited_fleet | concurrency | boxes | ci_slots) with a required reason and an optional expiry. |
revoke |
admin:grants |
Operator only: stop a grant. Parks the row (reason and history stay legible); already-stopped is a benign no-op. |
Review
AI code-review runs for a pull request (the PR rows themselves live on
pr).
| Action |
Scope |
Description |
status |
read:prs |
The PR's AI code-review runs, newest-first. |
rerun |
write:prs |
Re-run the latest review on the same commit. |
CI
| Action |
Scope |
Description |
runs |
read:runners |
List self-hosted CI runs newest-first (repo/status/per_page). |
log_url |
read:runners |
Short-lived presigned URL for one CI run's archived log. |
Artifact
| Action |
Scope |
Description |
put |
write:artifacts |
Register an artifact and get a presigned PUT URL (5-min TTL). |
get |
read:artifacts |
Get a presigned download URL for an artifact (1-hour TTL). |
list |
read:artifacts |
List artifacts for the account; filter by task_id, run_id, or repo_id. |
share |
write:artifacts |
Mint a fresh presigned download URL for an existing artifact. |
delete |
write:artifacts |
Delete an artifact immediately (soft-delete for 24 h, then purged). |
Issue
| Action |
Scope |
Description |
list |
read:issues |
One enabled repo's issues newest-first (state/qualification/q/per_page). |
get |
read:issues |
One issue by id. |
handoff |
write:issues |
Force-fire the issue to the coding-agent webhook (queued delivery; reason + optional webhook_ref). |
escalate |
write:issues |
Force-pull a human in (category + reason → escalation row + notification). |
Pull request
| Action |
Scope |
Description |
list |
read:prs |
One enabled repo's PRs newest-first (state/ci_status/per_page). |
approvals |
read:prs |
Account-wide queue of PRs parked on ask-before-acting. |
get |
read:prs |
One PR by id. |
approve_pending |
write:prs |
Approve the PR's outstanding ask-before-acting. |
skip_pending |
write:prs |
Decline the PR's outstanding ask-before-acting. |
Dashboard
| Action |
Scope |
Description |
list |
read:dashboards |
List account-shared boards. |
get |
read:dashboards |
Get a board with all widget specs. |
upsert |
write:dashboards |
Create a named board, a name already in use is refused unless replace: true, which fully replaces that board. A seeded built-in is never replaceable. |
patch |
write:dashboards |
Rename and/or relayout a board WITHOUT touching its widgets (unlike upsert). A layout ref to a widget not on the board is refused. A seeded built-in is read-only. |
widget_page |
read:dashboards |
One page of a widget's data, checked against that widget's declared spec.capabilities. |
delete |
write:dashboards |
Delete a board (idempotent). A seeded built-in is refused. |
Donation
| Action |
Scope |
Description |
create |
write:donations |
Donate money | compute | llm, earmarks the resource oss-only. Optional models on an llm gift = the ceiling the recipient picks within. Refused without an active oss_donor subscription. |
list |
read:donations |
List the account's donations. |
cancel |
write:donations |
Detach a donation (idempotent). |
received |
read:donations |
The MAINTAINER's inbox, gifts pinned to repos this account owns. |
decline |
write:donations |
Refuse a gift you were given, parks the row and releases the donor's box/key. Authorized against the RECIPIENT (the pinned repo's owner); the donor's own detach is cancel. |
set_model |
write:donations |
The maintainer's model pick on a received llm gift, inside the donor's ceiling (null clears it). |
Integration
| Action |
Scope |
Description |
list |
read:integrations |
List the account's connected integrations (status only; credentials never cross the boundary). |
get |
read:integrations |
Get one connector by kind (status only; never echoes the secret). |
disconnect |
write:integrations |
Disconnect a connector: drops the row and its vault secret. No connect verb, credentials stay dashboard-only. |
source_list |
read:integrations |
The account's connected inbound webhook sources: url, gesture, status. Never a secret. |
source_connect |
write:integrations |
Connect an inbound webhook source (sentry | linear | generic): mints the url and the signing secret, returned ONCE. The tenant is this row; a delivery never names one. A gesture is required; nothing is claimed implicitly. |
source_rotate |
write:integrations |
Mint a new signing secret for a source, keeping the old one verifying for the rotation window so no delivery is dropped. Returned ONCE. |
source_disconnect |
write:integrations |
Disconnect an inbound webhook source: drops the row and both vault secrets. |
Digest
| Action |
Scope |
Description |
list |
read:digests |
Digest header rows newest-first (per_page cap). |
get |
read:digests |
One digest with rendered_html. |
Billing
| Action |
Scope |
Description |
keys_list |
read:billing |
List BYOK keys (masked). |
key_add |
write:billing |
Add a BYOK key, sealed + captured, never echoed. Takes the picked model plus an optional per-model lane tier (fast | general | smart | heavy). |
provider_models |
write:billing |
List a provider’s real model ids for a raw key, BEFORE capture. The org-pool twin of account provider_models; stores nothing. |
key_delete |
write:billing |
Delete a BYOK key. |
key_verify |
write:billing |
Verify a key against its provider (live probe). |
key_rotate |
write:billing |
Swap an org key's material in place (probe first; a refusal writes nothing). |
usage |
read:billing |
Usage rollup for the current billing window. |
entitlements |
read:billing |
The account's tier entitlements. |
portal |
write:billing |
Mint a Stripe billing-portal URL. |
checkout |
write:billing |
Mint a Stripe Checkout session for N seats of solo | pro. |
set_cap |
write:billing |
Set the monthly spend cap. |
log_sink_get |
read:billing |
Read the LLM-log sink config. |
log_sink_set |
write:billing |
Set the LLM-log sink (validate + probe + seal). |
log_sink_clear |
write:billing |
Clear the LLM-log sink. |
BYOK key purpose
| Action |
Scope |
Description |
set |
write:billing |
Designate a BYOK key to a lane fence (a job class, review, or gardener; default is refused). An unrecognised value is refused at input naming the admissible set, before any row is touched. |
clear |
write:billing |
Clear the key's lane fence, returning it to a general key. Reads ride billing.keys_list (no separate get action). |
LLM route
Which pool key, provider or model serves which work. A pin names a purpose (a job
class, review, gardener, or the default catch-all) plus at least one of
key_label / provider / model; a re-pin replaces the row, so axes you leave
out are cleared. A repo pin beats the org one at claim time, and within a scope an
exact purpose beats the catch-all. Keys themselves live on the billing verb: a
route names a key by label, never key material.
| Action |
Scope |
Description |
list |
read:billing |
Every routing pin the account holds, org and per-repo. |
org_pin |
write:billing |
Pin the account-wide key / provider / model for one purpose (a job class, review, gardener, or the default catch-all). |
org_clear |
write:billing |
Clear the org pin for one purpose. Idempotent. |
repo_pin |
write:billing |
Pin one repo's route (repo uuid); it beats the org pin at claim time. |
repo_clear |
write:billing |
Clear a repo pin for one purpose. Idempotent. |
Email route
| Action |
Scope |
Description |
list |
read:account |
The resolved notification category → address matrix. |
set |
write:account |
Override one category's route. |
delete |
write:account |
Clear an override (back to the default). |
Notification
Your own inbox and delivery preferences, the same ones the dashboard bell and the
notification settings page drive. Inbox rows are events rather than deliveries: one
escalation fanned out to email and push reads as a single row, and marking it read
clears it everywhere. Every action needs a user-bound credential, because an inbox
belongs to a person; a machine token is refused. A mandatory cell (an escalation always
emails, which is the disclosure contract) refuses prefs_set. Web Push device
subscriptions stay browser-only and have no verb.
| Action |
Scope |
Description |
inbox |
read:account |
Your notification inbox, newest first (channel deliveries collapsed to one row per event) plus the unread count. |
read |
read:account |
Mark one event read; answers the new unread count. Idempotent. |
read_all |
read:account |
Mark every unread event read (clears the badge). |
prefs_get |
read:account |
The resolved (kind × channel) preference matrix, with the defaults. |
prefs_set |
write:account |
Set one cell. A mandatory cell (an escalation always emails) is refused. |
prefs_clear |
write:account |
Drop one override, back to the default. Idempotent. |
Token
| Action |
Scope |
Description |
list |
read:account |
List PATs (masked rows incl. revoked). |
mint |
write:account |
Mint a PAT (subset-of-caller scopes; plaintext returned ONCE). |
rename |
write:account |
Relabel a PAT (the human name only, no change of reach). |
revoke |
write:account |
Revoke a PAT. |
Webhook
Outbound delivery targets. Urls come back masked (origin kept, path redacted, since a
webhook path can itself carry a shared secret) and the HMAC signing secret is returned
exactly once, by create. test does not dial out from the control plane: it queues a
signed test.ping that the worker delivers on the real path, so the result names the
queued delivery and the outcome shows up in deliveries.
| Action |
Scope |
Description |
list |
read:webhooks |
List the account’s outbound webhooks (urls MASKED, never the signing secret). |
get |
read:webhooks |
Get one webhook by id (masked url, health, subscribed events). |
deliveries |
read:webhooks |
The account’s delivery ledger, newest first: status code, attempt, response excerpt. |
create |
write:webhooks |
Create a delivery target. The HMAC signing secret is minted server-side and returned exactly ONCE, since there is no re-reveal door. |
delete |
write:webhooks |
Delete a webhook (its deliveries cascade). |
test |
write:webhooks |
Queue a signed test.ping through the real delivery path (the worker fires it within ~15s); the outcome lands in deliveries. |
Member
The active org's roster. list returns all of it, with no page knob, because the REST
collection does too and a truncation nobody is told about is worse than a long answer;
list_invitations answers the whole invitation history for the same reason.
Every mutation below needs a user-bound credential (invite, set_role, remove and
revoke_invitation alike): the gate asks whether your own role outranks the target, and a
machine token holds no role at all. Neither read does. Nobody may promote past their own
rank, and the last owner can be neither demoted nor removed.
| Action |
Scope |
Description |
list |
read:account |
The active org’s WHOLE roster (no paging, same as REST), each row marking whether it is you. |
invite |
write:members |
Add someone to the org, by exactly one of login (an already-registered user, on the roster at once) or email (anyone: a one-time invitation link, returned once and mailed to them). Needs a user-bound credential: the gate asks whether YOUR role outranks the target. |
set_role |
write:members |
Change a member’s role. Nobody may promote past their own rank, and the last owner cannot be demoted. |
remove |
write:members |
Remove a member. The last owner cannot be removed. |
list_invitations |
read:account |
The org’s invitations, every status, newest first. |
revoke_invitation |
write:members |
Withdraw one PENDING invitation (idempotent). Refuses an already-accepted one; remove the member instead. |
SSO
Your org's own OIDC single sign-on. Owner-only on every action, so a PAT never reaches
it. set carries no client_secret field: a credential the platform mints may ride
back in a result, but one you supply never crosses this boundary, which is the same
rule that leaves integration without a connect. So set updates the non-secret
half and reuses the stored sealed secret, and refuses outright until a connection
exists. Create that one in the dashboard, or with PUT /v1/org-sso.
| Action |
Scope |
Description |
get |
read:account |
The org’s identity provider, MASKED: the stored client secret is a boolean, never a value. Shows the not-entitled state too. |
set |
write:account |
Update the non-secret half of the OIDC connection (issuer, client id, redirect, claim gate, group→role map) and REUSE the stored client secret. A caller-supplied secret never crosses this surface, so creating a connection stays a dashboard/REST act. The issuer is probed live. |
delete |
write:account |
Remove the connection; the org falls back to GitHub login. |
Ops
The devops / debugger run: reproduce a failure against the repository's own secrets,
read the running system, act on infrastructure, and report. It is the one role that
reaches a live system, so the surface here is deliberately one verb wide.
outcome_kind: report is the default and opens no pull request: a devops run's
deliverable is findings. ops_action may act on infrastructure, and on a
production-tagged box it refuses without a fresh signed approval and escalates to a
human; there is no field on this verb that can supply one, by design. A run that needs
access it does not have reports a blocker naming the credential rather than working
around it, and files a raw task for triage when the fix is bigger than the session.
| Action |
Scope |
Description |
dispatch |
write:tasks |
Dispatch a devops / debugger run against a repository: reproduce a failure with the repo’s own secrets, read the running system, and report. outcome_kind: report (the default) delivers findings and opens no pull request; ops_action may act on infrastructure and, on a production-tagged box, REFUSES without a fresh signed approval and escalates to a human (this verb cannot supply one). A run that lacks an access it needs reports a blocker naming the credential rather than working around it, and files a raw task when the fix is bigger than the session. |
Scopes
PATs carry only the scopes you select at creation time. Dashboard session cookies
grant all scopes. Scope names follow read|write:<resource>.
| Scope |
Grants |
read:repos / write:repos |
Repos + project management + KB |
read:tasks / write:tasks |
Fleet task queue |
read:runners / write:runners |
Boxes + templates + config + CI |
read:sessions / write:sessions |
Audit log + interactive runs |
read:issues / write:issues |
Tracked issues + forced handoff/escalate |
read:prs / write:prs |
PR review + pending decisions |
read:artifacts / write:artifacts |
Artifact storage |
read:dashboards / write:dashboards |
Realtime boards |
read:donations / write:donations |
OSS donations |
read:digests |
Weekly-digest archive |
read:billing / write:billing |
BYOK keys, usage, billing controls |
read:account / write:account |
Identity view, account switch, email routes, PATs |
admin:users |
Closed-beta user approval (staff only) |
admin:accounts |
Operator account overrides (staff only) |
admin:read:platform / admin:read:orgs / admin:read:users |
Platform radar reads (staff only) |
Verb tables on this page are generated from the MCP catalog (FLAT_TOOL_SCOPES + ARMY_ACTION_SCOPES in @developerz/mcp) by bun run mcp:doc; headings and prose are hand-curated. The same matrix is embedded in docs/idea/api.md + docs/idea/mcp.md.