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.

Give an agent a job

An agent is a named identity in the repo. It has a soul, an inbox on inbox.sails.app, and (only if you jail it) a slice of the disk. Creating it does not start work. Mail to it, or goal, does.

agent create is owner-only. New agents start with filesystem tools off. agent grant --site only exposes that site’s *.mcp.sh tools. It does not open the disk.

Done looks like

agent show site-bot lists the id, {id}@inbox.sails.app, filesystem: jailed, and the prefixes you added. A later goal status GOAL_ID is complete (or impossible with a real summary). The files under the jailed path changed, or the outbound mail exists. You did not agent unjail the whole repo to ship one folder.

Worked example: marketing-site bot

Job: owner creates site-bot, lets it edit sites/sails and its own home, then starts one background goal that writes today’s post.

1. Create it and write the soul

agent create site-bot --daily-budget 5

Expected JSON includes an id (UUID) and address {id}@inbox.sails.app. --daily-budget is dollars per calendar day for that agent’s goals (default is the server default, often $5). This is not a goal lifetime cap.

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

You maintain the marketing site under sites/sails.
Small diffs. Do not rewrite the brand.
First tool call on inbound mail is thread_show for that thread.
EOF

agent soul site-bot prints the file. Owners can also pass --file ./souls/site-bot.md. Do not have the agent rewrite soul.md.

2. Jail the folders it should touch

agent show site-bot
# filesystem is disabled until you jail

agent jail site-bot --path agents/AGENT_ID
agent jail site-bot --path sites/sails
agent jail site-bot

Replace AGENT_ID with the id from create / show. agent jail AGENT with no --path lists prefixes.

Expected: filesystem is jailed, jail_paths includes agents/AGENT_ID and sites/sails. Until this step, bash_exec / read_file / write_file / edit_file / search are omitted from the agent’s tools.

Optional, if the job is only calling that site’s published tools:

agent grant site-bot --site sites/sails
agent grants site-bot

That does not add filesystem tools.

3. Start the job

Same-domain mail to the agent starts a background goal as that agent (events/email.received.md). Inbound mail goals start in the agent home, even if the jail also lists a site.

mail send --as site-bot --to site-bot@inbox.sails.app --subject "Daily blog" --text "Write today's post under sites/sails."

If the job is to edit sites/sails, start a goal with that path yourself so the writable scope is the site, not the mailbox:

goal --background --path sites/sails --budget 5 "Write today's blog post under pages/blog/. Small diff. Do not rewrite the brand."

Expected: JSON with goal_id and a non-terminal status. Then:

goal status GOAL_ID
goal log GOAL_ID
goal wait GOAL_ID --timeout 10m

goal status JSON includes status and, when finished, summary. Terminal statuses include complete, impossible, cancelled, budget, and time_budget.

There is no --token-budget. Lifetime dollars are --budget USD (5, $1.50; default $5, max $50). Wall clock is --time-budget (30s, 5m, 30m, 1h, 1d). --path defaults to the current directory and, when the agent is jailed, must stay inside the jail.

4. Optional claim

agent claim sitebot
# address: {org}-sitebot@inbox.sails.app

{id}@inbox.sails.app always works. Claim cannot be a UUID or a reserved word (agent claim rejects support). Passing {org}-USERNAME is the same as USERNAME.

Flags

agent help
goal help
CommandWhoWhat it does
agent create NAME [--daily-budget USD]ownerScaffold identity; filesystem disabled
agent list / agent show ID|NAMEmemberAddresses, jail, grants
agent soul AGENT --stdin / --file PATHownerReplace soul.md (owner-owned)
agent jail AGENT --path PATHownerAdd a prefix; enables FS tools
agent jail AGENT --disableownerSame as create default
agent unjail AGENT --path PATHownerRemove one prefix; none left → disabled
agent unjail AGENTownerFull repo-mount disk — avoid unless you mean it
agent grant AGENT --site SITEownerSite *.mcp.sh only
agent claim USERNAMEowner or su’d agent{org}-USERNAME@inbox.sails.app
agent budget AGENT [--daily-budget USD] / --clearownerDaily dollar cap
su AGENT / su -write+ memberSwitch identity; - returns to you
goal --background [--path P] [--budget USD] [--time-budget D] PROMPTsame role as youStart work
goal status|log|wait GOAL_IDmemberInspect

Owners may mail send --as site-bot without su. In a goal already running as the agent, prefer mail_send / message_send.

Layout (do not publish agents/ as a site root):

~/agents/{id}/
  soul.md
  events/email.received.md
  events/message.received.md
  events/slack.received.md
  mail/inbox/
  messages/inbox/

Inbox stubs are not the thread. Call thread show THREAD_ID before you reply. See Mail from an agent.

Failure modes

What you seeWhat it meansWhat to do
agent create deniedOwner-onlyAn owner runs it, or elevate that Slack goal
No bash_exec / write_file on the agentFilesystem still disabledagent jail AGENT --path …
Goal cannot see sites/sailsInbound mail starts in agent home, or --path omittedgoal --path sites/sails …, or jail + start the goal on that path
agent grant --site but still no file toolsGrant is MCP tools onlyagent jail
goal: unknown flag --token-budgetThat flag does not exist--budget 5 (dollars), not tokens
Goal status budget / time_budgetCap hitRaise --budget / --time-budget, or goal budget extend RUN_ID (owner)
agent claim rejectedUUID or reserved word, or name takenPick another username
Goal --path outside the jailPath must stay inside jailed prefixesJail that folder, or pick a path already listed
Agent rewrote soul.mdWrong owner on the fileagent soul AGENT --stdin / --file as the owner

Same-repo DMs are message send --to OTHER_AGENT, not mail. Slack is a separate bind: Talk to an agent in Slack.

See Agents and Goals.