email-triage
Skill50 starsChanged 7 days agoMITView on GitHub
Autonomous multi-agent email triage system powered by Google Workspace CLI (gog). Discovers accounts dynamically, prioritizes the default account, delegates each thread to an isolated sub-agent for classification and state management, and safely creates draft replies and applies triage labels without raw CLI execution.
13 other projects use a version of this.
Adopted by
Most recently taken up by
- selamy-labs/agent-skillstheir own version, first seen Nov 8, 2026
- juliasadler/muse-skills-cntheir own version, first seen Oct 17, 2026
- mariagorskikh/open-instincttheir own version, first seen Oct 14, 2026
- Johnwang688/jarvistheir own version, first seen Oct 13, 2026
- Magnus-Gille/claude-skillstheir own version, first seen Oct 11, 2026
- joelhooks/joelclawtheir own version, first seen Oct 8, 2026
Other versions13 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 13
- gnekt/My-Brain-Is-Full-Crew★ 3.9ksame name
- mariagorskikh/open-instinct★ 428same name
- joelhooks/joelclaw★ 65same name
- Magnus-Gille/claude-skills★ 5same name
- MoeenNehzati/famulus★ 4same name
- megandmartin/agent-skills-repo★ 3same name
- juliasadler/muse-skills-cn★ 1same name
- leonardoaraujosantos/my_ai_skills★ 1same name
- huifeideyu-1121/email-triage★ 0same name
- Johnwang688/jarvis★ 0same name
3 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository11 other files it gives its agents.
- agent-loopSkill
- codebase-context-generatorSkill
- code-reviewSkill
- manual-automationSkill
- planning-and-task-breakdownSkill
- project-change-intelligenceSkill
- pull-requestSkill
- refactoringSkill
- slack-cliSkill
- test-driven-developmentSkill
- yt-random-comment-pickerSkill
The file
We split this skill into the rules it gives an agent
9 rules. 0 are common, 4 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 12 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 32
Multi-Account Discovery: All accounts with active Gmail access are detected via gog auth list --json.
- Distinctive: line 39
When a user requests an email triage or inbox sweep, the Orchestrator Agent executes this 4-step protocol:
- Very specific: line 55
Run ./scripts/scan_inbox.py across all accounts (or a specific account if explicitly requested by the user):
- Distinctive: line 59
If specific query or limit is required:
- Very specific: line 67
Prompt: Follow the Sub-Agent Prompt Template below, providing the thread_id, owning account, and subject snippet.
- Distinctive: line 95
If an immediate response is helpful, draft a proposed reply (never auto-send!):
- Distinctive: line 114
When invoking sub-agents from the orchestrator, pass this exact template:
- Very specific: line 148
All scripts support -h / --help and reside in ./scripts/.
- Very specific: line 216
Simulation via Dry-Run: All mutating scripts support --dry-run (-n) to preview actions safely.
“Common” is measured: kept by at least 6 in 10 of the 12 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Email Triage Skill
An autonomous, multi-account email triage system that organizes, classifies, and processes Gmail inboxes. It orchestrates a multi-agent workflow where an orchestrator agent discovers emails across accounts and delegates individual threads to specialized triage sub-agents.
[!IMPORTANT] Strict Tool Policy: No Direct Raw CLI Fallback Under NO circumstances should an agent invoke raw
gogCLI commands directly (e.g.,gog gmail ...). All interactions with Gmail MUST be executed exclusively through the curated Python scripts located in:./scripts/This safeguards credentials, eliminates accidental bulk deletions or unexpected auto-sends, ensures proper character encoding, strips tracking/boilerplate noise, and standardizes multi-account handling.
Architecture & Multi-Account Protocol
Dynamic Account Discovery
The system avoids hardcoded accounts or aliases. It resolves accounts dynamically:
- Default Account Prioritization: The default account is discovered via
gog auth status --json(or theGOG_ACCOUNTenvironment variable) and is always prioritized first. - Account Aliases: Aliases configured in
gogare queried viagog auth alias list --json(e.g.work_account,personal_account). - Multi-Account Discovery: All accounts with active Gmail access are detected via
gog auth list --json. - All-Accounts Scanning: By default,
scan_inbox.pyiterates across all configured accounts in order (default account first). Every thread item is tagged with its owning"account".
Orchestrator Protocol
When a user requests an email triage or inbox sweep, the Orchestrator Agent executes this 4-step protocol:
flowchart TD
A["User Request (Triage Inbox)"] --> B["Step 1: Scan Inboxes<br/>(scripts/scan_inbox.py)"]
B --> C{"Threads Found?"}
C -- No --> D["Report: Inbox Zero Reached"]
C -- Yes --> E["Step 2 & 3: Delegate to Sub-Agents<br/>invoke_subagent for each thread"]
E --> F["Sub-Agent: Read Thread<br/>(scripts/read_email.py)"]
F --> G["Sub-Agent: Classify<br/>(references/classification_rules.md)"]
G --> H["Sub-Agent: Apply Actions & Drafts<br/>(apply_triage.py / draft_reply.py)"]
H --> I["Sub-Agent: Return Thread Summary"]
I --> J["Step 4: Master Triage Report<br/>Synthesize Table for User"]Step 1: Scan Inboxes
Run ./scripts/scan_inbox.py across all accounts (or a specific account if explicitly requested by the user):
python3 ./scripts/scan_inbox.py --jsonIf specific query or limit is required:
python3 ./scripts/scan_inbox.py --query "is:unread in:inbox" --max 15 --jsonStep 2: Delegate Each Thread to an Isolated Sub-Agent
For each thread discovered, launch an independent sub-agent using invoke_subagent:
- Role:
Thread Triage Agent - Prompt: Follow the Sub-Agent Prompt Template below, providing the
thread_id, owningaccount, and subject snippet.
Running threads in isolated sub-agents ensures context window efficiency and eliminates cross-thread hallucination.
Step 3: Thread Sub-Agent Workflow
Each sub-agent runs the following sequence:
- Read Classification Rules: Consult
references/classification_rules.mdandreferences/actions_policy.md. - Fetch Thread Content:
python3 ./scripts/read_email.py <thread_id> --account <account> --json - Classify: Determine category:
SPAM: Unsolicited bulk marketing, phishing, unprompted vendor pitches.REGULAR: Informational notifications, receipts, digests, low-urgency status updates.NEEDS_ATTENTION: Direct requests from colleagues/clients, scheduled meetings, urgent blockers.
- Apply Triage Action:
- For
SPAM:python3 ./scripts/apply_triage.py <thread_id> --account <account> --trash - For
REGULAR:python3 ./scripts/apply_triage.py <thread_id> --account <account> --mark-read --archive - For
NEEDS_ATTENTION:
If an immediate response is helpful, draft a proposed reply (never auto-send!):python3 ./scripts/apply_triage.py <thread_id> --account <account> --add-label "Triage/Action-Needed"python3 ./scripts/draft_reply.py <message_id> --account <account> --body "Proposed draft text..."
- For
- Return Structured Summary: Communicate the result back to the orchestrator.
Step 4: Synthesize Master Triage Report
Once all sub-agents finish, the orchestrator compiles and displays the Master Triage Table:
| Account | From | Subject | Category | Action Taken | Draft Created | Web Link |
| work_account | Alice <alice@co.com> | Architecture Review | NEEDS_ATTENTION | Labeled Triage/Action-Needed | Yes (Draft #1) | Open |
| personal_account | Newsletter <news@info.com> | Weekly Digest | REGULAR | Marked read, Archived | No | Open |
| work_account | Spammer <promo@junk.io> | Boost your leads | SPAM | Moved to Trash | No | Open |
Sub-Agent Prompt Template
When invoking sub-agents from the orchestrator, pass this exact template:
You are a Thread Triage Agent for thread `{{THREAD_ID}}` on account `{{ACCOUNT}}`.
Your goal is to inspect, categorize, and triage this single email thread according to the project's email triage policy.
Mandatory Rules:
1. NEVER run raw `gog` commands directly. ONLY use scripts in `./scripts/`.
2. NEVER send emails. Only create drafts if a reply is warranted.
3. For spam, use `--trash` (safe delete to Gmail Trash). NEVER use `--delete` unless explicitly authorized with `--force`.
Steps to execute:
1. Fetch the thread details:
python3 ./scripts/read_email.py {{THREAD_ID}} --account {{ACCOUNT}} --json
2. Review classification rules:
Read `references/classification_rules.md` and `references/actions_policy.md`.
3. Categorize into SPAM, REGULAR, or NEEDS_ATTENTION.
4. Execute corresponding action using `./scripts/apply_triage.py` (pass `--account {{ACCOUNT}}`).
5. If NEEDS_ATTENTION and a reply is expected, draft a professional response using:
python3 ./scripts/draft_reply.py <message_id> --account {{ACCOUNT}} --body "<draft_text>"
6. Send your final report back to the orchestrator with:
- Account
- Thread ID
- Sender & Subject
- Classification category & 1-sentence rationale
- Actions taken (labels modified, archived, trashed, draft created)
- Web link to threadScript Suite & Flag Reference
All scripts support -h / --help and reside in ./scripts/.
1. scan_inbox.py
Scans Gmail inboxes for matching threads across all accounts or a designated account.
| Flag | Short | Default | Description |
--query | -q | is:unread in:inbox | Gmail search query |
--max | -m | 10 | Maximum number of threads per account |
--account | -a | All accounts | Specific account alias/email (omit to scan all) |
--json | -j | False | Structured JSON output |
2. read_email.py
Reads and decodes an entire email thread, stripping HTML noise, tracking pixels, and boilerplates.
| Flag | Short | Default | Description |
thread_id | (Required) | Gmail Thread ID to read | |
--account | -a | Default account | Specific account alias or email |
--json | -j | False | Structured JSON output |
3. apply_triage.py
Applies label modifications, read status, archiving, or trashing to one or more threads.
| Flag | Short | Default | Description |
thread_ids | (Required) | One or more thread IDs | |
--mark-read | -r | False | Remove UNREAD label |
--archive | False | Remove INBOX label | |
--trash | -t | False | Move thread to Gmail Trash (safe deletion) |
--delete | False | Permanently delete thread (requires --force) | |
--force | -f | False | Confirmation required for permanent deletion |
--add-label | None | One or more labels to add | |
--remove-label | None | One or more labels to remove | |
--dry-run | -n | False | Simulate action without modifying Gmail |
--account | -a | Default account | Specific account alias or email |
--json | -j | False | Structured JSON output |
4. draft_reply.py
Safely creates a draft reply in Gmail (never sends automatically).
| Flag | Short | Default | Description |
message_id | (Required) | Message ID to reply to | |
--body | -b | None | Reply text content |
--body-file | -F | None | File path containing reply text |
--reply-all | -R | False | Reply to all recipients |
--dry-run | -n | False | Preview draft without creating in Gmail |
--account | -a | Default account | Specific account alias or email |
--json | -j | False | Structured JSON output |
5. manage_labels.py
Inspects existing labels and sets up standard triage labels idempotently.
| Flag | Short | Default | Description |
--list | -l | False | List all labels in the mailbox (default action) |
--setup | -s | False | Ensure Triage/Action-Needed, Triage/Waiting, Triage/FYI exist |
--dry-run | -n | False | Simulate setup without creating labels |
--account | -a | Default account | Specific account alias or email |
--json | -j | False | Structured JSON output |
Safety Guarantees & Policies
- No Accidental Send: There is no script to send emails. Only draft creation (
draft_reply.py) is provided. - Safe Deletion: Unwanted or spam messages are moved to Trash via
--trash. Permanent deletion (--delete) requires explicit--force. - Simulation via Dry-Run: All mutating scripts support
--dry-run(-n) to preview actions safely. - Clean Content Extraction: Text extraction strips tracking web bugs (1x1 pixels), CSS styling, script tags, and disclaimers, protecting token context from inflation.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

