Connection
Folders
iPick the folders to scan. Gmail uses special names like [Gmail]/All Mail, [Gmail]/Trash (may be localized). Connect first to load the list.
Not connected - folders will appear here. Defaults to INBOX.
Add to scan just includes a folder in the list above (creates nothing). Create on server actually creates a new folder - a label on Gmail - on your mailbox (e.g. to use as a move destination).
⚠️ Every action - Run, List senders, Empty folder, Move - applies to the selected folders above. On a folder row, 🗑 deletes it on the server (system folders like Trash/Sent are protected and have no 🗑), while × only removes it from this list.
Manual Cleanup
Choose which messages to act on: paste senders / domains as a Target list, or build a Rule with the query builder. This selects the messages for Count, Run and Export - and, with AI Cleanup, the senders the AI analyzes.
✓ Works with AI Cleanup too: the Target list / Rule selection and the Load from file / Save to file / Clear all buttons and the Load saved Spam addresses flag still apply - AI takes them into account in its search. Leave it empty to have AI analyze the whole selected folder(s).
•
spam@example.com - exact sender address•
*@newsletter.com - that domain exactly, never subdomains•
annoying.com - that domain, plus subdomains if “Include subdomains” is on•
mail.annoying.com - that specific subdomain• lines starting with
# are commentsIn "full" mode,
*@paypal.com = paypal.com without Include-subdomains. The point: with Include-subdomains on, *@paypal.com stays exact while bare domains (e.g. newsletter.com) also catch their subdomains - so you can mix per-entry. ("search" mode is always a substring match.)
one entry per line · reuse across runs
Rules match server-side (substring), so a domain also matches its subdomains and partials - and *@ is not special here. For an exact domain with no subdomains, use a Target list with *@domain.com and scan mode "full".
Counts how many emails match the current filter in the selected folders - makes no changes.
These also follow your filter: Export downloads the matching messages - or the whole selected folder(s) if no filter is set; Import appends into the single selected folder (one only, not more).
.mbox file - same matching as Count (targets/rule, "search" or "full"), or the whole folder when no filter is set. Read-only: it does not mark anything as read. Import appends the messages from a .mbox (or single .eml) file into the one folder you have selected.
Options iThese shape a Target list / Rule run. AI Cleanup decides what to delete on its own and ignores all of them (it always scans server-side, never moves/empties, and handles Gmail Trash automatically). Expunge (in the Run section below) is the exception - it applies to AI Cleanup too.
Below options apply to a Target list / Rule run only - AI Cleanup ignores them.
AI Cleanup and Rule matching both always use a fast server-side SEARCH (subdomains already included), so Scan mode is disabled - it applies only to Target lists.
⚠️ On Gmail, deleting without “move to Trash” does not delete: it only removes the INBOX label, so the message is archived to All Mail (still there, recoverable). To actually delete, tick “Gmail: move to Trash” and run; then, after the run (a separate step), select [Gmail]/Trash and run Empty folder.
Pick an existing folder, or choose ➕ Create new… to make one (a label on Gmail). Tip: leave the Target list / Rule empty to move every message in the selected folders.
⚠️ Will delete all messages in the selected folders (the ones ticked under Folders), not just matches.
✨ AI Cleanup iScores every sender with a heuristic spam score (List-Unsubscribe, unread ratio, send frequency, sender pattern, bulk), then - with a configured model - asks an LLM to judge the senders above your threshold. Generate report only analyzes; later, Run will also delete the confirmed ones. Selecting this disables the other actions and the match list (it looks at all senders).
pip install "imap-cleanup-tool[ai]"
then restart the web UI.
No LLM model configured. You can still Generate report heuristic-only (tick Skip LLM below); Run (which deletes) needs a model. Tip: add a model in the LLM tab for a more precise, LLM-verified analysis.
Advanced: scoring weights (calibrated)
These weights drive the heuristic spam score (the local analysis that runs before any LLM). You can change them, but they were calibrated through testing - it is recommended to leave the default values unless you know what you are tuning.
⚠️ Disabled on Gmail (no effect here): Gmail auto-expunges deleted messages itself. With “Gmail: move to Trash” they go to the Trash - then, after the run, select [Gmail]/Trash and use Empty folder to remove them for good.
Removes the flagged messages permanently. Without it they are only flagged \\Deleted - not every server drops those on its own, so they can linger until expunged. Applies to manual runs and AI Cleanup.
Runs the action chosen above on the selected folders: Manual Cleanup (delete / move / empty folder for the matching messages) or AI Cleanup (heuristic + LLM, then delete the confirmed senders). With dry-run on, “Run” only previews - nothing is changed.
Shows the senders in the selected folders, following the selected filters (Target list / Rule) when one is set, ranked by how many emails each sent - use it to decide what to target.
Downloads the last “List senders” result to your browser’s download folder. Edit the file name if you like; with “ask where to save” enabled, your browser also lets you choose the folder.
Log
New scheduled job
The job connects with a saved profile; folders, match and options come from the Cleanup tab. It runs the CLI on a schedule - different jobs can use different profiles (different accounts).
pip install "imap-cleanup-tool[ai]" then restart the web UI.
When off, this job runs a normal cleanup using the match (targets/rule) and options you set in the Cleanup tab (folders, move/delete, gmail-trash, expunge…). Turn it on for an AI Cleanup job instead.
No non-encrypted model configured. Tick Report only + Skip LLM for a heuristic-only job; for an LLM-verified job add a non-encrypted model in the LLM tab (scheduled jobs can't use encrypted models).
Saved jobs
Runs via the system scheduler (Task Scheduler / cron) - even when this app is closed.pip install "imap-cleanup-tool[ai]" then restart the web UI.
Add / edit a model
The model used by AI Cleanup. Local-first & BYOA (Bring Your Own API key): run a free local model (Ollama) so nothing leaves your machine, or bring your own key for any cloud model (OpenAI, OpenRouter, ...). Powered by litellm, so both use the same form. The key is stored in a local SQLite DB and can be encrypted. ⚠️ Remote models send only sender subjects + stats (never the message body) to that provider - for full privacy prefer a local model.
🔒 This model's key is encrypted. Leave the key blank to keep it (and its passphrase); type a new one to change it.
- ○ at least 8 characters
- ○ a lowercase letter
- ○ an uppercase letter
- ○ a number
- ○ a special character
- ○ both passphrases match
This passphrase is never stored - you'll need it to use the model (encrypted models can't run scheduled jobs).
Configured models
No models yet.
Add / edit an SMTP profile
Outgoing mail server used to send notification emails. The password is stored locally (SQLite) and can be encrypted (an encrypted profile can't run in scheduled jobs). Supports any provider - Gmail, Amazon SES, Outlook, SendGrid, etc.
🔒 This profile is encrypted. Leave the password blank to keep it (and its passphrase); type a new one to change it.
- ○ at least 8 characters
- ○ a lowercase letter
- ○ an uppercase letter
- ○ a number
- ○ a special character
- ○ both passphrases match
This passphrase is never stored - you'll need it to use the profile (encrypted profiles can't run scheduled jobs).
Notifications
Get an email when a cleanup finishes. One profile is active. By default emails are sent for scheduled jobs; you can also enable them for interactive runs. For Gmail accounts the email reminds you to empty the Trash.
Saved SMTP profiles
No profiles yet.
Spam addresses
List-Unsubscribe header. done = already unsubscribed (✓ done). After a bulk Unsubscribe this jumps to manual so you can finish the leftovers by hand.
Senders flagged by AI Cleanup (report or run) for the connected mailbox, with their heuristic spam score and the LLM verdict. Click a column header to sort the whole list. Select rows to remove them from the list, or flag senders as spam - a popup lets you either move one message to the Junk/Spam folder and delete the rest (like Run), or just move all their mail to Spam. It scans the folders selected in the Cleanup tab (just like a run); the popup shows which ones. Moving mail to Spam is the standard "report spam" signal that trains the server to route their future mail to spam. Each connection has its own list. You can also add a sender manually below, and load matching addresses into a Target list from the Cleanup tab. To unsubscribe from newsletters, select senders and click Unsubscribe: it is automatic where possible; the rest only offer a confirmation page (a link ↗ in the Unsub column) - use the Unsub filter (top right) to list just those and open each by hand.
SenderiThe sender's email address (the local-part + domain extracted from the From header). Click to sort. |
ScoreiHeuristic spam score, 0-10. A weighted blend of the signals below, normalized to 10: List-Unsubscribe present, unread ratio, send frequency, Precedence: bulk, and a bulk-looking sender name (noreply@, newsletter@…). Higher = more spam-like. Click to sort. |
MsgsiTotal messages seen from this sender in the scanned folder(s). Click to sort. | UnreadiUnread ratio = messages without the \Seen flag ÷ total. A high ratio means you rarely open their mail. Click to sort. |
Msgs/weekiSend frequency: messages per week, estimated from the span between the oldest and newest Date headers. Frequent senders score higher. Click to sort. |
SignalsiBoolean flags that feed the score: unsub = has a List-Unsubscribe header; bulk = Precedence: bulk; pattern = a bulk-looking sender name (noreply@, newsletter@, no-reply@…). Sorts by how many signals are set. |
LLM verdictiThe model's judgement (only if AI Cleanup ran with a model): delete or keep, with its reason and confidence. Sorts by verdict then confidence. Empty if heuristic-only. | UnsubiHow each sender can be unsubscribed (from its List-Unsubscribe): ✓ done = already unsubscribed (hover for the method, date and result); auto ✉ = automatic, an email sent from your active SMTP profile; auto = automatic, a one-click HTTPS request (no SMTP needed); link ↗ = a confirmation page you open by hand; rescan = header seen but no link stored yet (run a fresh AI report; if it persists, clear the cache and retry); none = no List-Unsubscribe, so it can't be unsubscribed from here. Use the Unsubscribe button on selected rows, or the Unsub filter above to narrow the list. |
|
|---|---|---|---|---|---|---|---|---|
| No spam addresses yet - run an AI Cleanup report first. | ||||||||