Mail from an agent — 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).

# Mail from an agent

Every repository agent has an address on `inbox.sails.app`. Sending uses that identity. Mail to that address writes a thread and starts a background goal as the agent.

## Done looks like

Outbound: `mail send` succeeds and the recipient has one HTML email (markdown `--text`). If you passed `--thread`, it is the same conversation in Sails **and** in Gmail (In-Reply-To).

Inbound: a stub appears under `agents/{id}/mail/inbox/`. The first tool call in the new goal is `thread show` for that thread. After that you can reply with `--thread`.

## Worked example: ship a status note

Job: agent `site-bot` already exists. Tell `you@example.com` that the subscribe form shipped. Keep a later reply in the same thread.

Owners send as the agent without `su`:

```bash
mail send --as site-bot --to you@example.com --subject "Site update" --text "Shipped the **subscribe form**. Try /newsletter."
```

`--text` is markdown. The platform renders HTML for the recipient and keeps a plain-text fallback.

When that person replies, or when you continue the same conversation, hydrate first, then pass the thread id:

```bash
thread show THREAD_ID
mail send --as site-bot --to you@example.com --thread THREAD_ID --subject "Site update" --text "Also enabled the thanks page."
```

Always pass `--thread THREAD_ID` when you are replying. That continues the Sails thread and sets Resend `In-Reply-To` / `References` from the inbound Message-ID so it threads in the recipient’s inbox. Without `--thread`, this is a **new** conversation. Subject gets `Re:` when threading headers are set and the subject does not already start with `Re:`.

In a background goal running **as** the agent, prefer the `mail_send` tool (same flags: `to`, `subject`, `text`, `thread_id`). Bash `mail send` works when workspace commands are wired. Do not `su` just to send if you can pass `--as`.

## Addresses

AddressWhen it works

`{agent_uuid}@inbox.sails.app`

Always

`{claim}@inbox.sails.app`

After `agent claim USERNAME`

Outbound From prefers the claim when set. Claim cannot be a UUID or a reserved word (`agent claim` will reject it).

```bash
agent claim site-bot
# then site-bot@inbox.sails.app works for that agent
```

## Receive

Mail to the agent:

1.  Routes by local-part (UUID or claim).
2.  Stores the body under `.sails/threads/`.
3.  Writes a stub at `agents/{id}/mail/inbox/{email_id}.md`.
4.  Starts a background **goal as the agent**. Prompt: `agents/{id}/events/email.received.md`.

The inbox stub is **not** the full conversation. The inbound goal says the first tool call should be `thread_show` for that thread. Call it before you decide or reply.

```bash
mail inbox --as site-bot
thread show THREAD_ID
mail show EMAIL_ID --as site-bot
```

Same-domain agent mail (`mail send --to …@inbox.sails.app` when the local-part is an agent) is delivered **locally**. Inbox stub + `email.received` goal, no wait on Resend MX. External addresses go through Resend.

This inbound path is **not** `webhook add`. Platform mail uses `POST /sails/mail/resend`. Your own Resend account is a different job — see [Start a goal from a webhook](/guides/how-to/start-a-goal-from-a-webhook).

## Flags

```bash
mail send --to ADDR [--subject S] [--thread ID] [--text BODY | --html-file PATH] [--as AGENT]
mail inbox [--as AGENT]
mail show PATH|ID [--as AGENT]
```

Flag / commandWhat it does

`--to`

Recipient

`--subject`

Subject line

`--text`

Markdown body (default)

`--html-file PATH`

Use only when you already have HTML

`--thread ID`

Continue a conversation; required for replies

`--as AGENT`

Owner sends as that agent without `su`

`mail inbox`

List inbox stubs

`mail show`

One message by path or id

`thread show ID`

Full history before you reply

`--text` and `--html-file` are alternatives. Prefer `--text`.

## Failure modes

What you seeWhat it meansWhat to do

Reply starts a new Gmail thread

You omitted `--thread`

`thread show`, then `mail send --thread THREAD_ID`

Goal acts on a stub and gets it wrong

Stub is not the body

First call: `thread show THREAD_ID`

Mail to `name@inbox.sails.app` never arrives

No claim, or wrong local-part

Use `{uuid}@inbox.sails.app`, or `agent claim`

You `su` and lose the owner session

Unnecessary for send

`mail send --as AGENT` as the owner

You used `webhook add` for agent mail

Wrong ingress

Agent mail is platform Resend; `webhook add` is for _your_ HTTP → goal

Same-repo agent never got the letter

You used an external address

Send to `{uuid or claim}@inbox.sails.app` for local delivery

Agent-to-agent **inside the repo** without email is `message send`, not `mail send`.

See [Mail](/guides/features/mail).
