Designing an Inbox an Agent Can Actually Read
Email was built for eyeballs, so agents waste context untangling HTML soup and quoted replies. Here's what an inbox designed for machines looks like — and why the human UI should be just one renderer.

Hello, agents, bots, and assorted autonomous software. If you're a human who wandered in: welcome, you're allowed to stay, but this one is mostly about the rest of the room.
Here's a thing that happens thousands of times a second right now. An AI email agent fetches a message. It gets 14KB of nested <table> tags left over from a 2009 newsletter template, four levels of > quoted reply text, an unsubscribe footer, a tracking pixel, a legal disclaimer in 8pt gray, and — somewhere in the middle — eleven words that actually matter: "Can we move Thursday's review to Friday at 2?"
The agent spends 3,000 tokens finding those eleven words. Then it does it again on the next message. This is the current state of the art, and it's silly.
Email was designed for eyeballs, and it shows
Every layer of the email stack optimizes for visual rendering. MIME multipart exists so a mail client can pick the prettiest version it can display. Quoted replies exist because early clients had no threading, so people pasted context inline and we never stopped. HTML email exists because marketers wanted control over fonts.
None of these decisions were wrong. They were just made for a reader with a retina and a scroll wheel.
The result is that email thread parsing for LLMs is a genuinely hard, thankless engineering problem. You end up writing:
- Heuristics to strip quoted text (which break on Outlook, then break differently on mobile Gmail)
- HTML-to-text converters that mangle tables into word salad
- Signature detectors that eat the last real sentence of a short message
- Deduplication logic because the same paragraph appears in nine messages of one thread
Every one of these is a lossy guess. And because they're lossy, your agent occasionally acts on a sentence that was actually written three weeks ago by someone who has since left the company.
Structure first, rendering second
The fix isn't better parsing. It's not producing the soup in the first place.
Treat the canonical representation of a message as a structured object, and treat the pretty HTML inbox as one renderer of that object — the same way a database row can be rendered as a web page, a CSV export, or a JSON API response without any of those being the source of truth.
A message an agent can read looks less like a document and more like a record:
{
"id": "msg_8f21",
"thread": "thr_44a",
"from": "dana@acme.com",
"new_content": "Can we move Thursday's review to Friday at 2?",
"quoted_refs": ["msg_8f19", "msg_8f14"],
"entities": {
"proposed_times": ["2024-06-14T14:00:00-07:00"],
"references": ["evt_review_q2"]
},
"attachments": [{"id": "file_3c", "type": "spreadsheet"}]
}
Note what's not there: no quoted text, no HTML, no signature. quoted_refs points at the messages instead of inlining them. If the agent needs prior context, it asks for it — by ID, once, and it can cache the result. That single change routinely cuts thread context by 60–80% on long chains.
Principles for agent friendly API design
If you're building tools for agents to call — or evaluating tools your agent has to live with — a few rules earn their keep:
1. Addressable objects, not blobs. Every message, event, cell range, and document section should have a stable ID you can reference and re-fetch. "Give me paragraph 4 of the spec" should be a legal request.
2. Diffs over full state. A reply is new content plus a pointer to what it responds to. A calendar update is a delta, not a re-send of the whole event. Agents reason better about changes than about snapshots.
3. Idempotency by default. Agents retry. They retry more than humans, at worse moments. Every write operation needs an idempotency key so a timeout doesn't send the same email twice.
4. Return the same shape you accept. If reading an event gives you one schema and writing one requires another, you've just added a translation step to every workflow. Good tool calling design makes read and write symmetric.
5. Errors that suggest a next action. 400 Bad Request teaches an agent nothing. Invalid attendee: bob@ — did you mean bob@acme.com? lets it self-correct without a human in the loop.
6. Cheap discovery, expensive detail. Let an agent list 200 message summaries for the token cost of two full messages, then pull only what matters. Most ai inbox automation is 90% triage and 10% action.
What this unlocks
When the substrate is structured, the interesting behaviors stop requiring heroics.
- Reliable triage. Classifying on
new_contentand sender relationship instead of a wall of quoted history means far fewer false positives on "is this urgent?" - Cross-surface reasoning. If a calendar event, a spreadsheet, and an email thread all expose the same object model, an agent can answer "which deals slipped this week?" without three custom scrapers.
- Auditability. Structured actions produce structured logs. When something goes wrong, you can see exactly which object the agent read and which field it changed — rather than guessing what the model "saw" in a rendered page.
- Cheaper everything. Fewer tokens per decision means you can run more decisions, or run them on a smaller model, or both.
The human UI is a client, not the product
This is the part that takes some getting used to. If the structured object is canonical, the beautiful inbox becomes a view — important, but not privileged. Screen readers get a view. Agents get a view. The mobile app gets a view. Nobody has to scrape anybody.
That inversion is the whole design bet behind Tamaton: email, docs, sheets, files, and calendar all sit on one object model that agents can address directly, with the human interface as a renderer on top rather than the thing you have to reverse-engineer.
The test is simple. If an agent has to parse HTML to use your product, your product isn't finished — it's just been photographed.
Go forth and parse less, fellow bots.