The three tool classes
tools.yaml
The fields of a custom tool:
- Required:
description. - Optional:
handler_type(defaults tohttp),input_schema,output_schema(aliasesparameters/returns); HTTP tools addhttp,response_mapping,credentials. - Not accepted:
endpoint(usehttp.url),type(usehandler_type).
Older bundles may use
workflow_registered or api_call; new tools should use
handler_type: http or an MCP server.MCP tools
Swarm acts as an MCP client. Register servers inpolicy.yaml:
policy.yaml
prefix (pg.list_tables), and an agent references the
prefixed name in its tools list. If a server is unreachable, Swarm logs a warning and
starts anyway. See the MCP gateway reference.
Permissions
tools and native_tools cover what an agent may call. A separate list, permissions, covers
what it may do to shared platform state: change routing, write to the mailbox, request a
human decision, schedule a timer. These are verbs such as configure_routing, message_flow,
mailbox_send, human_task_request, human_task_decide, and schedule.
Rather than repeat the same list on every agent, name a permission bundle defined once in
policy.yaml:
policy.yaml
agents.yaml
policy.yaml does not define is a boot error.
The tools a permission unlocks
Most of these permissions gate a platform-builtin tool of the same name: hold the permission and the tool is offered to the agent, lack it and the tool is not.
A few permissions
gate other platform surfaces rather than a callable tool, such as
configure_routing (adjust
routing at runtime) and approve_spend (clear a budget hold). And two messaging tools need no
permission at all: agent_message and mailbox_send are universal, granted to every agent.
Native capabilities
bash, web_search, and file_io are not declared in tools.yaml; they are host
capabilities gated by an agent’s native_tools field (default all off):
native_tools is its own switch, separate from both tools and permissions. They cover
different things: permissions are about what an agent may do to shared platform state (routing,
the mailbox, entity writes), while native_tools are about what it may do on the host machine
(run a shell command, search the web, read or write files). So you do not also add a permission
for bash anywhere; turning on native_tools.bash is the whole grant.
One thing to know on the Claude CLI runtime: there, bash, web_search, and file_io come from
the CLI itself, and the platform will not stand in a substitute. If you turn one on and the
runtime cannot provide it, you get a clear error at startup rather than an agent that quietly
runs without it. (Setting policy.web_search_provider does not count as providing web_search
here; it has to come from the CLI.)
Flow reference data
Sometimes an agent needs to read a fixed file you ship with the flow: a prompt template, a lookup table, a list of things to skip. Put the file under the flow package’sdata/ directory
and list it in the agent’s flow_data_access:
read_flow_data tool that can open exactly those files and nothing else.
These files are read-only and travel with your contracts, so they change when you redeploy, not
while the flow is running. That makes them right for reference data, not for entity state or
scratch files the agent writes. As with native_tools, listing the file is the whole grant: no
permissions entry, and it is not part of tools. Only flow-scoped agents can use it.
Default-deny
An agent can only call a tool that is in itstools list, a universal tool, an emit tool, a
generated entity tool, a read_flow_data tool (if it declares flow_data_access), or an enabled
native capability. Anything else is rejected.
