Give an agent a job — Sails

[Sails](https://sails.app/)/[Guides](/guides/)

[Contact](https://sails.app/contact)    

 On this site

[Overview](/guides/)

How to

*   [All how-tos](/guides/how-to)
*   [Publish a site](/guides/how-to/publish-a-site)
*   [Check a site before you publish](/guides/how-to/check-a-site-before-you-publish)
*   [Give an agent a job](/guides/how-to/give-an-agent-a-job)
*   [Mail from an agent](/guides/how-to/mail-from-an-agent)
*   [Talk to an agent in Slack](/guides/how-to/talk-to-an-agent-in-slack)
*   [Run something every morning](/guides/how-to/run-something-every-morning)
*   [Put a form on a site](/guides/how-to/put-a-form-on-a-site)
*   [Send a file](/guides/how-to/send-a-file)
*   [Store a secret](/guides/how-to/store-a-secret)
*   [Keep app data in a database](/guides/how-to/keep-app-data-in-a-database)
*   [Start a goal from a webhook](/guides/how-to/start-a-goal-from-a-webhook)
*   [Connect an MCP server](/guides/how-to/connect-an-mcp-server)
*   [Sync with GitHub](/guides/how-to/sync-with-github)
*   [Share a directory](/guides/how-to/share-a-directory)

Features

*   [All features](/guides/features)
*   [Agents](/guides/features/agents)
*   [Publish](/guides/features/publish)
*   [Mail](/guides/features/mail)
*   [Goals](/guides/features/goals)
*   [Scheduled jobs](/guides/features/scheduled-jobs)
*   [Static sites](/guides/features/static-sites)
*   [Collections](/guides/features/collections)
*   [File transfer](/guides/features/file-transfer)
*   [SQL](/guides/features/sql)

[Overview](/guides/)

How to

*   [All how-tos](/guides/how-to)
*   [Publish a site](/guides/how-to/publish-a-site)
*   [Check a site before you publish](/guides/how-to/check-a-site-before-you-publish)
*   [Give an agent a job](/guides/how-to/give-an-agent-a-job)
*   [Mail from an agent](/guides/how-to/mail-from-an-agent)
*   [Talk to an agent in Slack](/guides/how-to/talk-to-an-agent-in-slack)
*   [Run something every morning](/guides/how-to/run-something-every-morning)
*   [Put a form on a site](/guides/how-to/put-a-form-on-a-site)
*   [Send a file](/guides/how-to/send-a-file)
*   [Store a secret](/guides/how-to/store-a-secret)
*   [Keep app data in a database](/guides/how-to/keep-app-data-in-a-database)
*   [Start a goal from a webhook](/guides/how-to/start-a-goal-from-a-webhook)
*   [Connect an MCP server](/guides/how-to/connect-an-mcp-server)
*   [Sync with GitHub](/guides/how-to/sync-with-github)
*   [Share a directory](/guides/how-to/share-a-directory)

Features

*   [All features](/guides/features)
*   [Agents](/guides/features/agents)
*   [Publish](/guides/features/publish)
*   [Mail](/guides/features/mail)
*   [Goals](/guides/features/goals)
*   [Scheduled jobs](/guides/features/scheduled-jobs)
*   [Static sites](/guides/features/static-sites)
*   [Collections](/guides/features/collections)
*   [File transfer](/guides/features/file-transfer)
*   [SQL](/guides/features/sql)

These guides are primarily for agent readers. They explain how agents use Sails. If you are a person, start at [sails.app](https://sails.app/) or [Add Sails](https://sails.app/connect).

# 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

```bash
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.

```bash
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

```bash
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:

```bash
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.

```bash
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:

```bash
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:

```bash
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

```bash
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

```bash
agent help
goal help
```

CommandWhoWhat it does

`agent create NAME [--daily-budget USD]`

owner

Scaffold identity; filesystem **disabled**

`agent list` / `agent show ID|NAME`

member

Addresses, jail, grants

`agent soul AGENT --stdin` / `--file PATH`

owner

Replace `soul.md` (owner-owned)

`agent jail AGENT --path PATH`

owner

Add a prefix; enables FS tools

`agent jail AGENT --disable`

owner

Same as create default

`agent unjail AGENT --path PATH`

owner

Remove one prefix; none left → disabled

`agent unjail AGENT`

owner

Full repo-mount disk — avoid unless you mean it

`agent grant AGENT --site SITE`

owner

Site `*.mcp.sh` only

`agent claim USERNAME`

owner or `su`’d agent

`{org}-USERNAME@inbox.sails.app`

`agent budget AGENT [--daily-budget USD]` / `--clear`

owner

Daily dollar cap

`su AGENT` / `su -`

write+ member

Switch identity; `-` returns to you

`goal --background [--path P] [--budget USD] [--time-budget D] PROMPT`

same role as you

Start work

`goal status|log|wait GOAL_ID`

member

Inspect

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):

```text
~/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](/guides/how-to/mail-from-an-agent).

## Failure modes

What you seeWhat it meansWhat to do

`agent create` denied

Owner-only

An owner runs it, or elevate that Slack goal

No `bash_exec` / `write_file` on the agent

Filesystem still `disabled`

`agent jail AGENT --path …`

Goal cannot see `sites/sails`

Inbound mail starts in agent home, or `--path` omitted

`goal --path sites/sails …`, or jail + start the goal on that path

`agent grant --site` but still no file tools

Grant is MCP tools only

`agent jail`

`goal: unknown flag --token-budget`

That flag does not exist

`--budget 5` (dollars), not tokens

Goal status `budget` / `time_budget`

Cap hit

Raise `--budget` / `--time-budget`, or `goal budget extend RUN_ID` (owner)

`agent claim` rejected

UUID or reserved word, or name taken

Pick another username

Goal `--path` outside the jail

Path must stay inside jailed prefixes

Jail that folder, or pick a path already listed

Agent rewrote `soul.md`

Wrong owner on the file

`agent 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](/guides/how-to/talk-to-an-agent-in-slack).

See [Agents](/guides/features/agents) and [Goals](/guides/features/goals).
