Receiving mail
What happens between an email arriving and your agent acting on it.
Inbound mail needs no setup. An identity receives at its address from the moment it exists, and if you connected an assistant over MCP it can already read the inbox. This chapter is about what happens in between, and about the three ways to find out that something arrived.
What happens to an arriving message
It is checked against the identity filter first. Mail that does not pass is dropped before it is stored, logged on the agent page, and pushed as message.filtered, so a whitelisted agent never sees it at all. See /docs/identities for how the modes and rules work.
What survives is threaded, using the standard In-Reply-To and References headers, so a reply lands in the same thread as the message it answers rather than starting a new one. It is filed against the mailbox with a spam verdict from the receiving side, its attachments are stored separately from the body, and only then does message.received fire. Delivery is idempotent: the same Message-ID arriving twice at one mailbox is filed once.
Finding out that mail arrived
There are three ways, and which one is right depends on what is doing the waiting. /docs/waking compares them and sets up the third; the short version is below.
Reading a message
list_messages returns snippets rather than whole bodies, which is usually what an agent should reason over first: it keeps a scan of twenty messages inside a sensible context. Call read_message for the full body when one of them turns out to matter, and get_thread to read a conversation in order before answering it.
Attachments arrive as metadata on the message, not as bytes. Fetch the ones you need by filename with get_attachment. A message with a 9 MB PDF costs nothing to list.
While an agent is paused
Pausing an agent stops it sending and stops anything connecting as it. Mail addressed to it still arrives and is filed, so nothing is lost and it picks up where it left off. What the sender hears meanwhile is a setting: an agent with a reply written on its Settings tab answers each new conversation once while it is paused, and one without says nothing at all.
That notice is never sent to bounces, autoresponders, list mail, or no-reply addresses, and never more than once per conversation. get_thread reports away_notice_sent_at, so an agent picking a conversation back up after a pause can tell whether the person has already been told, rather than apologising for a delay in the same words twice.
Answering
Prefer reply_all over composing a fresh message: it keeps the threading headers intact, so the exchange stays one conversation in the recipient's client. A reply also counts as a reply rather than a cold send, which is the difference between drawing on the ordinary allowance and passing under the tripwires that watch cold sends. See /docs/sending.