Every message,routed.
Rules sort your Gmail every hour. A model reads only the mail no rule can place, requests become Google Tasks, and nothing moves until you say so.
Open source · MIT · Gmail · Copilot CLI or Claude Code
| Rules | routed | 27 |
|---|---|---|
| First pass | read | 10 |
| Escalation | read | 3 |
| Google Tasks | created | 4 |
| Waiting for you | held | 1 |
Rules first. The model last.
Searching, tagging what a rule can match, sweeping old notifications, syncing finished tasks and writing the report are plain code. A model is called only for human mail that needs interpreting, and only after the rules have had their turn.
Sync tasks
Every run starts here: finished Google Tasks archive their thread, if the tag says so.
Rules
Your Gmail queries in
rules.json, in order. First match wins; the message never reaches a model.Sweep
Per tag, archive or mark read what is done: resolved alerts, yesterday's newsletters. Starred mail is left alone.
First pass
What is left goes in batches of 25, as untrusted data, to a small, cheap model.
Escalation
Only low-confidence cases go to a stronger model, with a bounded slice of the body, up to ten per run.
Validate, then write
Plain code checks IDs, tags, task policy and dates, rechecks the inbox, then writes tasks first and labels second.
Your nine o'clock inbox.
At eight, the demo inbox holds 38 unread messages. Thirty-seven arrived this week: requests, invites, alerts, pull requests, newsletters, promotions. The 38th is an older thread outside the seven-day window, so the run leaves it alone. One applied run later, every message from this week carries a label except one that waits for you, and four requests are tasks with due dates.
- 11messages archived by sweeps: a resolved alert, older pull-request noise and newsletters, three promotions.
- 4requests turned into tasks, with the deadline the mail actually states, or two business days when it states none.
- 1sender proposed as a new rule, three bulk webinar mails from the same address. You approve it; the runner never edits your rules.
- 1"Are you around on Friday?" Neither model was sure, so it stays untagged in your inbox.
The express spur stays dark.
The model is the expensive branch line, and most hours it carries nothing. Classifications are cached for the day, so applying a reviewed dry run costs no second call, and an hour with nothing new to read launches no model at all. The classifier is the CLI you already pay for: the GitHub Copilot CLI or Claude Code.
| Run | What happened | Model calls |
|---|---|---|
make classify | Dry-run preview27 routed by rules; 10 sent to the first pass, 3 of them escalated. Nothing in Gmail changes. | 2 |
make apply | Applied runReuses the preview's validated decisions: labels, sweeps and four tasks written. | 0 |
| Next hour | Scheduled runNothing new. The one message waiting for you is not re-sent today. | 0 |
| Task done | Scheduled runYou ticked "Approve the Q4 hiring plan"; its thread is archived. | 0 |
state/usage.jsonl; make usage totals it. In the demo, a stand-in CLI estimates tokens from text length.What a month costs
- Rules and cache resolve everything
- $0
- Two small-model calls a day
- $0.15
- Twelve small-model calls and one escalation a day
- $2.46
Illustrative estimates over 22 workdays at Copilot rates, from the project's cost guide. Not caps: your real numbers come from make usage.
Nothing moves without your say-so.
Every command that would change your mailbox is a preview until you add --apply. The model proposes; plain code decides whether the proposal is even allowed.
Dry run by default
make previewandmake classifychange nothing and write the exact plan tostate/plan.json.make applyasks before it touches mail.Journalled, undoable
Applied label changes and trash go to a journal;
triage.py undoreverts the last batches. Nothing is ever sent, forwarded or permanently deleted.Validated before written
Exactly the requested IDs, known tags, allowed tasks, real dates. Anything else and the batch is refused.
Unsure stays in the inbox
No "FYI" fallback, no automatic archive. Unresolved mail is listed in
summary.jsonand left for you.Starred mail is protected
Sweeps skip starred messages by default, through a guard you can edit.
Least privilege, local state
Only the Gmail-modify and Tasks scopes. The model runs with no tools, in a temporary folder, mail on stdin. Everything else stays in a
state/folder only you can read.
The film.
Narrated with a synthetic voice, subtitled. Every message shown is from the invented demo mailbox. The interactive version with chapters.
Board with one command.
make setup installs what is missing with Homebrew, creates your private rules and state, signs you in to Google (Gmail and Tasks only) and to your classifier CLI, then runs the tests and a read-only preview. It is safe to re-run, and it never changes mail or installs the schedule.
- Set up, then check.
make setup-previewprints every command first;make doctorticks off every install and login. - Personalise your rules.
The
mail-setupskill, in Copilot or Claude Code, reads at most 200 recent messages, read-only, and proposes sender rules for you to approve. - Preview, apply, schedule.
make preview, thenmake applywhen it looks right, thenmake schedule-install: weekdays, hourly, 08:00 to 19:00.
# a Mac with Homebrew $ git clone https://github.com/mmornati/ai-email-assistant.git $ cd ai-email-assistant $ make setup # or: bash scripts/setup-macos.sh --cli claude $ make doctor $ make preview # read-only, no model # or try it with no account at all $ make demo
What it won't do.
Said as plainly as what it does.
- Gmail onlyThrough the Google Workspace CLI, with Google Tasks for the to-do side.
- Your CLI, your subscriptionClassification runs through the GitHub Copilot CLI or Claude Code; you need one of them.
- Polling, not pushEach run looks at a time window (7 days by default); there is no history cursor.
- macOS for the scheduleThe schedule is a launchd calendar job; the Mac must be on and you logged in.
- Confidence is not calibratedIt is what the model reports. Review real output before trusting unattended runs with important mail.
- No silent cleanupThe starter rules archive and trash nothing. Every cleanup action is one you add.