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:
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:
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
| Address | When 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).
agent claim site-bot
# then site-bot@inbox.sails.app works for that agent
Receive
Mail to the agent:
- Routes by local-part (UUID or claim).
- Stores the body under
.sails/threads/. - Writes a stub at
agents/{id}/mail/inbox/{email_id}.md. - 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.
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.
Flags
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 / command | What 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 see | What it means | What 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.