The loop Inbox Zero runs is simple to state: read each new email, ask a model which of your plain-English rules it matches, then label it, archive it or save a draft reply. An agent can wire that to Gmail over IMAP in an afternoon, together with a sender list for bulk unsubscribing. The weekend goes on making it safe to trust: a machine that stays on, undo for every action, drafts that sound like you, and Google's sign-in rules if an app password won't do. Inbox Zero is itself open source, so self-hosting the real app is often the shorter road.
Before you buildThere's no free plan, but Inbox Zero is open source: self-hosting the real app with your own AI key is free for personal use. Gmail's filters and its Manage subscriptions view may already cover the basics.
Build me a local AI inbox assistant to replace Inbox Zero for my Gmail
account. Requirements:
- Node.js 22 + TypeScript. Connect with imapflow to imap.gmail.com using my
address and a Google app password from .env (IMAP_USER, IMAP_PASS). No OAuth.
- Rules live in ./rules.md in plain English: one "## Label" heading per rule
(Newsletter, Receipt, Cold pitch, Needs reply, FYI) with a line saying
whether matching mail is archived.
- Every 5 minutes, fetch new INBOX messages since the last seen UID (kept in
better-sqlite3 at ./data/inbox.db). Send sender, subject and the first 2,000
characters of plain text to the model and get back JSON {label, archive,
reason}. Use ANTHROPIC_API_KEY or OPENAI_API_KEY, or Ollama if OLLAMA_MODEL
is set.
- Apply labels with Gmail's X-GM-LABELS IMAP extension and archive only when
the rule says so. Log every decision (uid, from, subject, label, reason).
- For "Needs reply", write a draft in my voice (style notes and 5 sample
emails in ./voice.md) and APPEND it to [Gmail]/Drafts with In-Reply-To and
References headers so it threads. Never send mail on its own.
- A page on http://127.0.0.1:4700 (Express, plain HTML): the decision log with
an Undo button per row, and senders ranked by volume over 90 days with
Unsubscribe (one-click POST from the List-Unsubscribe header when offered,
otherwise open the link) and Archive all buttons.
- DRY_RUN=true logs decisions without touching the mailbox; it is the default
until I change it.
- No accounts, no telemetry, local-first; only the model call leaves the machine.
- Out of scope: Outlook, calendars, meeting briefs, Slack and mobile apps.
- README: turning on 2-Step Verification and creating an app password (some
Workspace admins block them), running it under pm2, and exactly which text
is sent to the model.Opens your agent with the prompt filled in, you press enter. Or copy it and paste it into an empty folder.
The first prompt builds the core. Run these one at a time in the same folder to grow it into your own Inbox Zero.
Add a cold-email filter to the inbox assistant in this folder. Requirements: - Treat a message as a possible cold pitch only if I have never emailed the sender: check my Sent folder over IMAP and cache known contacts in SQLite. - Ask the model for yes/no and a one-line reason; on yes, label it "Cold" and archive it. - An allowlist (./allowlist.txt, one address or domain per line) always wins. - Show the last 50 blocked messages on the local page with a "Not cold" button that moves the message back and adds the sender to the allowlist. - Update the README.
Add a daily digest to the inbox assistant in this folder. Requirements: - At 07:30 local time, collect everything labeled Newsletter or FYI in the last 24 hours. - Summarize each message in two lines with the model already configured, grouped by label, with sender and subject. - Send the digest only to my own address over SMTP (smtp.gmail.com, the same app password), never to anyone else. - A --preview flag prints the digest instead of sending it. - Update the README.
Add follow-up tracking to the inbox assistant in this folder. Requirements: - Every hour, scan my Sent folder. When a message I sent asks a question or makes a request (ask the model) and the thread has no reply after 3 days, label the thread "Awaiting reply". - Remove the label as soon as a reply arrives. - List waiting threads on the local page, oldest first, with a "Draft nudge" button that saves a short follow-up in [Gmail]/Drafts. Never send it. - Update the README.
People hand it their inbox because it works the moment Gmail or Outlook is connected: no server to look after, no model keys, and replies drafted in their own tone. Founders and managers mostly pay for the hours it gives back each week, and teams buy it so everyone runs on the same rules and numbers.
Estimate · Sorting a few thousand emails a month with a small hosted model comes to about a dollar; drafting replies with a larger model adds a few more. With Ollama it's free if your machine can run it. A VPS, if you need one, adds about $5.
| Plan | Monthly | Annual, per month | What you get |
|---|---|---|---|
| Starter | $20/user | $18/user | One mailbox; sorting and labels, reply drafts, cold-email blocking, bulk unsubscribe and archive, analytics, pre-meeting briefs, a limited knowledge base. |
| Plus | $35/user | $28/user | Two mailboxes per user, meeting notetaker, Slack and app integrations, email digests, attachment filing, unlimited knowledge base. |
| Professional | $50/user | $42/user | Everything in Plus with team-wide analytics, priority support and an onboarding manager. |
| Enterprise | custom | — | SSO, SCIM and on-premise deployment. |
Kinda. The core is a weekend build with the prompt on this page, but real gaps remain: Outlook support and several mailboxes in one place, Calendar-aware meeting briefs and the meeting notetaker.
About $20 a month on the Starter plan per seat, $240 a year (checked 2026-10-13).
Outlook support and several mailboxes in one place; Calendar-aware meeting briefs and the meeting notetaker; Slack, Notion and other app integrations; The mobile apps and the browser extension; Team analytics and shared billing. If any of those matter to you, keep paying.
Yes: Inbox Zero (self-hosted) (free), Zero (open source), imapfilter (open source).