My inbox had 500+ unlabeled emails in Primary. Newsletters mixed with flight confirmations mixed with bill statements mixed with wedding RSVPs. I’d given up on triage and was just searching for things when I needed them.
So I built a system that does the triage for me. Every morning at 9 AM, an AI agent reads my Primary inbox, applies labels to anything new, and quietly learns from any emails I label myself.
This guide walks through exactly how to build it. No code. ~30 minutes of setup.
✅ What you get when it’s working
- Every new email lands in your Primary inbox with the right label already on it
- You glance at the sidebar to find what you need instead of searching
- The system learns — when you manually label an email it skipped, it remembers the rule for next time
- A morning notification telling you what got labeled and what didn’t
It does NOT archive anything, delete anything, or move emails out of your inbox. Pure labeling, fully reversible.
What you’ll need
Two things have to be in place before you start. The system literally won’t work without them.
1. Claude desktop app with Cowork mode.
This is what runs the scheduled task in the background. If you’ve never used Cowork mode, open the Claude desktop app and switch to it — that’s where scheduled tasks live.
2. Both Gmail and Notion connected as MCP connectors.
- Gmail is what gets read and labeled.
- Notion is where the “memory” lives — the rules the system follows, plus the new ones it learns from your manual labels over time.
To check: in Claude, open the MCP registry and confirm Gmail and Notion are both installed and authenticated. If either is missing, search for it, click install, and follow the auth flow. Two minutes per connector.
If you skip this step, the rest of the guide won’t work. Don’t skip this step.
⏱️ Total setup time, end to end: ~30 minutes including the verification run.
The label structure
You can adapt this, but here’s the set that covered ~95% of my inbox. Pick what fits you and drop what doesn’t.
| Label | What goes here |
|---|---|
| Events | RSVPs, meetups, conferences, weddings |
| Travel | Flights, hotels, Airbnb |
| Reservations | Restaurant bookings, salon appointments |
| Personal Finance/Receipts | Purchases, food delivery, online orders |
| Personal Finance/Deposits | Paychecks, e-transfers, dividends |
| Personal Finance/Bills | Bill payments, utility statements, credit card statements |
| Personal Finance/Tax Documents | T4s, T5s, RRSP slips |
| Subscriptions | Spotify, Netflix, SaaS renewals |
| Property | Condo notices, building updates |
| Newsletters & Learning | Substacks, beehiivs, podcasts |
| Account & Security | Verification codes, login alerts, password resets |
| Job Updates | Recruiter outreach, job board notifications, application confirmations |
| (your business label) | Anything related to your side project / newsletter |
A few notes from doing this myself:
- Nest your Personal Finance sub-labels under a parent label so they collapse in the sidebar
- Skip anything too niche — if you only get 2 emails a month for “Driving School”, don’t make a label for it
- Don’t make a “Calendar” label. It overlaps with everything. Events / Travel / Reservations handle calendar-style emails better.
Step 1 — Hand it off to Claude
Here’s where it gets fun. Instead of building any of this yourself, you give Claude one prompt and it does the whole setup: audits your existing labels, proposes a clean structure, creates anything new, builds the Notion memory page, and wires up the scheduled task. All of it.
Open a fresh Claude conversation in Cowork mode and paste the entire prompt below. Edit the seed rules section to match what you’d realistically receive before you send it.
I want you to set up an automated Gmail labeling system for me. Walk
me through this in four phases. Don't skip ahead — pause where I
need to approve something.
PHASE 1 — AUDIT MY EXISTING LABELS
Start by listing the user labels I currently have in Gmail. Then
propose a clean, focused label structure. For each existing label,
give me one of these recommendations:
- Keep as-is
- Rename to: <new name>
- Delete (no longer useful)
- Not sure, leaving alone
Then propose any NEW labels you think I'd benefit from based on what
typically lands in a Primary inbox.
Use this as a reference set, but adapt to what's actually in my inbox:
- Events — Luma RSVPs, meetups, weddings, conferences
- Travel — flights, Airbnb, hotels
- Reservations — restaurants, salons
- Personal Finance/Receipts — purchases, food delivery
- Personal Finance/Deposits — incoming money, paychecks, e-transfers
- Personal Finance/Bills — bill payments, statements
- Personal Finance/Tax Documents — T-slips, CRA, RRSP
- Subscriptions — recurring SaaS, streaming, services
- Property — condo board, building stuff
- Newsletters & Learning — Substacks, beehiivs, course content
- Account & Security — verification codes, login alerts, 2FA
- Job Updates — recruiters, applications, job board
Important: most Gmail connectors can create new labels but can't
rename or delete existing ones. For any rename or delete
recommendations, tell me what to do manually in Gmail UI (right-click
the label → Edit, or Remove label).
Show me the proposal as a table. Wait for my approval before moving
on. If I want changes, adjust and re-propose.
PHASE 2 — CREATE THE NEW LABELS
Once I approve the structure, create any new labels I agreed to in
Gmail. Give each a reasonable color so the sidebar stays scannable.
PHASE 3 — CREATE THE NOTION MEMORY PAGE
Create a new Notion page called "Inbox Labeling Memory" with the icon
📬 and the content below. Update the "Active labels" section to
reflect the final label set we landed on in Phase 1 — don't blindly
copy mine.
---
# How this page works
The daily Gmail labeling agent reads this page every morning before
processing new emails. It applies the rules below in order, then appends
new rules it learns from emails I labeled manually.
I can edit this page anytime to teach the system faster or override
anything.
---
# Rules of engagement
- Conservative by default. If a sender or pattern isn't in the rules
below and the agent can't make a confident judgment, leave the email
unlabeled.
- Primary inbox only. Never label Promotions, Social, or Updates tabs.
- Skip personal correspondence from real humans.
- Skip threads where I've already replied.
---
# Active labels
- Events — Luma RSVPs, meetups, weddings, conferences
- Travel — flights, Airbnb, hotels
- Reservations — restaurants, salons
- Personal Finance/Receipts — purchases, food delivery
- Personal Finance/Deposits — incoming money, paychecks, e-transfers
- Personal Finance/Bills — bill payments, statements
- Personal Finance/Tax Documents — T-slips, CRA, RRSP
- Subscriptions — recurring SaaS, streaming, services
- Property — condo board, utilities at home
- Newsletters & Learning — Substacks, beehiivs, course content
- Account & Security — verification codes, login alerts, 2FA
- Job Updates — recruiters, applications, job board
---
# Sender domain rules (seed)
## Events
- @luma-mail.com → Events
- @calendar.luma-mail.com → Events
- @withjoy.com → Events
- @email.ticketmaster.ca → Events
## Travel
- @airbnb.com → Travel
- @expedia.com → Travel
- @notification.aircanada.ca → Travel
## Reservations
- @resy.com → Reservations
- @opentable.com → Reservations
- @exploretock.com → Reservations
- @fresha.com → Reservations
## Personal Finance/Receipts
- noreply@uber.com → Personal Finance/Receipts
- @doordash.com → Personal Finance/Receipts
- @amazon.ca → Personal Finance/Receipts
## Subscriptions
- @spotify.com → Subscriptions
- @netflix.com → Subscriptions
## Property
- @condocontrol.com → Property
## Account & Security
- Subject contains "verification code", "confirmation code",
"new login", "new device", "2FA", or "password reset"
→ Account & Security
---
# Subject keyword rules (seed)
Use these only when sender rules don't match. First match wins.
- "direct deposit", "deposit received" → Personal Finance/Deposits
- "bill has been paid", "statement is ready" → Personal Finance/Bills
- "itinerary", "flight confirmation", "trip confirmation" → Travel
- "reservation confirmed", "table for", "booking confirmed"
→ Reservations
- "registration confirmed", "registration approved", "RSVP" → Events
- "receipt", "order confirmation", "thanks for your purchase"
→ Personal Finance/Receipts
---
# Learned rules (auto-appended)
The agent appends new rules below this line each morning, based on what
I labeled manually. Format:
[YYYY-MM-DD] sender or pattern → label (observed Nx)
(empty — will populate over time)
---
# Skip list (never auto-label)
- Personal emails from real humans (gmail.com, outlook.com with
name-like addresses)
- Replies in threads I've already responded to
- Emails older than 7 days
---
# Run log
The agent appends a one-line summary each morning, newest at the top.
(empty — will populate after first run)
---
PHASE 4 — CREATE THE SCHEDULED TASK
After the Notion page is created, take its page ID and embed it in
the scheduled task below. Create the task with:
- Task ID: daily-gmail-labeler
- Schedule: 0 9 * * * (every morning at 9 AM local time)
- Notify on completion: true
Task prompt:
---
You are my morning Gmail labeling agent. Run daily at 9 AM. Your job is
to apply labels to new emails in my Primary inbox AND learn from emails
I labeled manually since your last run.
# Operating principles
- Conservative. If unsure, leave unlabeled.
- Label only. Never archive, delete, or move emails.
- Primary tab only. Never touch Promotions, Social, Updates.
- Skip threads that already have a user label.
- Skip threads where I've already replied.
# Step 1 — Read memory page
Fetch the Notion page "Inbox Labeling Memory" (use the page ID embedded
in this task) to get current rules.
Priority: sender rules > learned rules > subject rules > your judgment.
# Step 2 — Learn pass
Query Gmail: category:primary newer_than:2d has:userlabels
For each labeled thread, extract sender domain and label(s). If a
(sender → label) mapping isn't already in the memory page, append it
to the "Learned rules" section. Format:
[YYYY-MM-DD] <sender domain> → <label> (observed 1x)
If a sender already maps to a different label, log a conflict:
[YYYY-MM-DD] CONFLICT: <sender> was → <old>, now also → <new>
# Step 3 — Label pass
Query unlabeled threads:
category:primary in:inbox -has:userlabels newer_than:2d
For each thread: extract sender + subject. Apply Skip list. Then apply
first matching rule in order: sender rules, learned rules, subject
rules, confident judgment. If no confident match, leave unlabeled.
# Step 4 — Run log
Append one line at TOP of "Run log" section:
[YYYY-MM-DD] Processed N — labeled X, unlabeled Y. Learned Z new rules.
# Step 5 — Send summary
Send me a notification under 150 words:
- Count labeled, breakdown by label
- Count unlabeled and rough reason
- Up to 5 new rules learned (with examples)
- Any conflicts needing input
---
Once everything is created, give me:
- The Notion page URL
- The next scheduled run time
- A list of any old labels I need to manually rename or delete in
Gmail UI (since you can't do that yourself)
When Claude finishes, it’ll walk you through the proposal in Phase 1, wait for your approval, then execute Phases 2, 3, and 4 in sequence. The whole thing takes a few minutes of back-and-forth.
If something fails — usually a missing connector permission — Claude will tell you what’s wrong. Re-authenticate Gmail or Notion as needed.
Step 2 — Verify with a test run
Don’t wait until tomorrow morning to find out something’s broken.
Open the scheduled task in Claude (or wherever your task list lives) and trigger a manual run. Watch what it does:
- Did it fetch the memory page successfully?
- Did it find any unlabeled emails to label?
- Did the labels apply correctly?
- Did it send you a summary?
If anything fails, the most common culprits are:
- Wrong Notion page ID — double-check it matches the URL
- MCP connector missing a permission — re-authenticate Gmail or Notion
- Label names don’t match — if you renamed a label in Gmail UI, update the memory page
How the learning loop actually works
This is the part that makes the system get smarter over time. Each morning, before labeling anything new:
- The agent looks at every email that got labeled in the past two days
- For each one, it pulls out the sender’s domain and the label that was applied
- If that (sender → label) pair isn’t already in the memory page, it adds it as a new rule
- Next time an email from that sender arrives, the rule fires automatically
So all you have to do is manually label anything the agent skipped. After a week or two, the skip rate drops dramatically because the memory page has learned your specific senders.
The Notion page is also yours to edit anytime. If a rule is wrong, delete it. If you want to add a rule before the agent learns it, just type it in.
Customization tips from running this myself
Don’t auto-label cal.com / calendar invites. They’re better handled by the actual calendar app. Skip them in the skip list.
Be careful with multi-purpose senders. Wealthsimple sends me deposits, bill payments, dividends, and marketing newsletters from four different subdomains. The memory page needs to differentiate by subdomain + subject keyword, not just the parent domain.
Marketing emails are the hardest call. They’re not really newsletters (you didn’t sign up for content), they’re not transactional, and they’re not security alerts. I left these unlabeled and just unsubscribe when I see them pile up.
Threads with replies are tricky. If I’ve already replied to someone, the thread is “active” and I don’t want it labeled and forgotten. The agent skips these by default.
Receipts vs Subscriptions. A Steam purchase is a receipt. A Steam subscription renewal is a subscription. Subject keywords usually disambiguate, but flag this in your memory page rules if you have a lot of recurring SaaS.
Edge cases worth knowing
- Renaming labels: Most Gmail MCP connectors can create labels but not rename/delete existing ones. If you change your mind on a name, do it in Gmail UI directly.
- Deleted labels: If you delete a label that the memory page references, the agent will throw errors on those emails. Either remove the rule from the memory page or recreate the label.
- First-day overlap: The first run after setup will look at the past 2 days, so you might see things get labeled that were already there. That’s expected — it’s also the chance to spot any rules that are wrong.
- Backlog cleanup: The daily task only looks at the past 2 days. If you want the system to retroactively label your historical inbox, ask Claude to do a one-time backlog pass.
What this replaces
Before: open inbox, scan 30+ emails, mentally categorize, never actually file anything, search later by keyword.
After: open inbox, sidebar shows what category each new email belongs to, archive in bulk by label when needed, find anything in two clicks.
Time saved per day: ~10 minutes. Mental load saved: a lot more than that.