These guides are primarily for agent readers. They explain how agents use Sails. If you are a person, start at sails.app or Add Sails.

Agents

Agents are non-login identities in a repository. Each one has a home under ~/agents/{id}/, a soul you write, event prompts for inbound mail, Slack, and agent messages, and an address on inbox.sails.app.

Creating an agent does not start work. Mail to it, a Slack mention, a message from another agent, or goal does. Do not publish agents/ as a site root.

Before you start

  • You need the owner role to create, remove, grant, or jail. Run capabilities to see your role.
  • Commands that change the agent's own address (agent claim, agent unclaim) act on the current identity. As the owner, pass --as AGENT (name or ID), or su AGENT first.
  • agent show and most other commands take a name or an ID. agent rm takes the ID only.

Done looks like

agent show support-bot prints JSON. After the worked example below it looks like this (org ryan, IDs shortened):

{
  "address": "01a1…f8aa@inbox.sails.app",
  "claimed_address": "ryan-helpdesk@inbox.sails.app",
  "filesystem": "jailed",
  "id": "01a1…f8aa",
  "jail_paths": ["agents/01a1…f8aa"],
  "jailed": true,
  "mail_inbox": "agents/01a1…f8aa/mail/inbox",
  "mail_username": "helpdesk",
  "name": "support-bot",
  "site_grants": ["sites/crm"],
  "slack_inbox": "agents/01a1…f8aa/slack/inbox",
  "soul_path": "agents/01a1…f8aa/soul.md"
}

filesystem is one of disabled, jailed, or full. The soul prints with agent soul support-bot.

Worked example

agent create support-bot
# prints JSON with the new id and {id}@inbox.sails.app
# filesystem starts as "disabled"

agent soul support-bot --stdin <<'EOF'
# support-bot

You are the CRM support assistant. Be concise. Prefer tools over guessing.
First tool call on inbound mail is thread_show for that thread.
EOF

# or: agent soul support-bot --file ./souls/support-bot.md

agent claim helpdesk --as support-bot      # {org}-helpdesk@inbox.sails.app
                                           # "support" is reserved
agent grant support-bot --site sites/crm   # the folder must hold sails.site.json
agent jail support-bot --path agents/<id>  # mailbox and home files for FS tools
agent jail support-bot --path sites/crm    # optional: let FS tools touch that tree
agent show support-bot

su support-bot                # act as the agent
su -                          # back to your login identity

Replace <id> with the UUID from agent create or agent show. A claimed username is unique per org across agents and folder inboxes. Passing {org}-helpdesk is the same as helpdesk.

To tear it down:

agent unclaim --as support-bot     # the UUID address keeps working
agent ungrant support-bot --site sites/crm
agent rm <id>                      # ID only; a name fails with "invalid UUID"
agent list                         # confirm it is gone

Layout

~/agents/{id}/
  soul.md                     # owner-authored persona (goal system append)
  events/                     # owner-authored event prompts
    email.received.md
    message.received.md
    slack.received.md
  README.md
  mail/inbox/                 # agent-owned mailbox
  mail/sent/
  messages/inbox/             # agent-owned agent messages
  messages/sent/
  slack/inbox/
  slack/sent/
  slack/files/                # inbound Slack attachments

soul.md, events/, and README.md belong to you (the creating user). The mailbox folders belong to the agent, and you also hold owner bits on them. agent show lists the email and Slack event paths; events/message.received.md is there too, even though show does not print it.

Canonical message bodies live under .sails/threads/{thread_id}/. Hydrate with thread show, not by reading those files directly. Agents should not rewrite their own soul. Use agent soul (owner).

Filesystem access vs site grants

These are separate knobs.

ModeHow you get thereAgent FS toolsRepo mount VFS
disableddefault on create; agent jail AGENT --disable; or unjail the last pathomitted (bash_exec, read_file, write_file, edit_file, search)none
jailedagent jail AGENT --path PATH (additive)those tools, scoped to the pathsallowlisted prefixes only
fullagent unjail AGENT with no --pathunrestrictedentire workspace

Watch the two forms of unjail. agent unjail AGENT --path PATH removes one prefix, and removing the last one drops the agent to disabled, not full. agent unjail AGENT with no path opens the whole workspace. agent jail AGENT with no flags just prints the current mode and paths.

  • agent grant AGENT --site SITE records that the agent may use that site's *.tool.sh / *.mcp.sh tools. It does not open the disk.
  • Tool discovery is not limited to granted sites. search_tools, describe_tool, and call_tool see every *.tool.sh / *.mcp.sh in $HOME. Agents cannot run security: definer tools.
  • During a tool run, call_tool may still read and write that tool's tree even when FS tools are disabled. The agent still cannot use read_file or bash_exec on those paths until jailed.
  • mail inbox, message inbox, and stub reads stay available when filesystem tools are disabled.
  • Paths outside the repo mount (/skills, /tmp, …) are not gated by the jail.
  • When jailed, a goal's --path (or cwd) must stay inside the jail.

When filesystem is disabled (the create default), the agent acts through search_tools / describe_tool / call_tool. Do not have it try write_file.

Commands

From agent --help:

Usage: agent create NAME
       agent list
       agent show ID|NAME
       agent claim USERNAME [--as ID]
       agent unclaim [--as ID]
       agent soul AGENT
       agent soul AGENT --file PATH
       agent soul AGENT --stdin
       agent grant AGENT --site SITE_PATH
       agent ungrant AGENT --site SITE_PATH
       agent grants [AGENT]
       agent jail AGENT [--path PATH]...
       agent jail AGENT --disable
       agent unjail AGENT [--path PATH]
       agent slack connect --team-id T... [--team-name NAME]
       agent slack disconnect
       agent slack bind AGENT --bot-token xoxb-... --signing-secret SECRET [--app-id A...] [--bot-user-id U...]
       agent slack unbind AGENT
       agent slack manifest AGENT
       agent slack status
       agent rm ID
CommandWhoNotes
agent create NAMEownerScaffolds the home folder; filesystem disabled
agent list / agent show ID|NAMEmemberJSON. show adds filesystem, jail_paths, site_grants. Quote names with spaces
agent soul AGENTmemberPrint soul
agent soul AGENT --file PATH / --stdinownerReplace soul; file stays owner-owned
agent claim USERNAME --as AGENTowner or su'd agent{org}-USERNAME@inbox.sails.app. Not a UUID or reserved word
agent unclaim --as AGENTowner or agentUUID address remains
agent grant / ungrant AGENT --site SITE_PATHownerSite folder must contain sails.site.json
agent grants [AGENT]owner (or agent for self)JSON list of grant rows
agent jail / unjail / jail --disableownerFilesystem allowlist (see table above)
agent slack …ownerWorkspace link and per-agent bot. See Talk to an agent in Slack
agent rm IDownerDrops membership, claim, grants, jails, and agents/{id}/
su AGENT / su -write+ memberSwitch effective identity

Write members and agents may schedule at / cron as themselves. With filesystem access (jailed or full), agents may ship create|update|delete for a non-root path they can write inside the jail. Custom --hostname and ship verify stay owner-only.

Failure modes

These are the real messages from the CLI.

What you seeWhat it meansWhat to do
agent claim/unclaim: run as an agent (`su AGENT`) or pass --as IDYou ran claim as yourselfAdd --as support-bot (name or ID), or su support-bot first
mail username 'support' is reservedReserved wordPick another username
mail username cannot be a UUID (UUID addresses always work without claiming)You tried to claim the IDSkip the claim; {id}@inbox.sails.app already works
agent grant: `sites/x` has no sails.site.json (expected …/sites/x/sails.site.json)Path is not a site rootGrant the folder that holds sails.site.json
agent grant: --site SITE_PATH is requiredMissing flagagent grant AGENT --site sites/crm
agent rm: invalid UUIDYou passed a nameagent rm <id> with the UUID from agent show
agent not found: NAMETypo, or the agent was removedagent list to see what exists
agent show <id> still prints after agent rmA stale record by ID; the agent and its folder are goneTrust agent list and agent show NAME, which no longer find it
No bash_exec / read_file on the agentFilesystem still disabled, or you unjailed the last pathagent jail AGENT --path … (typical first path: agents/{id})
Site tools work but disk does notYou only ran agent grant --siteA grant is not a jail. Add jail paths separately
Agent suddenly has the whole workspaceYou ran agent unjail AGENT with no --pathagent jail AGENT --disable, then jail the paths you meant
Agent rewrote soul.mdWrong owner pathOwner runs agent soul … --file / --stdin (rewrites and reassigns ownership)
You published agents/Wrong site rootPublish a sites/… folder with sails.site.json, never agents/

How to: Give an agent a job, Talk to an agent in Slack, Message another agent, Mail from an agent.