Delete years of Gmail clutter in minutes. Free, open-source, privacy-first.
mailtrim
Clean your inbox safely in seconds. Everything goes to Trash. Undo anytime.
Quick Demo
pip install mailtrim
mailtrim setup # connect Gmail or IMAP β guided, ~2 minutes
mailtrim stats # rank your inbox clutter by impact
mailtrim purge # bulk-delete what you picked β goes to Trash
That's the whole workflow. No API key. No subscription. Nothing sent to any server.
Why mailtrim?
- Finds what's actually filling your inbox β ranks senders by storage impact, not just count
- Bulk cleanup in seconds β delete 300+ emails from one sender in a single command
- Nothing is permanently deleted β everything goes to Trash, recoverable for 30 days
- Privacy-first β core commands run entirely on your machine; AI is opt-in and off by default
- Works with Gmail and IMAP β Outlook, Fastmail, iCloud, any IMAP server
Safety Guarantees
| Guarantee | How it works | |---|---| | Trash first | Every delete sends mail to Trash, not permanent deletion | | Full undo | mailtrim undo reverses any operation within 30 days | | No cloud required | stats, purge, undo, setup are 100% local | | AI is optional | AI is off by default β you enable it explicitly | | Dry-run available | purge --json shows what would be deleted before you confirm |
60-Second Quickstart
First time:
pip install mailtrim
mailtrim setup # walks you through Gmail auth and runs your first scan
After setup:
mailtrim stats # see your inbox ranked by clutter
mailtrim purge # interactive: pick senders, confirm, done
mailtrim purge --domain linkedin.com # target one sender directly
mailtrim undo # reverse anything you just did
Already set up? Jump straight to cleanup:
mailtrim quickstart # one command β scans, ranks, shows the safest first action
Example Output
mailtrim stats
Provider: Gmail
β¨ Scan complete β analyzed 2,341 emails across 41 senders in 4s
AI: OFF no data leaves your machine
34% of your inbox is clutter β caused by just 3 senders. 87.4 MB gone in one command.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β TOTAL RECLAIMABLE SPACE β β You can safely free ~87.4 MB (34% of scanned inbox) β β from your top 3 senders Β· Each cleanup takes ~3-5s β β All deletions go to Trash β undo anytime β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Impact Sender Emails Size Oldest Risk 1 100 LinkedIn Jobs 312 44 MB 847d ago Safe to clean 2 82 Substack Weekly 183 26 MB 512d ago Safe to clean 3 29 Shopify Receipts 94 12 MB 203d ago Safe to clean
mailtrim purge
Top Email Offenders (589 emails Β· 82 MB)
# β Sender β Emails β Size β Latest β Sample subject ββββΌββββββββββββββββββββββΌβββββββββΌββββββββΌββββββββββΌβββββββββββββββββββββββββ 1 β LinkedIn Jobs β 312 β 44MB β Apr 03 β 12 new jobs matchingβ¦ 2 β Substack Weekly β 183 β 26MB β Apr 01 β This week: AI is eatingβ¦ 3 β Shopify Receipts β 94 β 12MB β Mar 28 β Your order has shipped
Your selection: 1,2
Move 495 emails to Trash? (undo available for 30 days) [y/N]: y β Moved 495 emails to Trash. mailtrim undo 1 β to reverse
mailtrim undo
Recent operations
#1 Apr 05 495 emails trashed (LinkedIn Jobs + Substack) #2 Apr 03 94 emails trashed (Shopify Receipts)
Restore which operation? 1
β Restored 495 emails.
Privacy
Data never leaves your machine unless you explicitly enable cloud AI.
- All data stored in
~/.mailtrim/β no telemetry, no analytics, no external sync - OAuth token written
chmod 0600β owner read-only stats,purge,undo,setupare fully local β no API key, no network calls- AI mode is shown in every command output:
AI: OFF no data leaves your machine (default)
- AI: LOCAL runs on your machine β nothing sent externally
- AI: CLOUD email data may be sent to Anthropic
- When cloud AI is enabled, a warning appears before any data is sent
- Cloud AI features send only email subjects and 300-character snippets β never full body content
- Google: myaccount.google.com/permissions β remove mailtrim
- Local:
rm ~/.mailtrim/token.json
Commands Overview
Core (no API key needed)
| Command | What it does | |---|---| | mailtrim setup | Guided first-time setup: connect Gmail or IMAP, run first scan | | mailtrim auth | Re-authenticate with Gmail (OAuth browser flow) | | mailtrim quickstart | One-shot scan β shows your safest first cleanup action | | mailtrim stats | Rank all senders by storage impact with confidence scores | | mailtrim stats --since 30d | Scope the scan to the last N days | | mailtrim stats --scope anywhere | Include archived and sent mail, not just inbox | | mailtrim stats --share | Generate a shareable summary (Twitter/plain) | | mailtrim purge | Interactive bulk delete β pick senders, confirm, done | | mailtrim purge --domain example.com | Target one domain directly | | mailtrim purge --sort size | Show largest senders first | | mailtrim protect invoices@bank.com | Protect a sender from future purge operations | | mailtrim undo | List recent operations and reverse any of them | | mailtrim undo 3 | Reverse operation #3 specifically | | mailtrim version | Show installed version (--version / -V also works) | | mailtrim doctor | Health check β auth, Gmail connection, storage, config | | mailtrim sync | Pull inbox into local cache for faster repeated queries | | mailtrim unsubscribe email@sender.com | Unsubscribe via List-Unsubscribe header | | mailtrim privacy | Show exactly what data is stored and what (if anything) leaves your machine | | mailtrim config ai-mode off\|local\|cloud | Set AI mode persistently |
Optional AI (requires mailtrim config ai-mode cloud)
| Command | What it does | |---|---| | mailtrim triage | Classify unread inbox β priority, category, why, suggested action | | mailtrim bulk "archive newsletters older than 60 days" | Natural language bulk operation | | mailtrim avoid | Surface emails you've viewed repeatedly but never acted on | | mailtrim digest | Weekly inbox summary β patterns, action items, one cleanup suggestion |
AI enrichment (local β no Anthropic key)
mailtrim stats --ai-backend ollama --ai-model phi3 # requires Ollama
mailtrim purge --ai-backend llama # requires llama.cpp at localhost:8080
Setup
Gmail (OAuth)
# 1. Get credentials.json from Google Cloud Console (one-time, ~10 minutes)
console.cloud.google.com β New project β Gmail API β OAuth 2.0 Client ID (Desktop)
Download JSON β save to ~/.mailtrim/credentials.json
2. Authenticate
mailtrim auth # opens browser once, stores token locally
3. Run
mailtrim stats
"This app isn't verified" β expected. You're authorising your own app to access your own inbox. Click Advanced β Go to mailtrim (unsafe) to proceed.
IMAP (Outlook, Fastmail, iCloud, self-hosted)
mailtrim setup # choose IMAP at the prompt β enter server, user, password
Setup saves your server, username, port, and folder to ~/.mailtrim/.env. After that, every command works with no flags:
mailtrim stats # reads persisted IMAP config automatically
mailtrim purge # same
mailtrim undo # same
For the password, set it once in your shell environment (never stored on disk):
export MAILTRIMIMAPPASSWORD="your-app-password"
Or mailtrim will prompt securely each time.
Confidence Scores
purge shows a 0β100 score that estimates how safe bulk-deletion is:
| Signal | Weight | |---|---| | List-Unsubscribe header present | 30 pts β sender self-identifies as bulk/marketing | | Age β₯ 180 days in inbox | up to 35 pts β emails sitting >6 months are rarely actionable | | Volume β₯ 50 from one sender | up to 35 pts β high frequency = almost certainly automated |
π’ β₯70 Safe to clean Β· π‘ 40β69 Needs review Β· π΄ Sensitive (bank, health, legal β never auto-suggested)
Scores are heuristics. The 30-day undo exists precisely because no heuristic is perfect.
Configuration
Settings via ~/.mailtrim/.env or environment variables:
| Variable | Default | Description | |---|---|---| | MAILTRIMAIMODE | off | AI mode: off Β· local Β· cloud | | ANTHROPICAPIKEY | (not set) | Required for cloud AI features | | MAILTRIMAIMODEL | claude-sonnet-4-6 | Claude model for cloud AI | | MAILTRIMDRYRUN | false | Preview without executing | | MAILTRIMUNDOWINDOW_DAYS | 30 | How long undo logs are kept | | MAILTRIM_DIR | ~/.mailtrim | Data directory | | MAILTRIM_PROVIDER | gmail | Active provider β set automatically by mailtrim setup | | MAILTRIMIMAPSERVER | (not set) | IMAP server hostname β set automatically by mailtrim setup | | MAILTRIMIMAPUSER | (not set) | IMAP username β set automatically by mailtrim setup | | MAILTRIMIMAPPORT | 993 | IMAP SSL port | | MAILTRIMIMAPFOLDER | INBOX | IMAP folder to scan | | MAILTRIMIMAPPASSWORD | (not set) | IMAP password β never stored on disk, set in your shell |
Set AI mode:
mailtrim config ai-mode off # default β no AI, nothing sent anywhere
mailtrim config ai-mode local # local models only (Ollama, llama.cpp)
mailtrim config ai-mode cloud # Anthropic Claude β requires ANTHROPICAPIKEY
Troubleshooting
mailtrim doctor # diagnoses auth, Gmail connection, storage, config
| Symptom | Fix | |---|---| | "Gmail connection expired" | mailtrim auth | | "Token file not found" | mailtrim auth | | "Cannot write to ~/.mailtrim/" | chmod 700 ~/.mailtrim | | "Rate limit hit" | Wait 60s, retry with --max-scan 300 | | Scan feels slow | mailtrim stats --max-scan 500 | | Not seeing enough senders | mailtrim stats --scope anywhere | | IMAP connection failed | Re-run mailtrim setup to update server/user settings | | Switched to Gmail but still prompted for IMAP password | Re-run mailtrim setup and choose Gmail β this clears stale IMAP settings from .env | | IMAP undo restores fewer emails than expected | Normal on non-Gmail IMAP β UIDs are folder-specific; check Trash manually for any remaining emails | | IMAP purge returns 0 emails moved | Server may lack a Trash folder; run mailtrim doctor to check |
Testing
# Zero credentials required β all AI paths use MockAIEngine
pytest tests/ -v
Contributing
Bug reports and feature requests via GitHub Issues. See CONTRIBUTING.md for development setup.
License
MIT β free to use, modify, distribute.