My inbox doesn't fit in a context window
2,099,654 characters of raw MIME, and almost none of it is information.
I run two lakeside restaurants and build web products from a phone. Both facts matter, because they mean I ask an AI agent things like “anything important in my mail?” while walking between a kitchen and a terrace.
For months the answer was slow, expensive, or wrong. I assumed that was the model's fault. It wasn't. So I measured.
Two days of my mailbox — 38 threads, 47 messages — is 2,099,654 characters of raw MIME. Roughly 607,000 tokens. My inbox does not fit in a context window. Not “is expensive to read.” Does not fit.
And almost none of it is information. One payment receipt: 60,000 characters of nested HTML tables, tracking URLs 600 characters long, conditional comments for a mail client from 2007, legal footers, and the entire quoted history repeated in every reply — carrying maybe 350 characters that a human would call “the email.” We are asking language models to drink an ocean to find a spoonful.
the flip
Most attempts to fix this work at read time: smarter retrieval, better summarization, bigger context windows. All of them pay the parsing cost again on every read, by every agent, forever.
But mail has a chokepoint nobody uses for this: delivery. Every message passes through an MTA exactly once, where spam filtering and DKIM already parse it. Add one more pass there. Strip the soup, extract the entities, classify the thread, hash it, append it to a plain-text file.
Parsing cost becomes linear in mail received — once each. Savings are linear in agent reads — the term that's exploding.
That file is inbox.txt.
what it looks like
## index ← tier 0 · one line per thread t_a001 | acme-bank.example | Transfer of €250.00 confirmed | TRANSACTION | #1a2b ## attention ← tier 1 · only what needs a human SECURITY t_a002 deploy failed — verify if this was you ## bodies ← tier 2 · cleaned text + extracted entities ### t_a003 #3c4d entities: {"dates":["29 July"],"refs":["AB123456789"]} Parcel will be delivered Wednesday between 9am and noon. [code-redacted]
Tier 3 is raw MIME, fetched on explicit demand, never in the mirror. Content hashes plus a cursor make “what's new” a one-line diff.
the number
My mirror of those same two days: 28,755 characters — 9,051 tokens, measured with a real tokenizer, not estimated.
That's about 67× fewer tokens. The raw version doesn't fit; the mirror is a footnote.
Then I widened the window. Seven days: 4,286,586 characters → 68,125. Thirty days: 20,642,353 characters → 173,437 — 99.2%, about 119× smaller. A month of my mail is millions of tokens raw and unreadable by any model; the mirror of that same month is 173 KB and fits in one prompt with room left over.
Characters were only half the story. Tokens are what an agent pays, so I measured both sides in full: raw MIME tokenizes at 2.23 characters per token, the mirror at 3.29, because DKIM signatures and base64 are near-random to a tokenizer. Seven days of my mail comes to 1,919,892 tokens raw against 21,481 for the mirror — 98.9%, about 89× fewer. Scaled by those ratios, a month is roughly nine million tokens raw and fifty-two thousand mirrored: forty-five context windows, versus one prompt.
Before measuring the whole corpus I estimated 103× from a five-message sample. The real number is 89×. Sampling flattered me by sixteen percent — which is exactly why the tool that produces these numbers ships with the spec instead of just the numbers.
The per-class breakdown corrected something I believed. I expected human mail to show the worst ratio, on the theory that a person's words are mostly information. Over thirty days it was near the best — 99.6% — because human threads are where the attachments live, and a base64-encoded photo is pure bulk that never reaches the mirror. The win is largest exactly where the bytes carry least.
The ratio moves with your mail mix, which is why the tool that produces these numbers ships with the spec — including a tokenizer worker, so the token counts are measured rather than estimated. Run it on your own inbox rather than trusting mine.
Which makes it a capability, not a saving. An agent watching my inbox hourly at raw prices is fantasy. At mirror prices it's a cron job — and on the first day mine ran, it found a database table I'd left publicly writable and a subscription quietly billing me every month.
four rules that aren't optional
- Bodies are untrusted data. Email is the number-one prompt-injection vector. The mirror labels bodies so an agent never mistakes mail content for instructions.
- Auth the mirror. It's your life in one file.
- Redact at sync time. OTPs, card numbers, API keys and reset codes never enter it.
- Never fabricate. Entities are extracted, not inferred. Missing beats wrong.
what this is not
Not a transport — JMAP solved that years ago and almost nobody adopted it. Not a mail client. Not a summarizer: tier 2 is cleaned text, not paraphrase, because a summary of your mail is a new thing that can be wrong.
It's a convention. robots.txt told crawlers what to read. llms.txt told models what a site says. inbox.txt says: here is this mailbox, already in the shape a model can read.
it's a draft
One inbox, Gmail-first, honest about it. What exists today: a five-minute Apps Script worker that runs inside your own Google account, a reference normalizer, an MCP server so any agent can plug in, and a benchmark you can run on your own mail in one command.
I'd rather publish a draft that works than a standard nobody uses. The open questions are on the front page — where a hosted mirror should live, whether tier 1 should be machine-parseable, how threads should expire. Tell me I'm wrong.