Files
SuperUser 24de446308 fix: add robust draft deduplication via gmail_list_drafts lookup
The previous approach of checking for DRAFT labels within gmail_read_thread
was unreliable because the Gmail API often excludes draft messages from
thread reads. This caused duplicate drafts across processing runs.

Now explicitly calls gmail_list_drafts at the start of Phase 1 to build
a threadId blocklist, and hard-blocks draft creation for any thread
already in the set.
2026-03-30 07:13:03 +00:00

11 KiB

name, description
name description
email-processor Processes Michael's Gmail inbox in bulk: reads all unread emails, categorizes them by priority and type, summarizes each one, drafts replies in Michael's authentic tone of voice, and collects decisions needed into a Q&A flow. Use this skill whenever Michael mentions: inbox, emails, process my email, check my mail, draft replies, email backlog, catch up on email, respond to emails, what's in my inbox, email triage, morning emails, or any variation of wanting to review and respond to a batch of emails. Also trigger when he asks to process new/unread emails, draft a reply to someone, or wants help managing email communication. Even a simple "emails" or "inbox" should trigger this skill — it's the go-to for anything email-related.

Email Processor

Process Michael Heerkens' Gmail inbox end-to-end: triage, summarize, draft replies, and collect decisions.

Overview

This skill handles the full email processing workflow that Michael uses to stay on top of his inbox as CTO of HelloPrint. The core idea is simple: read everything, understand context, draft replies in Michael's voice, and only interrupt him for actual decisions — never for things you can handle autonomously.

Prerequisites

This skill requires the Gmail MCP tools:

  • gmail_search_messages — find emails
  • gmail_read_message — read individual messages
  • gmail_read_thread — read full conversation threads
  • gmail_create_draft — create draft replies
  • gmail_list_drafts — list existing drafts (critical for deduplication)

If Google Drive MCP is available, use it to review shared documents linked in emails. If Chrome MCP is available, use it to check external tools (Recruitee, HubSpot, etc.) when email context references them.

Workflow

Phase 0: Draft Deduplication Setup (MANDATORY — run this FIRST)

This step is non-negotiable. Run it before reading any emails.

  1. Call gmail_list_drafts with maxResults: 100 to fetch all existing drafts.
  2. Build a blocklist set of threadIds that already have a draft. Extract the threadId from each draft's message object.
  3. Keep this set in memory throughout the entire workflow.
  4. HARD RULE: Never call gmail_create_draft for any threadId that appears in this blocklist. No exceptions.

Why this exists: The Gmail API's gmail_read_thread does NOT reliably include draft messages in its response. Previous versions of this skill tried to detect existing drafts by reading threads — this failed silently, causing duplicate drafts across processing runs. The only reliable method is the explicit gmail_list_drafts lookup.

Phase 1: Inbox Scan

Search for unread emails in the inbox. For every email, read the FULL thread using gmail_read_thread — never just the individual message. This is critical for context: you need thread history to write a good reply, and you need to check whether Michael already sent a reply. For high-volume inboxes (30+ emails), work in batches of 15-20.

For each email, capture:

  • From (name + email)
  • Subject
  • Date received
  • Thread context (is this a reply in an ongoing conversation?)
  • Core content (what do they want/need?)
  • Attachments or shared links (Google Docs, PDFs, etc.)
  • Whether a reply is needed
  • Whether Michael already replied — check the thread for sent messages FROM Michael after the incoming email. If yes, skip.
  • Whether a draft already exists — check the threadId against the Phase 0 blocklist. If yes, skip. Do NOT rely on DRAFT labels in the thread — they are unreliable.
  • Language of the latest incoming message — note the exact language (Dutch/English/other) of the most recent message sent TO Michael. This determines what language the reply must be in.

Phase 2: Categorize and Prioritize

Sort every email into one of these categories:

Priority Category Examples
P1 — Action Required Needs Michael's decision or personal reply Contract decisions, hiring calls, partner negotiations, escalations
P2 — Reply Needed Needs a response but the answer is clear Meeting confirmations, info requests, scheduling, vendor follow-ups
P3 — FYI / Monitor No reply needed, but worth knowing about Team updates, industry newsletters, automated notifications
P4 — Noise Can be ignored or archived Marketing spam, duplicate notifications, expired invites

Automated system notifications (CI/CD alerts, monitoring, cron jobs) get their own subsection. Only flag these if something looks abnormal — a spike in error rates, a failed deployment, an overage alert. Don't waste Michael's time listing 20 "everything is fine" notifications.

Important: Acknowledgment messages like "we're looking into it", "thanks, noted", or "FYI" forwards do NOT need a reply — classify them as P3 even if they're from important contacts. Only classify as P1/P2 if the sender is explicitly asking Michael to do something or provide information.

Phase 3: Draft Replies

Draft a Gmail reply for every P1 and P2 email. This is the most important part — the drafts must sound like Michael actually wrote them.

Before drafting anything, read the tone of voice reference at references/tone-of-voice.md (relative to this skill's directory). This contains Michael's actual writing patterns extracted from 100+ sent emails. Follow it closely.

Mandatory pre-draft checks — run these for EVERY email before creating a draft:

  1. Is this threadId in the Phase 0 blocklist? If YES → do NOT draft. A draft already exists. This check is ABSOLUTE — skip immediately, no further evaluation needed.
  2. Has Michael already replied? Read the full thread. If Michael's most recent message is AFTER the incoming email, do NOT draft. He already handled it.
  3. Does this actually need a reply? Acknowledgments ("we're on it", "thanks", "FYI"), automated notifications, and forwarded-for-info messages don't need replies. When in doubt, classify as P3 and skip.
  4. What language was the incoming message in? Match it exactly. If Lennert writes in Dutch, reply in Dutch. If Dan writes in English, reply in English. Never guess — look at the actual words in the message.

After creating a draft, immediately add the threadId to the blocklist so that no other part of the current run can create a second draft for the same thread.

Key rules for drafting:

  • Use gmail_create_draft with the correct threadId and inReplyTo/references headers so the draft appears in the right conversation
  • Apply the tone of voice guide for every single draft — no exceptions
  • If you don't have enough context to draft a good reply, mark it as [DECISION NEEDED] and add it to the Q&A queue (Phase 4)
  • For scheduling requests, always include Michael's HubSpot link: https://meetings-eu1.hubspot.com/michael-heerkens/
  • Language rule: ALWAYS match the language of the incoming email. For Dutch contacts writing in Dutch, draft in Dutch. For English messages, draft in English. When a thread mixes languages, match the language of the MOST RECENT incoming message. Never default to English when the sender wrote in Dutch.

Draft quality checklist (run mentally for each draft):

  1. Is it shorter than what you initially wrote? Cut more.
  2. Does it start with "Hi [name]," or no greeting? Never "Dear" or "Good morning."
  3. Does it end with "Thanks!" / "Groet," / nothing? Never "Kind regards."
  4. Would Michael actually write this, or does it sound like a template?
  5. Are contractions used? (don't, can't, won't — never formal expansions)
  6. Is the ask/answer in the first sentence?
  7. For Dutch emails: are common abbreviations used naturally? (kwa, mbt, eea, oid, iig, sws)
  8. Is the language correct? Does it match the incoming email's language?

Phase 4: Collect Decisions

Some emails genuinely need Michael's input — a hire/no-hire decision, a contract approval, a strategic direction. Don't guess on these.

Collect all decision points into a numbered Q&A list. For each one:

  • Reference the email (sender + subject)
  • Give the one-sentence context
  • State the specific decision needed
  • If relevant, give a recommendation

Present these to Michael after all processing is done. Ask them one at a time or in small batches. After each answer, immediately create the corresponding Gmail draft.

Phase 5: Summary

After everything is processed, give Michael a brief summary:

  • Total emails processed
  • How many drafts created (and how many skipped due to existing drafts)
  • Any items flagged for follow-up
  • Anything unusual spotted in automated notifications

Keep it to a few sentences. He doesn't need a five-paragraph report.

Handling Specific Email Types

Recruitment emails

  • Check candidate details if Recruitee access is available (via Chrome MCP)
  • For interview scheduling: include HubSpot link
  • For candidate feedback: be honest and direct, matching Michael's style ("the conversation was ok, not a wow")
  • For rejections: direct but respectful

Vendor/supplier emails

  • Check invoices or contracts if mentioned
  • For pricing discussions: flag for Michael's decision
  • For service complaints: draft assertive but professional responses

Automated notifications

  • Group by source (CI/CD, monitoring, billing, etc.)
  • Only surface anomalies — error spikes, failed deployments, overage alerts, webhook failures
  • Summarize the rest as "X notifications from [source], all normal"

Google Docs / shared documents

  • If Google Drive MCP is available, read the document content to understand context before drafting
  • If not available, note that a shared doc was linked and flag it for Michael's review

Re-processing

When Michael says "process new emails" or "check for new ones", search for unread emails that arrived after the last batch was processed. Always re-run Phase 0 (gmail_list_drafts) first to refresh the blocklist — drafts may have been created in a previous run or manually by Michael. Then run the same workflow. If any of the new emails are replies in threads you already drafted responses for, the blocklist will automatically prevent duplicate drafts.

Output Format

For the initial inbox review (if creating a summary document rather than just drafts), organize by priority:

  1. Action Required — items needing Michael's decision
  2. Replies Drafted — emails where drafts are ready in Gmail
  3. Skipped (draft exists) — threads where a draft was already present
  4. FYI Items — notable updates worth skimming
  5. Automated Notifications — only anomalies highlighted
  6. Open Questions — the Q&A list for Michael

But the primary output is always Gmail drafts ready to send — the document is secondary.