Skip to main content
This page lists, per role, the tools a session is given: registered with the model and allowed by the session’s ceiling. A tool that is not listed for a role is not described to that model at all. Each section ends with the file and symbol it was read from.
A test in the repository (src/server/docs-site.test.ts) imports the tool lists from the code and fails if any tool name is missing from this page. The prose around the names is checked by people, not by the test.

How a session’s tools are decided

Three filters run in order, and a tool must survive all three.
  1. Registration. A tool exists only if its server is built for the session. A connector’s server is built only when that brand’s credentials for it resolve. An operator switch that is off means the tool is never registered.
  2. The ceiling. A coworker run carries a list of permitted tool names. Every server is intersected with it, and a server with nothing left is dropped. A call to a name outside the ceiling is denied and logged as a permission_denied event.
  3. The per-call gate. Some registered tools ask a person before each call, or refuse above a spending limit. See Approvals and budgets.
On the default harness the session’s tool list is passed to the Claude Agent SDK as an exclusive allowlist (tools), with a permission callback that is always present. The code deliberately does not pass allowedTools: an entry there is approved automatically and would skip the callback. Source: src/engine/session.ts (createSession), src/engine/harness/claude-code.ts (claudeCodeOptions), src/engine/tool-surface.ts

Roles at a glance

Built-in Claude Code tools

The deployment’s built-in list is tools in agent.config.json. As shipped it is: Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch Because the list is an exclusive allowlist, every other built-in the CLI has (for example Agent, NotebookEdit, TodoWrite) is not offered to any role. Removing a name from agent.config.json removes it from every role.
In the local environment, Bash and the file tools run on the server host. They are confined to the session’s workspace folder by a path check on the tool’s arguments. The code calls this “policy, not a sandbox”: it catches honest mistakes, not a determined adversary. Under E2B the host file tools are disallowed and the sandbox container is the boundary.
Under E2B (selected when the operator sets an E2B key), a coworker’s ceiling does not include the sandbox tools, so a coworker there keeps only WebSearch and WebFetch of the built-ins. This is reasoned from the code, not observed on a run. Source: agent.config.json, src/engine/config.ts (loadConfig), src/engine/environment.ts (HOST_FS_TOOLS), src/engine/guard.ts (evaluateAccess), src/server/registry.ts (coworkerCeiling)

Person chat

A person’s own conversation in the browser. It gets the widest surface, and it is the only role with someone present to approve gated calls.

Platform tools

Environment tools (E2B only)

The browser reads pages only. Clicking, typing, filling forms, running JavaScript, downloads, PDFs, cookies and long-lived sessions are not built, because each turns a read into a write on someone else’s site.

Connector tools

A person’s session gets every tool of every connector the brand has connected, subject to the operator switches below. The full list, and what each connector’s writes require, is on Connections. The names in brief: The Shopify-side content tools for the Content writer preset are listed under Specialist coworker run: a person’s session does not register them. Whose credentials a session uses: a brand’s own stored connections first; then a connection the account owner has shared with that brand; then, for the deployment owner’s own brand only, the server’s host environment. No other brand ever inherits the host environment. Source: src/engine/session.ts (createSession), src/engine/connector-tools.ts (TOOLS_BY_CONNECTOR), src/engine/credentials.ts (resolveConnectors), src/server/registry.ts (create)

Inbound email turn

When AGENTMAIL_WEBHOOK_URL_SECRET is set, an email that arrives in the brand’s AgentMail inbox starts one turn on the default model. A stranger chose its input and nobody is watching it, so its session is built narrow: Tools: mcp__agentmail__agentmail_list_threads, mcp__agentmail__agentmail_search_threads, mcp__agentmail__agentmail_get_thread, mcp__agentmail__agentmail_list_messages, mcp__agentmail__agentmail_search_messages, mcp__agentmail__agentmail_get_message, mcp__agentmail__agentmail_get_attachment, mcp__agentmail__agentmail_whoami, mcp__agentmail__agentmail_create_draft, mcp__agentmail__agentmail_list_drafts, mcp__agentmail__agentmail_get_draft. Not given: any built-in tool, the sandbox or browser, memory, the project folder, transcripts, skills, goals, team, every other connector, and the four AgentMail send tools whatever AGENTMAIL_ALLOW_SENDS says. The session is handed AgentMail’s credentials and no others, so no other connector’s server is even built. No one to ask. Like a coworker run, an inbound turn has no approval channel, so nothing it does can park an approval card. Limits: $0.50 and eight turns per message, or the deployment’s own per-session limits if they are lower.
Until 2026-10-11 an inbound turn had the same tool surface as person chat, on the deployment’s per-session limits, and “read-only” was only an instruction in its prompt. That was the gap this section used to warn about. The new surface is proved against a stand-in for the CLI, not on a live delivery.
Each brand’s inbound turns are rate-limited, and they count against the live session cap. Source: src/server/http.ts (inbound webhook route), src/server/registry.ts (createInbound), src/engine/agentmail-inbound.ts (inboundSessionShape, INBOUND_TOOLS, composeInboundTurn)

Coworker run

A coworker is a saved profile that runs a task unattended. Its permitted tools are the intersection of what its profile asks for and the coworker ceiling. The coworker ceiling on a standard route is the deployment’s built-ins plus memory and the project folder: Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch, the nine memory tools, and four of the five project tools. Since 2026-10-11 mcp__project__project_delete is not in it: a delete is recursive, unapproved and cannot be undone, so only a person’s own chat holds it. A saved profile that lists it keeps the entry and loses the tool. On a read-only route it is only the read-only built-ins: Read, Glob, Grep, WebSearch, WebFetch. What a coworker run actually holds, beyond the ceiling: Limits. Each profile carries its own runBudgetUsd (must be above zero), maxTurns (at least 1), maxConcurrentRuns (at least 1), maxDelegationDepth (0 or more), and optionally maxAttempts (default 1). The run’s dollar and turn caps are the profile’s, not the deployment’s. The monthly model cap is the brand’s and is shared with person chat. A retry is narrowed to the tools the previous attempt actually ran with. A profile whose requested tools all fall outside the ceiling is refused rather than started with none. Source: src/server/registry.ts (coworkerCeiling, create), src/engine/coworkers.ts (CoworkerLimits, permittedTools), src/engine/tasks.ts (ceilingFor), src/engine/memory.ts (memoryToolNames)

Specialist coworker run

A specialist is a coworker with a grant: a list of connectors, a spending allowance for the connectors that bill, and optionally bundled skills. Only a person can write a grant, through the coworker settings (PUT /coworkers/:id). An agent cannot widen its own or another coworker’s grant. The grant adds to the coworker ceiling, in this order:
  1. The tools of each granted connector that are in the read table (CONNECTOR_READS) and whose server will actually register with the credentials the run is handed.
  2. A joint tool, such as mcp__dataforseo__seo_page_opportunities, only when every connector it reads (DataForSEO, Search Console and Shopify) is granted and live.
  3. Opt-in tools of a granted connector: today the content writer’s tools beside Shopify, given only to a profile that asks for them by name.
  4. The skill tools, when the grant names at least one bundled skill that resolves.
  5. Tools that ride on one skill: today the SEO brief tools on seo-method.

The read table

These are the only connector tools a specialist or the goal agent can be granted. The content writer tools write only into the brand’s project folder: a voice guide saved as a draft, and page copy saved as a draft. Nothing is written to the store. A voice guide is used only once its status line says APPROVED, which the tool itself can never set.

SEO brief tools

Rules a grant must pass

A profile is refused when it is saved, not at its first call, if:
  • it asks for a connector tool its grant does not cover;
  • it asks for any tool outside the read table (“a specialist reads and proposes; it never commits”);
  • it grants a connector that bills (DataForSEO or Firecrawl) without an allowance, or with a per-run figure above the per-day figure;
  • it asks for a skill tool without granting a skill, or names a skill that is not bundled;
  • it asks for mcp__seo__seo_hand_off_brief at delegation depth 0.

Allowance

The per-run figure is enforced inside the connector’s spending gate on every call. The per-day figure is checked before a run starts: runs already ended today count at what they recorded (or their whole per-run figure if they recorded nothing), and live runs count at their whole per-run figure. Google products in a grant also narrow the Google credential the run is handed to the scopes of the granted products.

Presets

The coworker setup screen offers these starting points. Each is a profile a person can still edit before saving. Presets default to $0.50 per run, one run at a time, no delegation and ten turns. The SEO analyst may delegate one level so it can hand a brief to the Content writer. The Content writer is not given mcp__project__project_write, so it cannot mark its own voice guide approved by editing the file directly. Source: src/server/specialist.ts (specialistCeilingFor, specialistToolsFor, workerConnectorEnv), src/engine/connector-tools.ts (CONNECTOR_READS, OPT_IN_TOOLS_BY_CONNECTOR), src/engine/coworkers.ts (specialistProblem), src/engine/allowance.ts (specialistDayProblem), src/engine/seo/handoff.ts (TOOLS_BY_SKILL), public/coworker-presets.js

Goal agent step

The built-in goal agent (goal-agent) runs one step of a goal plan when a person starts it from the Goals page. It runs as an unattended coworker. Tools: Read, Glob, Grep, WebSearch, WebFetch, mcp__project__project_list, mcp__project__project_read, mcp__project__project_write. Plus, if a person has given it a connector grant under Goals, Advanced (PUT /goals/agent), the granted connectors’ tools from the read table, with an allowance for any that bill. Not given: Bash, Write, Edit, memory, transcripts, skills, team, goals, and any connector tool outside the read table. Limits: $0.50 per step, ten turns, one at a time, no delegation, at most two attempts. There is no separate daily cap for the goal agent; a granted billing connector’s per-day allowance applies.
An agent step has never been run against the real service, with or without a grant (GOALS_UNVERIFIED.agent_step_run, GOALS_UNVERIFIED.agent_step_with_grant).
Source: src/engine/goal-agent.ts (GOAL_AGENT_TOOLS, goalAgentToolsFor, goalAgentInvariantProblem)

Goal reviewer

The reviewer reads goal progress on each goals tick and writes a short review. Tools: none. Its profile asks for an empty tool list, and the code refuses to start a reviewer that has any tool, any delegation, or any grant. Limits: 0.10perreview,twoturns,oneatatime,oneattempt.Adailycapapplies:thesmallerofthedeployment′sfigureandthebrand′ssetting(default0.10 per review, two turns, one at a time, one attempt. A daily cap applies: the smaller of the deployment's figure and the brand's setting (default 0.25 per day, GOALS_REVIEW_DAILY_USD). If today’s spend cannot be read, no review runs. Model: a reviewer created after 2026-09-23 defaults to google/gemini-3.8-flash through OpenRouter. What an empty tool list does on the wire was measured locally on 2026-09-05 against CLI 2.1.261: zero tool schemas sent, against 24 with the option omitted (GOALS_CAPTURED.empty_tools_on_the_wire). A review on the deployment has never been run (GOALS_UNVERIFIED.zero_tool_worker). Source: src/engine/goal-reviewer.ts (reviewerProfile, reviewerInvariantProblem, REVIEWER_MODEL), src/engine/goal-store.ts

Read-only route

A route is read-only when its model is not certified for the standard tool set, or when it runs on an uncertified harness. The session is assembled narrow, not fenced wide. Which routes are read-only today:
  • Models. Every gateway model in the registry is certified. The one held back is claude-haiku-5-5, which is read-only for every brand except the owner’s: the owner’s own sessions run uncertified models on the standard set.
  • The loop harness. On only when HARNESS_LOOP_ENABLED is 1 or true. Owner only, OpenRouter only, $0.25 and eight model calls per session. It is given MCP tools only, never the CLI built-ins.
  • The Hermes harness. On only when HARNESS_HERMES_ENABLED is 1 or true and the MCP bridge is on (HARNESS_MCP_BRIDGE_ENABLED). Owner only, OpenRouter only, $0.25 and eight turns. Of Hermes’s own tools, only todo_list (also called todo), skills_list, skill_view, skill_manage and session_search are enabled, all scoped to a throwaway folder deleted when the session ends. Every permission request Hermes raises is rejected. The bridge listens on loopback only and serves only the owner on a read-only route.
The loop harness has one observed owner turn (2026-10-10, LOOP_CAPTURED). Hermes has never run against this adapter: HERMES_CAPTURED and BRIDGE_CAPTURED are empty.
Source: src/engine/session.ts (read-only ceiling), src/engine/backends.ts (READ_ONLY_BUILTINS, CLAUDE_HELD_BACK), src/engine/harness/registry.ts (switchOn, harnessSessionLimits), src/engine/harness/hermes.ts (HERMES_OWN_TOOLS), src/engine/harness/mcp-bridge.ts

What is never given, to any role

Each connector keeps a written list of what it deliberately does not build, and why. A summary: Source: GOOGLEADS_WITHHELD, MICROSOFT_ADS_WITHHELD, FIGMA_WITHHELD, SEARCH_CONSOLE_WITHHELD, ANALYTICS_WITHHELD, SHEETS_WITHHELD, GITHUB_WITHHELD, RAILWAY_WITHHELD, BROWSER_WITHHELD, and WITHHELD_TOOLS in src/engine/agentmail.ts and src/engine/firecrawl.ts

Where “absent beats refusing” has exceptions

Three groups of tools stay registered and refuse, on purpose:
  • AgentMail sends register whenever AGENTMAIL_ALLOW_SENDS is true, and refuse when the session has no approval channel. The refusal is the control: a session that cannot ask anybody cannot send mail.
  • GitHub writes (mcp__github__github_create_branch, mcp__github__github_commit_files, mcp__github__github_open_pull_request, mcp__github__github_comment) register with the connector and refuse, before any request to GitHub, when GITHUB_ALLOW_WRITES is off or there is no approval channel.
  • Google Sheets mcp__sheets__sheets_export and mcp__sheets__sheets_append refuse without an approval channel.
  • Shopify mutations through mcp__shopify__shopify_admin_graphql refuse, before any request to Shopify, when there is no approval channel. The tool stays registered because it is also the read path, and reads still run.
Coworkers hold none of these: they are outside the read table. Until 2026-10-11 the Shopify gate loosened rather than tightened without an approval channel: a mutation ran on SHOPIFY_ALLOW_WRITES alone when approvals were switched off. That was a hole, and it is closed. Source: src/engine/session.ts (comments at the AgentMail and Shopify servers), src/engine/agentmail.ts, src/engine/github.ts (preflight), src/engine/sheets.ts, src/engine/shopify.ts

Operator switches

Set on the server’s host environment. None can be changed from inside a session, and none can be set per brand. Spending limits for each connector are on Approvals and budgets. Source: src/engine/approval.ts (approvalRequired, approvalTimeoutFromEnv), src/engine/shopify.ts, src/engine/github.ts, src/engine/agentmail.ts, src/engine/railway.ts, src/engine/browser.ts, src/engine/browser-config.ts, src/engine/harness/registry.ts

What has been measured and what is reasoned

The code keeps two kinds of record side by side: *_CAPTURED maps for behaviour observed against the real service, with a date, and *_UNVERIFIED maps for behaviour reasoned from documentation. Only the first kind is a measurement. A passing test suite is evidence about the test fakes, not about any vendor.

Measured

Reasoned, never exercised

Source: the *_CAPTURED and *_UNVERIFIED exports across src/engine/