Install
openclaw skills install inbox-cleanupIMAP bulk email triage — pattern-based delete/archive with dry-run mode. Use when: cleaning up large email inboxes, bulk-deleting emails from specific sender...
openclaw skills install inbox-cleanupBulk IMAP email triage: classify → delete/archive by sender domain, subject keywords, or custom patterns.
Use inbox-cleanup when:
Do NOT use inbox-cleanup when:
Boundary with other skills: This skill does NOT read email content for decision-making (no NLP/LLM classification). It matches on sender domain and subject string patterns only. For content-aware triage, a different approach is needed.
Some email categories look like noise but must be preserved:
Safeguard pattern: Add these sender domains to leave_domains in your config. When in doubt, archive instead of delete.
leave_domains:
- ato.gov.au # Australian Tax Office
- myob.com # Accounting
- godaddy.com # Domain registrar
- cloudflare.com # DNS / hosting
- stripe.com # Payments
- paypal.com # Payments
- no-reply@apple.com # Apple receipts
scripts/inbox_cleanup.py — main cleanup script (dry-run by default)scripts/config_example.yaml — pattern config template# Step 1: Always dry-run first — no changes made, just a preview
python3 scripts/inbox_cleanup.py --config my_patterns.yaml --dry-run
# Step 2: Review the output. If it looks right:
python3 scripts/inbox_cleanup.py --config my_patterns.yaml
When dry-run completes, you'll see output like:
[DRY RUN] Would delete 142 emails from github.com
[DRY RUN] Would delete 38 emails from slack.com
[DRY RUN] Would archive 17 emails from notion.so
[DRY RUN] Would archive 9 emails matching keyword "newsletter"
[DRY RUN] Skipping 3 emails from leave_domains (stripe.com, paypal.com)
─────────────────────────────────────────────
Total would-delete: 180
Total would-archive: 26
Total skipped (leave_domains): 3
If the numbers look wrong (e.g. 0 matches when you expected hundreds), check:
IMAP_HOST / IMAP_PORT / IMAP_USER env vars are setnoreply.github.com ≠ github.com)IMAP_HOST=127.0.0.1 # IMAP server host (127.0.0.1 for Proton Bridge local proxy)
IMAP_PORT=1143 # Port: 993 = direct SSL, 1143 = Proton Bridge STARTTLS
IMAP_USER=you@example.com # Your IMAP login username
IMAP_PASSWORD=yourpassword # IMAP password (use op read for 1Password)
IMAP_STARTTLS=true # true = STARTTLS upgrade after connect (Proton Bridge); false = SSL-from-start
IMAP_SKIP_CERT_VERIFY=true # true = accept self-signed cert (required for Proton Bridge)
ARCHIVE_FOLDER=Archive # Exact IMAP folder name to move archived emails into (must already exist)
Or use --imap-* CLI flags. See python3 scripts/inbox_cleanup.py --help.
# Sender domains whose emails should be permanently deleted
delete_domains:
- github.com # GitHub notifications (Issues, PRs, Actions)
- noreply.github.com # GitHub no-reply (different subdomain — list both if needed)
- slack.com # Slack digest/notification emails
# Sender domains whose emails should be moved to Archive (not deleted)
archive_domains:
- notion.so # Notion share notifications
- coinbase.com # Crypto price alerts
# Subject line keywords — emails matching any of these are archived (case-insensitive)
archive_keywords:
- newsletter # Matches "The Weekly Newsletter", "Newsletter #42", etc.
- digest # "Daily Digest", "Weekly Digest"
- weekly roundup # Exact substring match
# Subject line regex patterns — emails matching any of these are deleted
# Note: patterns are Python re.search() — anchored with ^ if you want start-of-line match
delete_subject_patterns:
- "^\\[GitHub\\]" # Subjects starting with "[GitHub]"
# Sender domains that should NEVER be touched — overrides all other rules
# Add banks, payment processors, auth providers, registrars here
leave_domains:
- important-bank.com
- stripe.com
- paypal.com
UID FETCH/UID STORE to
avoid message-renumbering bugs when messages are deleted mid-batch.--no-dry-run to apply.--one-at-a-time for reliable UID tracking.Credentials via env vars or 1Password:
# Via env vars
export IMAP_PASSWORD="$(op read 'op://Vault/Email Account/password')"
python3 scripts/inbox_cleanup.py --config patterns.yaml
Running live without a dry-run first
--dry-run first and review the countsDomain mismatch — listing github.com but emails come from noreply.github.com
github.com AND noreply.github.comARCHIVE_FOLDER doesn't exist in the mailbox
Proton Bridge not running when script executes
leave_domains not populated
leave_domains, the script will happily delete emails from payment processors, banks, and auth providers if they match another ruleleave_domains before any live runSTARTTLS vs SSL confusion
IMAP_PORT=993, IMAP_STARTTLS=falseIMAP_PORT=1143, IMAP_STARTTLS=true, IMAP_SKIP_CERT_VERIFY=true