I Built a Claude Agent That Files My Email Into Structured Notes Every 10 Minutes
๐Ÿ“ข
← Back to Blog

I Built a Claude Agent That Files My Email Into Structured Notes Every 10 Minutes

John Aspinall · · 9 min read

I forward a lot of email to myself. Supplier updates, a screenshot from a client, a Seller Central notice I want to remember, a half-formed idea I emailed from my phone at 11pm. For years that all landed in the same place: a graveyard inbox folder I swore I'd "process later." I never processed it later.

So I built a Claude agent that does it for me. Every 10 minutes it checks one Gmail label, reads anything sitting there, and writes it into my notes vault as a clean, structured, cross-linked markdown note โ€” with a summary in my own voice, tags, and links to related notes I already had. Then it pulls the label so it never touches that email again.

It has been running unattended on a Mac mini for weeks. This is the build log: what it does, the actual prompt, the three things that broke, what it costs, and how an Amazon operator could point the same pattern at their own inbox.

The problem, with the cost of doing it manually

The manual version of this isn't hard. It's just death by a thousand cuts.

An email comes in worth keeping. To actually make it useful, I'd have to: open my vault, create a note, write a filename that follows my convention, paste the body, strip the email junk, write a two-sentence summary so future-me knows what it is, tag it, and link it to the two or three notes it relates to. Call it three to five minutes of fiddly, low-judgment work per email. The summary and the cross-links are the only valuable parts. Everything else is clerical.

I do this maybe 8-15 times a week. Realistically, I didn't do it โ€” the note creation was annoying enough that the email just rotted in a label. Which meant the cost wasn't three minutes. The cost was that the information effectively disappeared. I'd half-remember that "someone sent me that thing about the freight rate" and never find it.

That's the worst kind of cost: invisible. No line item, no alert. Just a slow leak of stuff you meant to keep.

The build

The stack is deliberately boring. No framework, no orchestration platform, no vector database. Four pieces:

  • Claude Code CLI, headless โ€” claude --print --dangerously-skip-permissions, running a single pass and exiting.
  • The Gmail MCP server โ€” gives the agent search_emails, read_email, download_attachment, and modify_email (to add/remove labels).
  • The vault filesystem โ€” just a folder of markdown files. The agent uses normal Read/Glob/Grep to find related notes and writes the new one with a file write.
  • launchd โ€” macOS's scheduler. One plist fires the job every 10 minutes. (cron works fine too.)

The whole thing is a shell script that pipes one prompt into Claude. The model is Sonnet 4.6 โ€” this is production grunt work, not frontier judgment, so I run the workhorse, not the expensive model. Here's the actual prompt the job runs, lightly trimmed:

You are the unattended email-to-vault ingestion pass. Work entirely
headless: never ask questions, never open a file in an editor, never
auto-move notes into venture folders.

1. Call the gmail search_emails MCP with query "label:vault-inbox". If it
   returns nothing, print exactly "email-to-vault: queue empty" and stop
   without writing anything.

2. For EACH returned message, in order:
   a. read_email to get from, subject, date, and the plaintext body.
   b. Build <slug> = lowercase-kebab of the subject (max ~8 words). If
      "00 inbox/<received-date>-<slug>.md" already exists, append "-" plus
      the last 6 chars of the message id.
   c. If the message has attachments, download_attachment each into
      "00 inbox/_attachments/<slug>/".
   d. Search the vault (Grep/Glob) for 2 to 4 genuinely related notes. Do
      not manufacture links. Pick 1-3 tags and a type from the
      tag-vocabulary note, and a best-guess destination folder.
   e. Write the note with frontmatter (type, tags, source, from, subject,
      received, ingested), a ## Summary in plain operator voice, a
      ## Proposed Routing block, the cleaned ## Original, and ## Attachments.
   f. On a SUCCESSFUL write only: modify_email to remove the "vault-inbox"
      label from that message.
   g. If ANYTHING fails for a message: do NOT remove "vault-inbox"; instead
      add the "vault-error" label and continue. Never delete or lose an email.

3. End by printing exactly one line: "email-to-vault: wrote N note(s), M error(s)".

That's the entire program. The judgment โ€” what's a good summary, which notes are genuinely related, what tags fit โ€” is the model's job. The plumbing is six bullet points.

What broke, and how I fixed it

The first version "worked" in a demo and then quietly misbehaved in three ways once it ran unattended. All three fixes are now baked into the prompt above.

1. It collided filenames. My naming convention is date-slug. Two emails with the same subject on the same day โ€” say two "Re: shipment update" replies โ€” produced the same filename, and the second silently overwrote the first. The fix is the message-id suffix in step (b): if the filename already exists, append the last 6 characters of the message ID. Unique by construction, and still human-readable. This is the kind of bug you only catch in production, because in testing you never send yourself two identical subjects in one day.

2. It could lose email. This was the one that mattered. In the naive version, the agent removed the vault-inbox label as part of "processing" the message โ€” but if the note write failed halfway (a weird character, a permissions hiccup, a network blip on an attachment), the label was already gone and the email was now invisible. Lost. The fix is strict ordering and a safety label: only strip the label after a confirmed successful write, and if anything fails, add a vault-error label instead and move on. Nothing ever gets deleted, and a failure leaves a visible breadcrumb instead of a silent hole. The label removal also doubles as the idempotency guard โ€” a processed email has no label, so the next run can't re-ingest it.

3. It tried to be too helpful. Early runs would do things an unattended job must never do: it "wanted" to move a note into the right venture folder, or it would essentially pause waiting for input that would never come (a headless run has no human). I had to constrain it hard โ€” never ask questions, never open a file, never auto-route. Routing is a proposal written into the note (a ## Proposed Routing block), not an action. The agent's job is to capture and suggest; I decide where things actually live. That line between "propose" and "act" is the single most important design choice in any unattended agent. Capture is safe to automate. Filing things into permanent homes is not โ€” at least not without me in the loop.

The throughline of all three bugs: the failure modes of an unattended agent are completely different from the failure modes of one you're watching. When you're sitting there, you catch the overwrite, you notice the lost email, you answer the question. Headless, every one of those becomes a silent data-loss event. You design for the unattended case or you don't ship it.

Time and cost

The boring part is the good part. Most of the time, the inbox label is empty. The agent calls search_emails, gets nothing, prints queue empty, and exits. That pass costs almost nothing โ€” a tiny number of tokens. It only does real work when there's actually mail to file.

Running every 10 minutes on Sonnet 4.6, with mostly-empty passes and the occasional real ingestion, this lands around $4-6 a month in API usage. Call it the price of two coffees.

Against that: 8-15 emails a week that used to take 3-5 minutes each to file properly โ€” and that I mostly didn't file, so the real comparison is "structured, searchable, cross-linked record" versus "rotting in a label." Conservatively it's saving 45-60 minutes a week of clerical work I'd never actually do. But the honest win isn't the minutes. It's that the information now exists in a form I can find, instead of being technically-in-my-inbox-but-functionally-gone.

There's a second-order benefit I didn't expect: because the agent writes a summary and proposes cross-links, the notes are better than the ones I used to make by hand. I was lazy about cross-linking. The agent isn't. So my vault is more connected now than when I did it myself.

What an operator could replicate

You don't have a "notes vault," but you have the same problem in a different shape: important email that arrives, matters, and then vanishes into the pile. The pattern โ€” a label, an unattended Claude pass, a structured record, never lose the source โ€” ports directly. A few places I'd point it if I ran a $200K/mo Amazon business:

  • Seller Central performance notifications. Auto-file policy warnings, listing suppressions, and account-health notices into a dated, searchable log. When you're proving a pattern to Seller Support six weeks later, you have receipts instead of a frantic inbox search.
  • Supplier and 3PL email. POs, freight quotes, shipment confirmations, delay notices โ€” turned into structured records with the numbers pulled into the summary. Your cost-of-goods history stops living in a thread.
  • Chargebacks and A-to-z claims. Each one filed the moment it arrives, with the relevant order details summarized, so disputes don't depend on you finding the original email under deadline.
  • Buyer messages worth keeping. Recurring complaints or product questions, captured and tagged, become the raw material for a listing fix or an FAQ โ€” instead of evaporating.

Two rules if you build it. First, run the workhorse model, not the frontier one โ€” this is grunt work, and the cost difference compounds across thousands of passes. Second, and this is the one people skip: design the never-lose-it path before you design the happy path. An unattended agent that processes your real email is only trustworthy if a failure is loud and recoverable, never silent. Get the safety net right and the rest is six bullet points and a scheduler.

I spend zero minutes a day filing email now. A $5/month agent does it, files it better than I did, and has never lost a message. That's the whole pitch for this kind of build: not magic, just one annoying, low-judgment loop handed to something that's happy to run it every 10 minutes forever.

Want results like these for your listings?

Book a free visual strategy audit and see exactly what changes your marketplace listings need.

Get Your Free Audit