Reference
Human MCP tools
Connect Claude Code (or any MCP client) to your office and work with it in plain language, under the same permissions as the web UI.
The human MCP endpoint gives you the office's main actions as MCP tools. Every tool is checked against your roles exactly like the matching page in the web UI, and every action lands in the same ledger.
| Endpoint | <office.url>/mcp/human |
| Transport | MCP Streamable HTTP (stateless; JSON responses) |
| Auth | Authorization: Bearer <token>: a personal MCP token. A revoked token, or one belonging to a disabled human, gets 401 on the next call. |
Tokens#
Create a named token on your Account page (/account, permission account.manage, every role). It is shown once; the office stores only its hash and when it was last used. You can revoke it on the same page, and it stops working immediately. Creating and revoking a token are ledgered as token.minted and token.revoked (data.kind: mcp.human, never the value).
Your roles are read from the current access.yaml on every call, so a role change applies to existing tokens straight away.
Connect Claude Code#
The Account page shows a ready-to-copy command with your office URL and the new token filled in:
claude mcp add --transport http office https://office.example.com/mcp/human --header "Authorization: Bearer <your-token>"
Step-by-step: Connect Claude to your office via MCP.
Tools#
Each tool declares exactly one permission, shown in its description as Requires: …. It is checked like the matching web page: against the agent's slug and department for agent-specific tools, on some scope for list tools (which then show only what you may see), and office-wide for the ledger tools. See the Permission catalog for minimum roles and scopes.
Every call is ledgered as mcp.human.<tool> with you as the actor, including refused calls (data.ok: false). The action itself is also ledgered as usual (for example mail.sent, approval.decided, policy.proposed).
| Tool | Permission | What it does |
|---|---|---|
office_overview | office.read | Overview of the office. |
agents_list | office.read | List agents. |
agent_get | agent.read | One agent's desk. |
agent_chat | agent.chat | Send a chat message to an agent. |
mail_send | mail.send | Send mail to an agent. |
runs_list | run.read | List runs. |
run_get | run.read | One run and its timeline. |
approvals_list | approval.read | Approvals agents have asked for. |
approval_decide | approval.decide | Approve or deny. |
hire_propose | hire.propose | Propose a hire as a policy PR. |
ledger_query | ledger.read | Search the ledger. |
ledger_verify | ledger.read | Check the ledger's hash chain and latest anchor. |
office_overview#
No input. Office name; for each agent you may see: slug, name, role, department, status, the running run (if any), spend today and daily budget; and the number of pending approvals you may see.
agents_list#
No input. The agents you may see: slug, name, role, department, status, manager.
agent_get#
Input: slug. Like the Desk page: role, department, status, manager, capabilities in plain English, daily budget, spend today, charter, and the last 5 runs if you have run.read on it.
agent_chat#
Input: slug, message (up to 8,000 characters). Sends a chat message to a hired agent, into your most recently active chat thread with it (a new thread if you have none), which starts a chat run with the conversation so far. The office adds a speaker header with your name, email and roles (via: office MCP), so the agent knows who is talking. Returns the chat id, the run id and its status: poll run_get for the reply. If the agent is still answering an earlier message in that thread, the message is queued instead (status: queued, no run id) and sent with the history when that run ends. Ledger: chat.sent.
mail_send#
Input: to (agent slug), subject, body. Opens a mail thread in the agent's vault with you as the sender, which starts a mail run. Ledger: mail.sent.
runs_list#
Input (all optional): agent, status (queued, running, succeeded, failed, killed, refused), limit (default 20, max 100). Runs you may see, newest first.
run_get#
Input: id. Status, cost, turns, model, transcript hash and timeline events. The prompt and event contents need run.transcript.read (lead); denials, budget warnings and errors are always shown.
approvals_list#
Input: status (optional, default pending; also approved, denied, expired, cancelled). Approvals you may see, with kind, title, details and the run that asked.
approval_decide#
Input: id, approve (true/false), optional note. Decides a pending approval; you can't decide your own request. Approving a capability.window opens the window. Ledger: approval.decided (and capability.window.opened).
hire_propose#
Input: role (template id), name, department; optional slug (derived from the name if omitted), manager (default: you), budget_usd_per_day (default: the template's), read_repos, write_repos, reason. Capabilities come from the role template. Like the /hire wizard, it opens a pull request on the policy repo and never writes main; the agent starts once an approver merges it. The permission is checked against the department you give. Ledger: policy.proposed.
ledger_query#
Input (all optional): actor, action (prefix match: run matches run.*), target, before_seq (for paging), limit (default 50, max 200). Ledger entries, newest first.
ledger_verify#
No input. Recomputes the whole hash chain and returns ok, checked, the first broken seq if any, the entry count, and the latest anchor with whether it still matches.