muammar-yacoob/GMail-Manager-MCP
FreeNot checkedManage your Gmail inbox in natural language: bulk delete promotions and newsletters, organize labels and get inbox insights.
About
Manage your Gmail inbox in natural language: bulk delete promotions and newsletters, organize labels and get inbox insights.
README
Gmail Manager MCP
🧹 Clean your inbox • 🏷️ Organize with labels • 🗑️ Bulk delete emails
npm MCP Server MIT GitHub Sponsors Report Bug GitHub Stars

✨ What It Does
Gmail Manager MCP provides direct access to your Gmail inbox through the Model Context Protocol, allowing you to:
Feature |
Description |
|---|---|
| Find emails by sender, subject, date, or any Gmail query | |
| Get insights about your email patterns and volume | |
| Read the full content of an email | |
| Create and apply labels to categorize emails automatically | |
| Remove old newsletters, notifications, and spam efficiently | |
| List, search, create and update events, RSVP, and find times everyone is free | |
| Attach local files to drafts, download attachments, or file them into Drive |
[!IMPORTANT] Upgrading from a version before calendar or Drive support? Google cannot add scopes to a token it has already issued, so your saved credentials keep working for mail while calendar calls and
save_attachment_to_drivefail with a permissions error. Enable the Calendar and Drive APIs and add their scopes as below, then re-authenticate once:npx @spark-apps/gmail-manager-mcp@latest authRunning a local checkout instead of the published package? Re-authenticate with the build your client actually loads, or you will re-consent against whichever version npm is serving and see the same error:
node /path/to/GMail-Manager-MCP/dist/index.js auth
🚀 Quick Setup
📋 Prerequisites: Get Gmail Credentials 🗝️
🔑 Required before any installation
- Create New Project 📁
- Enable all three APIs: Gmail 📧, Calendar 📅 and Drive 📁
- Create OAuth client ID (Desktop app type) 🔐
- Download as
gcp-oauth.keys.json📥 - Navigate to Data access → Add or remove scopes → add all three:
https://mail.google.com/,https://www.googleapis.com/auth/calendarandhttps://www.googleapis.com/auth/drive.file🔓 - Navigate to Test users → Add your Google email 👤
📁 Where to put gcp-oauth.keys.json:
For Windows users in WSL:
# Copy from Windows to current directory
cp /mnt/c/Users/YourUsername/gcp-oauth.keys.json ./gcp-oauth.keys.json
General locations:
- Current directory:
./gcp-oauth.keys.json(works everywhere) - Home directory:
~/gcp-oauth.keys.json(for npx usage) - Custom path: Set
GMAIL_OAUTH_PATHenvironment variable
📥 Installation
Claude Code, one line, nothing to install first:
claude mcp add gmail-manager -- npx -y @spark-apps/gmail-manager-mcp@latest
Add -s user to make it available in every project instead of just this one.
Then authorise your Google account once:
npx @spark-apps/gmail-manager-mcp@latest auth
That needs an OAuth keys file. See Quick Setup above if you have not made one yet.
📦 Other clients, or a global install
The server runs straight from npm, so npx is enough for any MCP client (see Configure MCP Client for the JSON form):
npx -y @spark-apps/gmail-manager-mcp@latest
Prefer it on your PATH as gmail-manager:
npm i -g @spark-apps/gmail-manager-mcp
🏠 Clone and build locally (Safer 🛡️)
git clone https://github.com/muammar-yacoob/GMail-Manager-MCP.git
cd GMail-Manager-MCP
npm install
💻 Terminal Usage
🖥️ Quick Commands
# Install globally
npm i -g @spark-apps/gmail-manager-mcp
# Setup authentication (run this first)
npx @spark-apps/gmail-manager-mcp@latest auth
# Test MCP server (for debugging)
npx @modelcontextprotocol/inspector npx @spark-apps/gmail-manager-mcp@latest
⚙️ Configure MCP Client
🔧 Required for MCP client integration
Add to your MCP client config file (Claude Desktop example):
- Windows
%APPDATA%\\Claude\\claude_desktop_config.json - macOS
~/Library/Application Support/Claude/claude_desktop_config.json - Linux
~/.config/Claude/claude_desktop_config.json
📦 For NPM Install:
{
"mcpServers": {
"gmail-manager": {
"command": "npx", "args": ["@spark-apps/gmail-manager-mcp@latest"],
"env": { "GMAIL_OAUTH_PATH": "C:\\path\\to\\gcp-oauth.keys.json" }
}
}
}
For Local Development:
{
"mcpServers": {
"gmail-manager": {
"command": "node", "args": ["C:\\path\\to\\GMail-Manager-MCP\\dist\\index.js"]
}
}
}
🛠️ Available Tools
🔧 View All Available Tools
📬 Reading
| Tool | Description |
|---|---|
search_emails |
Search using Gmail query syntax |
read_email |
Full content of one email |
get_thread |
Every message in a conversation, oldest first |
🧹 Cleaning up
| Tool | Description |
|---|---|
trash_emails |
Move to Trash, recoverable for 30 days. Prefer this |
untrash_emails |
Pull messages back out of Trash |
archive_emails |
Remove from inbox, keep everything else |
mark_emails |
Mark read or unread |
delete_email / batch_delete_emails |
Permanent, bypasses Trash, cannot be undone |
🏷️ Labels
| Tool | Description |
|---|---|
list_labels |
List all labels |
create_label |
Create a label, or return the existing one if the name is taken |
delete_label |
Delete a label |
apply_label / remove_label |
One message |
batch_apply_labels / batch_remove_labels |
Many messages, throttled and retried |
⚙️ Rules & unsubscribing
| Tool | Description |
|---|---|
list_filters |
Filters (rules) currently on the account |
create_filter |
Set a rule that applies to mail arriving from now on |
delete_filter |
Remove a filter |
get_unsubscribe_info |
Read a sender's List-Unsubscribe link, without clicking it |
unsubscribe_email |
Opt out of a mailing list via the sender's own one-click endpoint |
✍️ Drafts
Everything here writes to Drafts. Nothing is delivered. See Sending below.
| Tool | Description |
|---|---|
create_draft |
Compose to any To/Cc/Bcc with subject, body and attachments. Not tied to a thread |
create_reply |
Draft a threaded reply. Recipient can be overridden with to/cc/bcc |
update_draft |
Edit a draft in place, keeping its ID and URL. Pass only the fields you are changing |
delete_draft |
Throw a draft away, so a superseded version cannot be sent by mistake |
list_drafts |
Every draft with its ID, recipients, subject and snippet |
Three things these do that are worth knowing about:
Every draft reports the recipient Gmail actually stored, read back from the saved message rather than echoed from the request. A wrong address is visible before anyone presses send, which is the only moment it can still be fixed.
A draft addressed only to yourself is called out. create_reply used to
answer the From header unconditionally, so replying to your own sent mail
resolved the recipient to your own address: the draft looked perfectly correct
and would have gone nowhere. Replying to a message you sent now answers its
original recipients instead, and says which rule it applied.
update_draft merges rather than replaces. Gmail's API has no partial
update, so the underlying call rewrites the whole message; the tool reads the
draft first and keeps every field you did not pass, attachments included.
📎 Attachments
| Tool | Description |
|---|---|
list_attachments |
Attachments on a message, with the IDs needed to fetch them |
download_attachment |
Save one to a local path. Missing directories are created |
save_attachment_to_drive |
Upload one straight to Google Drive, optionally into a folder |
Outgoing attachments are local file paths (~ is expanded), assembled into a
proper MIME multipart message and sent base64url-encoded via raw.
Gmail's 25 MB ceiling applies to the encoded message, and base64 adds about a third, so the real limit is roughly 18 MB of actual files. Oversized attachments are refused up front, with the per-file arithmetic, rather than being uploaded and rejected by Google with an opaque 400.
save_attachment_to_drive needs the Drive scope. See Scopes.
📤 Sending
Off by default. This server composes; a human sends. A draft can be read, corrected or thrown away; a sent message cannot, because SMTP has no recall.
To enable delivery, set GMAIL_ENABLE_SEND=1 in the server's environment and
restart your MCP client:
"env": { "GMAIL_ENABLE_SEND": "1" }
That adds three tools:
| Tool | Description |
|---|---|
send_email |
Compose and send immediately |
send_draft |
Send an existing draft |
resend_email |
Send a fresh copy of a sent message (does not recall the original) |
📅 Calendar
| Tool | Description |
|---|---|
list_calendars |
Calendars this account can access |
list_events |
Events on a calendar, optionally in a time range |
search_events |
Find events by keyword |
get_event |
One event in full, including RSVPs |
create_event |
Create an event, optionally with Meet link and guests |
update_event |
Change an event; only the fields you pass are altered |
delete_event |
Delete an event |
respond_to_event |
RSVP as yourself |
suggest_time |
Find slots where everyone is free, via free/busy |
🔐 Auth
| Tool | Description |
|---|---|
authenticate_gmail |
Authenticate via browser. Covers Gmail, Calendar and Drive |
🔑 Scopes
| Scope | Why |
|---|---|
https://mail.google.com/ |
Read, label, draft, trash and permanently delete mail |
https://www.googleapis.com/auth/calendar |
Calendar tools |
https://www.googleapis.com/auth/drive.file |
save_attachment_to_drive |
Drive is requested as drive.file, not the full drive scope: it grants rights
over the files this app creates and nothing else, so the server cannot read,
list or alter anything already in your Drive.
The trade-off is worth knowing. Because the app never gains rights over folders
it did not create, passing a folderId for a folder you made in the Drive web
UI can come back as "not found" even though it plainly exists. When that
happens the file is uploaded to My Drive instead and the result says so, rather
than the upload being lost.
Changing this list invalidates existing credentials. Google will not add scopes to a refresh token it has already issued, so a token predating a scope keeps working for everything else while the new feature returns a bare 403. The tools detect that case and tell you to re-run authentication:
npx @spark-apps/gmail-manager-mcp@latest auth
🗄️ Caching
Mail is cached locally so the same message is not downloaded twice, but never at
the expense of being current. Gmail hands out a mailbox-wide historyId and a
feed of what changed since any earlier value of it, so this server validates its
cache against Gmail rather than expiring it on a timer:
- Nothing has changed: the cached answer is provably still exact, and a repeated search costs a single request instead of one per result.
- Something has changed: the list of matching messages is always re-fetched, so new mail, sent mail and anything relabelled show up immediately. Only the per-message headers and bodies are reused, which is safe because Gmail does not let the content of a delivered message change.
There is no staleness window to tune: a message that arrives between two searches appears in the second one.
| Variable | Default | Effect |
|---|---|---|
GMAIL_CACHE |
full |
full keeps the cache in ~/.gmail-mcp/cache/ (owner-only), memory keeps it in RAM for the life of the process, off disables it |
GMAIL_CACHE_MAX_MESSAGES |
2000 |
Messages held before the least recently used are dropped |
GMAIL_CACHE_MAX_THREADS |
300 |
Conversations held |
GMAIL_CACHE_MAX_QUERIES |
200 |
Search results remembered |
"env": { "GMAIL_CACHE": "memory" }
Set GMAIL_CACHE=memory on a shared machine if you would rather no mail content
touched the disk. The cache is dropped automatically when you authenticate as a
different account, and deleting ~/.gmail-mcp/cache/ clears it by hand.
💬 Example Commands
🧹 Quick Cleanup
- "Delete all promotional emails from last 30 days"
- "Delete all unread newsletters older than 1 week"
- "Delete all 'no-reply' emails from last 3 months"
- "Delete all LinkedIn notification emails"
- "Delete all password reset emails older than 1 month"
- "Delete redundant email chains where I'm CC'd"
⚡ Smart Actions
- "Summarize email with subject: 'last boring meeting'"
- "Summarize all emails about 'project deadline'"
- "Reply to email about 'project update' saying 'Got it, thanks!'"
- "Label all emails from my bank as 'Finance'"
- "Create 'Travel' label and move all booking confirmations"
- "Find emails with attachments larger than 5MB"
📊 Inbox Insights
- "Show me who sends me the most emails"
- "Find all unread emails older than 1 week"
- "Show my busiest email days this month"
- "Find emails I starred but never replied to"
📅 Calendar
- "What's on my calendar this week?"
- "Find a 45-minute slot next week when Sam and I are both free, weekdays 9-5"
- "Move Thursday's standup to 10am and add a Meet link"
- "Decline the Friday review, comment that I'm on leave"
- "Search my calendar for anything about the tax deadline"
🛡️ Rules & Unsubscribing
- "Show me the rules currently on my account"
- "Rule: anything from noreply@ skips the inbox and gets labelled Noise"
- "Get the unsubscribe link for this sender so I can check it before clicking"
- "Unsubscribe me from this newsletter"
Unsubscribing uses the sender's own published opt-out. Where they support one-click (RFC 8058) it completes on its own; where the only route is emailing them, it asks first, since that sends mail from your account. A plain link with no one-click declaration is handed back for you to open. Arbitrary URLs found in mail are never visited, and no response body from a sender is ever read back into the conversation.
🌱 Support & Contributions
⭐ Star the repo & I power up like Mario 🍄
☕ Devs run on coffee - Buy me one?
💰 Crypto tips welcome - Tip in crypto
🤝 Contributions are welcome - 🍴 Fork, improve, PR!
🎥 Need help?
Setup Tutorial •
Join Discord
💖 Sponsor
Your support helps maintain and improve the tool. please consider sponsoring the project.
Made with ❤️ for MCP • Privacy Policy • Terms of Service
Installing muammar-yacoob/GMail-Manager-MCP
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/muammar-yacoob/GMail-Manager-MCPFAQ
Is muammar-yacoob/GMail-Manager-MCP MCP free?
Yes, muammar-yacoob/GMail-Manager-MCP MCP is free — one-click install via Unyly at no cost.
Does muammar-yacoob/GMail-Manager-MCP need an API key?
No, muammar-yacoob/GMail-Manager-MCP runs without API keys or environment variables.
Is muammar-yacoob/GMail-Manager-MCP hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install muammar-yacoob/GMail-Manager-MCP in Claude Desktop, Claude Code or Cursor?
Open muammar-yacoob/GMail-Manager-MCP on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

