Let the agent send the report.
You kick off a long job in Codex or Claude, close the laptop, and go to a meeting. Forty minutes later the work is done and it is sitting in a terminal nobody is looking at. It could've been in your inbox.
This is the smallest useful thing you can do with an email API and an agent, and it is the one we use most ourselves. The agent finishes a piece of work and mails the result to whoever asked for it. No dashboard to check, no notification to configure, no webhook to catch.
The reason it's worth writing up isn't the sending. It's what you don't have to do.
The way this usually goes
The normal approach is to give the agent SMTP credentials. A host, a port, a username, a password, sitting in the environment of a process that writes and runs its own code. If you've thought about that for more than a second, you've already stopped.
The second approach is to have the agent write a file, then have something else pick the file up and send it. That works, and now you own a second moving part, a queue, and a class of bug where the report gets written but never sent.
The third is to connect the agent to your actual mailbox over IMAP or the Gmail API. Now a process that writes its own code can read your mail. That's a worse idea than the first one.
What we do instead
Every Waymail region runs an MCP server. Point the agent at it once, and sending becomes a tool the model can call, in the same way it calls a file read. It gets a scoped API key that can send and nothing else, it cannot read your inbox because there is no inbox, and every message it sends is in the delivery log with the key that sent it.
For Claude Code the whole setup is one line:
claude mcp add --transport http waymail https://eu.mcp.waymail.app/mcp \
--header "Authorization: Bearer $WAYMAIL_API_KEY"
After that, the instruction is just English. Put it in CLAUDE.md, or AGENTS.md for Codex, and forget about it:
When a migration finishes, email a summary to the person who asked
for it. Subject line should say what ran and whether it passed.
Send from reports@yourdomain.com using the email_send tool.
That is the integration. There's no client library to install, no SDK version to keep up with, and no code in your repository whose only job is formatting an email.
What the agent actually calls
Under the hood the model calls email_send with something like this. You'll rarely see it, but it helps to know there's nothing clever going on:
{
"from": "Deploy bot <reports@yourdomain.com>",
"to": "tobias@yourcompany.com",
"subject": "Migration 2026-09-20 finished: 4,812 rows, 0 errors",
"text": "Ran in 38 minutes. Full log attached below.\n\n..."
}
If you'd rather the agent didn't choose the wording, give it a template and let it fill the variables. template_manage holds the copy on our side, so changing how the report reads does not mean redeploying anything.
Where this earns its keep
The pattern is always the same. Something takes long enough that nobody waits for it, and somebody needs to know how it went.
- Overnight jobs. The nightly reconciliation emails finance the exceptions, with the numbers already in the body rather than in a link to a dashboard that needs a login.
- Research dispatches. You ask for a competitor sweep or a codebase audit, go and do something else, and read the writeup on your phone.
- Customer-facing work. An agent processes an upload and mails the customer the result directly, from your domain, with your branding. The customer never knows an agent was involved, which is the correct amount for them to know.
- Escalation. The agent only mails you when something needs a human. Silence means it worked, which is the right default for anything that runs nightly.
Keep the key boring
One practical note, because it's the part people get wrong. Give the agent its own API key, scope it to sending, and do not reuse your application's key. If the agent ends up somewhere it shouldn't be, you revoke one key and nothing else stops working.
Our keys can carry an expiry and an IP allow-list, both of which are worth using for anything that runs unattended. An agent key that expires in ninety days is one you'll actually rotate.
Try it in about five minutes. Verify a domain, make a sending key, add the MCP server to your agent, and ask it to email you a summary of whatever it is working on right now. If it doesn't work first time, the delivery log will tell you why rather than making you guess.