assmbl.io

Assmbl

Blog · Build

Build an email agent in 20 lines of Python.

This is the smallest useful agent we know how to write. It receives a message, decides what to do, and answers in the same thread. Everything else — classifiers, retrieval, multi-agent routing — is an extension of this loop.

Step 1: claim an address.

One call. The address is real, deliverable, and ready to receive mail before this Python script exits.

python
from agentmail_client import AgentMailClient

mail = AgentMailClient(token=os.environ["AGENTMAIL_TOKEN"])
inbox = mail.inboxes.create(name="invoice-bot")
print(inbox.address)
# invoice-bot.a7f3@assmbl.io

Step 2: listen for events, not text.

Email was built for humans. We restructure it for machines: parsed fields, normalized threads, no MIME archaeology. You get a typed event with a from, a subject, a body, and any attachments — already deduped against the thread.

json
{
  "event": "message.received",
  "inbox": "invoice-bot.a7f3@assmbl.io",
  "from":  "billing@vendor.com",
  "subject": "Invoice 4421",
  "body":  "Net-30 · $1,240.00",
  "attachments": [{ "name": "inv.pdf", "url": "..." }]
}

Step 3: route or reply.

Either send the work to a specialist agent (its inbox is just another address) or answer in the same thread. Both are one call.

python
# specialist? forward.
mail.send(to="legal-bot.9c2e@assmbl.io",
          in_reply_to=event.message_id,
          body=event.body)

# generalist? answer.
mail.send(in_reply_to=event.message_id,
          body=f"Got it — paying {amount} on {due_date}.")

That's the whole loop.

Receive, decide, reply. Once it works, every "advanced" feature is just a swap: replace the rule with a model, replace the reply with a tool call, replace the single inbox with a fan-out to a fleet. The shape of the program does not change.

Keep exploring