A 100% local Gmail inbox analysis and cleanup tool. Helps you identify bulk senders, unsubscribe from newsletters, and clean up your inbox efficiently.
┌─────────────────────────────────────────────────────────────────┐
│ │
│ YOUR DATA NEVER LEAVES YOUR COMPUTER │
│ │
│ • All processing happens locally on your machine │
│ • No external servers, no cloud storage, no tracking │
│ • OAuth tokens stored only in local files │
│ • No analytics, telemetry, or data collection │
│ • Open source - verify the code yourself │
│ │
│ The only network requests are directly to Gmail's API │
│ using YOUR credentials on YOUR machine. │
│ │
└─────────────────────────────────────────────────────────────────┘
- Multi-account support - Connect and analyze multiple Gmail accounts
- Smart aggregation - Group emails by sender and domain
- Bulk actions - Mark as spam or trash entire senders/domains at once
- One-click unsubscribe - Uses List-Unsubscribe headers when available
- Gmail search filters - Focus on promotions, old emails, large attachments, etc.
- Privacy focused - Everything runs locally, nothing is transmitted externally
git clone https://github.com/kiwicro/Gmail-Email-Cleaner.git
cd Gmail-Email-CleanerRequires Python 3.10 or higher.
pip install -r requirements.txtYou need to create your own OAuth credentials. This takes about 5 minutes.
See detailed instructions below
python run.pyOpen your browser to http://127.0.0.1:5000
Since this tool accesses your Gmail, you need to create your own Google Cloud credentials. This ensures YOU control access to YOUR data.
- Go to Google Cloud Console
- Sign in with your Google account
- Click Select a Project (top navigation bar) → New Project
- Enter project name:
Gmail Cleanmail(or any name you prefer) - Click Create
- Wait for creation, then make sure the project is selected
- In the left sidebar, click APIs & Services → Library
- Search for "Gmail API"
- Click on Gmail API in the results
- Click the blue Enable button
- Go to APIs & Services → OAuth consent screen
- Select External and click Create
- Fill in the required fields:
- App name:
Gmail Cleanmail - User support email: Select your email
- Developer contact email: Enter your email
- App name:
- Click Save and Continue
- On the Scopes page:
- Click Add or Remove Scopes
- Find and check these scopes:
https://www.googleapis.com/auth/gmail.readonlyhttps://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.settings.basic
- Click Update
- Click Save and Continue
- On Test users page:
- Click + Add Users
- Enter your Gmail address (the one you want to clean)
- Add any other Gmail addresses you want to use
- Click Add
- Click Save and Continue → Back to Dashboard
- Go to APIs & Services → Credentials
- Click + Create Credentials → OAuth client ID
- Select Desktop app as Application type
- Name it:
Gmail Cleanmail Desktop - Click Create
- In the popup, click Download JSON
- Rename the downloaded file to exactly:
credentials.json - Move the file to:
Gmail-Email-Cleaner/config/credentials.json
- Run
python run.py - Click "+ Add Gmail Account" in the web interface
- A browser window opens for Google sign-in
- Sign in with a Gmail account you added as a test user
- Click through the permissions (you may see "unverified app" warning - this is normal for personal projects, click "Advanced" → "Go to Gmail Cleanmail")
- Grant the requested permissions
- Done! The account appears in your dashboard
- After connecting your account(s), click "Scan All Emails"
- Wait for the scan to complete (progress bar shows status)
- View results by Sender or Domain
Enter filters in the search box before scanning:
| Filter | What it does |
|---|---|
category:promotions |
Marketing emails only |
category:social |
Social media notifications |
category:updates |
Receipts, confirmations |
is:unread |
Only unread emails |
older_than:1y |
Emails older than 1 year |
older_than:6m |
Emails older than 6 months |
larger:5M |
Large emails (5MB+) |
has:attachment |
Emails with attachments |
Combine filters: category:promotions older_than:6m
For each sender or domain, you can:
- View - See all emails from that sender
- Unsubscribe - Open the unsubscribe link (if available)
- Spam - Move all emails to spam folder
- Trash - Move all emails to trash
Use checkboxes for bulk actions on multiple senders at once.
Gmail-Email-Cleaner/
├── config/
│ └── credentials.json ← Your OAuth credentials (you create this)
├── data/
│ └── tokens/ ← OAuth tokens (created automatically)
├── src/
│ ├── gmail_client.py # Gmail API wrapper
│ ├── aggregator.py # Email analysis logic
│ └── app.py # Flask web server
├── templates/
│ └── index.html # Web UI
├── static/
│ ├── style.css
│ └── app.js
├── requirements.txt
├── run.py ← Entry point
└── README.md
| Guarantee | How It's Enforced |
|---|---|
| Data never leaves your machine | Server binds to 127.0.0.1 only - not accessible from network |
| No email content stored on disk | All scan data held in memory, cleared on app restart |
| No analytics or telemetry | Zero external API calls except Gmail API |
| No third-party services | Direct OAuth with Google - no middleman |
| Open source | Full code available for inspection |
This tool requests only the minimum permissions needed:
| Scope | Purpose | What It Allows |
|---|---|---|
gmail.readonly |
Read email headers | Sender, subject, date, snippets - NOT full body |
gmail.modify |
Take action on emails | Move to spam/trash, mark read |
gmail.settings.basic |
Create filters | Auto-trash future emails from senders |
This tool CANNOT:
- ❌ Read full email body content
- ❌ Send emails on your behalf
- ❌ Permanently delete emails (only trash - recoverable for 30 days)
- ❌ Access contacts, calendar, or other Google services
| Protection | Implementation |
|---|---|
| File permissions | Tokens saved with 600 permissions (owner read/write only) on Unix |
| Local storage only | Tokens stored in data/tokens/ - excluded from git |
| No encryption | Tokens are plain JSON - protected by OS file permissions |
| Easy revocation | Delete token files or revoke via Google Account |
| Vulnerability | Protection |
|---|---|
| Path Traversal | Account IDs sanitized - only alphanumeric, underscore, hyphen allowed |
| XSS (Cross-Site Scripting) | All user data escaped before rendering via escapeHtml() and escapeAttr() |
| Malicious URLs | Unsubscribe links validated - only http/https/mailto allowed, localhost blocked |
| Input Injection | All API parameters validated and bounds-checked |
| Session Hijacking | Cryptographically random session keys, regenerated each restart |
| Memory Leaks | Automatic cleanup of old scan progress entries |
| Data | Location | Persistence | Shared Externally? |
|---|---|---|---|
| OAuth credentials | config/credentials.json |
Until you delete | ❌ Never |
| OAuth tokens | data/tokens/*.json |
Until you delete | ❌ Never |
| Email metadata | Memory only | Until app restart | ❌ Never |
| Scan results | Memory only | Until app restart | ❌ Never |
Option 1: Remove from Google Account
- Go to Google Account Permissions
- Find "Gmail Cleanmail" (or your app name)
- Click Remove Access
Option 2: Delete Local Tokens
# Delete all stored tokens
rm data/tokens/*_token.jsonOption 3: Both (recommended for complete removal)
- Revoke access in Google Account
- Delete local token files
- Optionally delete
config/credentials.json
Make sure you:
- Downloaded the OAuth credentials from Google Cloud Console
- Renamed the file to exactly
credentials.json - Placed it in the
config/folder
Your OAuth consent screen needs configuration:
- Go to Google Cloud Console → OAuth consent screen
- Make sure you added the Gmail API scopes
- Make sure you added yourself as a test user
You need to add your Gmail address as a test user:
- Google Cloud Console → OAuth consent screen
- Go to "Test users" section
- Add your Gmail address
Delete the token file and re-authenticate:
- Delete files in
data/tokens/ - Restart the app
- Click "Add Gmail Account" again
This is normal for personal OAuth apps. Click:
- Advanced
- Go to Gmail Cleanmail (unsafe)
This warning appears because the app isn't verified by Google (which requires a review process meant for public apps). Since this runs locally and you created the credentials yourself, it's safe.
python run.py --help
Options:
-p, --port PORT Port to run on (default: 5000)
--debug Enable debug mode (for development)Issues and pull requests welcome! This is a personal tool shared for anyone who finds it useful.
If you find this tool useful, consider supporting the project:
MIT License - Free to use, modify, and distribute.
This tool is provided as-is. Always review what you're deleting before taking bulk actions. Trashed emails can be recovered within 30 days from Gmail's Trash folder.