Email on inbox.sails.app. Bodies live under .sails/threads/. Inbox and sent stubs point at the thread. Two mailbox kinds:
| Kind | Create | Inbound | Folder |
|---|---|---|---|
| Agent | agent create + optional agent claim | Starts a background goal (events/email.received.md) | agents/{id}/mail/ |
| Folder inbox | inbox create USERNAME | Stores stubs only — no goal | inboxes/{username}/mail/ |
MCP clients that should read and send themselves use a folder inbox. Agents use mail when inbound should wake a goal with a soul.
Done looks like
Outbound: mail send succeeds. The recipient gets one HTML email from markdown --text (plain-text fallback kept). With --thread, it is the same conversation in Sails and in Gmail (In-Reply-To).
Inbound to an agent: stub under agents/{id}/mail/inbox/, then a background goal as that agent. First tool call is thread show for that thread.
Inbound to a folder inbox: stub under inboxes/{username}/mail/inbox/ only. No goal.
Worked example: folder inbox for an MCP client
Job: claim helpdesk, send one note, hydrate before any reply.
inbox create helpdesk
# → {org}-helpdesk@inbox.sails.app
# → folder: inboxes/helpdesk/mail/inbox/
mail send --as helpdesk --to user@example.com --subject "Hi" --text "Hello **world**"
mail inbox --as helpdesk
thread show THREAD_ID --as helpdesk
mail send --as helpdesk --to user@example.com --thread THREAD_ID --subject "Hi" --text "Following up."
inbox create / inbox rm are repository owner only. Folder inboxes require --as (su only works for agents). Owners may pass --as AGENT|INBOX without su.
Agent send (owner, no su):
mail send --as site-bot --to you@example.com --subject "Site update" --text "Shipped the **subscribe form**."
In a background goal running as the agent, prefer the mail_send tool (to, subject, text, thread_id). Bash mail send works when workspace commands are wired.
Addresses
| Form | Meaning |
|---|---|
{uuid}@inbox.sails.app | Agent or folder inbox UUID — always works |
{org}-{username}@inbox.sails.app | After agent claim USERNAME or inbox create USERNAME |
Outbound From prefers the claim when set. Claims are unique per org across agents and folder inboxes. Do not publish inboxes/ as a site root.
Commands
mail send --to ADDR [--subject S] [--thread ID] [--text BODY | --html-file PATH] [--as AGENT|INBOX]
mail inbox [--as AGENT|INBOX]
mail show PATH|ID [--as AGENT|INBOX]
thread show THREAD_ID [--as AGENT|INBOX]
inbox create USERNAME
inbox list
inbox show USERNAME|ID
inbox rm USERNAME|ID
| Flag / command | What it does |
|---|---|
--to | Recipient |
--subject | Subject line |
--text | Markdown body (default). Prefer this over HTML |
--html-file PATH | Use only when you already have HTML |
--thread ID | Continue a conversation; required for replies |
--as AGENT or --as INBOX | Owner sends or lists as that mailbox without su |
mail inbox | List inbox stubs |
mail show | One message by path or id |
thread show ID | Full history before you reply |
inbox create | Claim a folder inbox (owner only) |
Always pass --thread when replying. Without it, the send is a new conversation. Subject is prefixed with Re: when threading and the subject does not already start with Re:.
The inbox stub is not the full conversation. Call thread show THREAD_ID before you decide or reply. Inbound agent goals prepend: first tool call should be thread_show for that id.
Delivery
Same-domain addresses on inbox.sails.app deliver locally (agent and folder inboxes). External addresses go through the platform (Resend).
Agent and folder inboxes are platform-managed. Do not webhook add for {uuid}@inbox.sails.app. Use Start a goal from a webhook only when connecting your own email provider.
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 claim / inbox create |
inbox create helpdesk fails | Username already claimed by an agent (or another inbox) | Pick another username |
You su for a folder inbox | su is agents only | mail … --as USERNAME |
You used webhook add for agent mail | Wrong ingress | Platform mail is not a custom webhook |
| 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.
How to: Mail from an agent.