West Atlas Email Reporter — Case Study
West Atlas LLC — Case Study

Building an autonomous
email intelligence agent

How I replaced 20 minutes of morning inbox triage with a production multi-agent system that reads, prioritizes, and drafts replies — running silently in the background on every boot.

AuthorPatrick Metz, West Atlas LLC
BuiltApril 2026
StackNode.js · Claude API · Gmail OAuth2
StatusProduction — running daily
$0.12
Cost per daily run
<60s
End-to-end runtime
2
AI agents in pipeline
3
SQLite memory tables
20
Emails processed daily

Inbox triage is expensive attention tax

Running a consulting business means your inbox is a mix of client messages, platform notifications, vendor emails, security alerts, and newsletters — all arriving at the same priority level. Every morning I was spending 15–20 minutes manually sorting what needed a reply, what was urgent, and what could be ignored.

I wanted a system that could do that triage for me, remember patterns over time, and hand me pre-written replies for the emails that actually needed one. Not a filter. Not a label. A reasoning agent.

Before
20 minutes of manual triage every morning
Urgent items buried under newsletters
No context — is this the 3rd message this week?
Every reply written from scratch
No record of what came in or when
After
Digest waiting in inbox on every boot
Action items surfaced with priority reasoning
Trend detection — "3rd Upwork message this week"
Draft replies ready to copy and send
SQLite memory persists sender history daily

A true multi-agent pipeline

The system uses two Claude models in sequence. The sub-agent handles focused single-email triage in parallel across all emails simultaneously. The orchestrator handles cross-email reasoning, memory context, and final HTML generation — working from clean JSON summaries rather than raw email bodies.

Trigger
Windows Service — auto-starts on boot
Registered via node-windows · survives reboots · managed via manage.ps1
Data fetch
Gmail API (OAuth2) — last 24 hours
Dedup check against processed_messages table · skips already-seen message IDs
↓ parallel calls via Promise.all
Sub-agent — Haiku
Email #1 → structured JSON
priority · keyPoints · suggestedReply · category
Sub-agent — Haiku (x19)
Emails #2–20 in parallel
All fired simultaneously · ~8s total for 20 emails
↓ structured JSON summaries
Orchestrator — Sonnet — tool-use loop (3 iterations)
read_memory → review → write_memory → HTML digest
Applies trend context · refines priorities · generates mobile-optimized HTML
Delivery
Nodemailer → Gmail SMTP
HTML email with token usage footer · marks messages processed in SQLite

Why two models instead of one

The instinct is to use one model for everything. The better move is to give each model one job it's genuinely good at. Haiku is fast and cheap — perfect for the focused, repetitive work of summarizing a single email into structured JSON. Running 20 in parallel takes about 8 seconds total and costs $0.022.

Sonnet handles the harder job: reasoning across all summaries simultaneously, applying memory context from past runs, detecting patterns, and generating coherent HTML. Giving it clean JSON instead of raw email bodies makes it significantly more reliable — and the orchestrator's output improves over time as the memory layer accumulates.

ModelRoleWhy this modelCost/run
claude-haiku-4-5Sub-agent — one per email, parallelFast, cheap, focused single-email triage~$0.022
claude-sonnet-4-6Orchestrator — tool-use loopCross-email reasoning, memory, HTML generation~$0.097

The agent gets smarter over time

Three SQLite tables persist across every run. The orchestrator reads trend context before analyzing each day's emails — so by week two it knows that certain senders are recurring clients, that a Google security alert is worth flagging differently than a newsletter from the same domain, and that an Upwork message is the third this week.

TablePurposeKey fields
digestsOne row per day — daily summary historydate (unique), email_count, urgent_count, summary
sendersCategorized sender records with running countsemail (unique), name, category, notes, count, last_seen
processed_messagesDeduplication log — prevents double-processingmessage_id (PK), thread_id, digest_date

What lands in the inbox

West Atlas Daily Digest — Saturday, April 12, 2026
West Atlas LLC — Daily Email Digest
Saturday, April 12, 2026  ·  20 emails reviewed
Quick summary
·20 emails in — 3 need action, 1 urgent
·Inbound client inquiry requires reply today
·3rd Upwork message this week from same contact
Action required
Upwork — Client Inquiry
Question about project scope and timeline
HIGH
Draft reply:
Hi — thanks for reaching out to West Atlas. I'd love to learn more about your project. Are you available for a 20-minute call this week?

Patrick Metz | West Atlas LLC
Google — Security Alert
New sign-in detected on your account
VERIFY
FYI only
StripeInvoice #1042 paid — $2,400
UpworkProposal viewed by client
NewsletterWeekly digest — no action needed

What it actually costs to run

The entire system runs on pay-as-you-go API pricing. No subscriptions, no infrastructure costs beyond the machine it runs on. At 20 emails per day the economics are essentially free.

Sub-agent (Haiku) per run$0.022
Orchestrator (Sonnet) per run$0.097
Total per run~$0.12
Monthly 30 runs~$3.57
Annual~$43

What I'd tell someone building this

01
Deduplicate from day one
Without a processed_messages table, every restart re-processes the same emails and corrupts your memory layer. I added this after the first production bug. It should be in the schema from the start.
02
Specialization beats consolidation
The instinct is to use one model for everything. The better move is to give each model one focused job. Haiku doing triage and Sonnet doing synthesis produces better output than Sonnet doing both — and costs less.
03
Unicode will crash your API calls
Gmail snippets contain emoji, special characters, and lone Unicode surrogates that are valid in Gmail but break JSON serialization when sent to the API. A sanitize function is non-optional.
04
The system prompt is the product
The quality of the digest is almost entirely determined by how well you specify output format, priority rules, and tone. Swapping models has a fraction of the impact of improving the system prompt.
05
node-windows beats PM2 on Windows
PM2 requires the terminal to stay open or complex startup scripts. node-windows registers a true Windows Service that survives reboots natively. One setup command, no maintenance.

What gets built next

The agent already has the better brain. What it needs now are better bones — more reliable parsing, schema validation on model outputs, and priority reasoning that explains itself. The commercial path is a managed service for solo operators and small agencies who want this running for their inbox without touching code.

Near term
HTML email body parsing (not just plain text)
Zod schema validation on sub-agent output
Priority reasoning explanation in digest cards
Configurable Gmail filters (inbox only, no promotions)
Longer term
Web search to research unknown senders
Multi-inbox support (Outlook via Graph API)
Human feedback loop for priority corrections
Multi-user managed service deployment