multi-gmail-mcp
Allows connecting multiple Gmail accounts to scan inbox, read threads, draft and send replies, manage follow-ups, and send new emails through the Gmail API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@multi-gmail-mcpShow me my latest unread emails"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
multi-gmail-mcp
Multi-account Gmail MCP server for Claude Desktop, Cursor, and other MCP hosts.
It lets your assistant:
connect one or more Gmail accounts
scan the inbox with lightweight list mode (metadata only)
load one full thread at a time with
get_thread(plain or quote-stripped bodies)draft replies from real message text (not Gmail snippets)
send replies (
send) or new outbound mail (send_new), including HTML bodiessave drafts to Gmail
send only after explicit approval
manage follow-up reminders for email threads
Safety rule: nothing is ever sent automatically. send, send_new, and followup_send must only be called after human approval.
What This MCP Does
This server is thread-first, not message-first, and metadata-first for inbox triage.
multi_gmail_fetchwithmode=list(default) returns small per-thread metadata — snippets are not full emailsfor each thread you care about, call
multi_gmail_get_threadonce — never load many full threads in one LLM contextmulti_gmail_get_threadreturns a chronological transcript (format,stripped,latestN)multi_gmail_sendsends an approved reply (messageIdrequired);multi_gmail_send_newstarts a new thread (standalone outbound mail)outbound tools support
format:text/plain(default) ortext/html(pricing tables, CTAs)legacy
mode=fullon fetch still batch-loads and auto-drafts (token-heavy — avoid for normal inbox review)multi_gmail_followup_duerefreshes the thread before showing a due follow-up
This project is designed for setups where one person may handle:
multiple Gmail accounts
multiple chats against one MCP server session
inbox review plus follow-up workflows in the same toolset
Related MCP server: Gmail Plugin MCP Server
Requirements
Node.js
18+a Gmail account
Claude Desktop, Cursor, or another MCP-compatible host
a Google Cloud project with Gmail API enabled
Check Node:
node --versionInstall
npm install -g @nitsantechnologies/multi-gmail-mcp
mkdir -p ~/.multi-gmail-mcpSet this env var anywhere you run the server or auth command:
export MULTI_GMAIL_MCP_HOME="$HOME/.multi-gmail-mcp"Useful commands:
multi-gmail-mcp
multi-gmail-mcp-authLocal development from git still works:
git clone https://github.com/nitsan-ai/Multi-Gmail-MCP.git
cd Multi-Gmail-MCP
npm install
npm start
npm run authGoogle OAuth Setup
Open Google Cloud Console
Create or select a project
Enable Gmail API
Go to APIs & Services -> Credentials
Create OAuth client ID
Choose Desktop app
Download the JSON file
Save it in your config home as:
~/.multi-gmail-mcp/credentials.jsonSet a different location with MULTI_GMAIL_MCP_HOME. For local git development, project root still works by default.
OAuth scopes used by this MCP:
https://www.googleapis.com/auth/gmail.readonlyhttps://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/gmail.settings.basic(Gmail signature on send/draft)
After upgrading: re-authenticate every connected account once so tokens include gmail.settings.basic (required for automatic signature appending on send, set_draft, and followup_send):
MULTI_GMAIL_MCP_HOME="$HOME/.multi-gmail-mcp" multi-gmail-mcp-auth --alias <your-alias>Then reconnect in your MCP client (connect + connect_finish).
Local Account Auth
Authenticate the first Gmail account:
MULTI_GMAIL_MCP_HOME="$HOME/.multi-gmail-mcp" multi-gmail-mcp-authAdd another account with an alias:
MULTI_GMAIL_MCP_HOME="$HOME/.multi-gmail-mcp" multi-gmail-mcp-auth --alias workNotes:
token files are saved under
$MULTI_GMAIL_MCP_HOME/accounts/each alias gets its own token JSON
--accountis accepted as a synonym for--alias
Connect to Claude Desktop
Edit:
~/Library/Application Support/Claude/claude_desktop_config.jsonExample:
{
"mcpServers": {
"multi-gmail-mcp": {
"command": "npx",
"args": [
"-y",
"@nitsantechnologies/multi-gmail-mcp"
],
"env": {
"MULTI_GMAIL_MCP_HOME": "/Users/you/.multi-gmail-mcp"
}
}
}
}Replace /Users/you/.multi-gmail-mcp with your real path.
After saving:
fully quit Claude Desktop
reopen Claude Desktop
Connect to Cursor
Open Cursor Settings -> MCP -> Add server and use:
{
"multi-gmail-mcp": {
"command": "npx",
"args": [
"-y",
"@nitsantechnologies/multi-gmail-mcp"
],
"env": {
"MULTI_GMAIL_MCP_HOME": "/Users/you/.multi-gmail-mcp"
}
}
}Replace /Users/you/.multi-gmail-mcp with your real path.
First-Time Flow Inside Claude or Cursor
Run this once per account:
multi_gmail_statusmulti_gmail_connectwithConnect you@example.com personalmulti_gmail_connect_finishmulti_gmail_set_signermulti_gmail_fetchwithmode="list"multi_gmail_get_threadfor each thread you will read or reply toreview drafts
use
multi_gmail_send(reply) ormulti_gmail_send_new(new outbound) only after approval
Typical signer example:
Set signer name to Jane SmithDaily Workflow
Recommended inbox review (list → one thread at a time)
Ask:
Fetch my inbox with mode list, then get_thread for threads I need to reply toStep 1 — triage (small payload):
{ "mode": "list", "maxResults": 10 }You get per thread: threadId, latestMessageId, subject, participants, date, direction, snippet (preview only).
Step 2 — full bodies (one thread per call):
{
"threadId": "<from fetch>",
"format": "full",
"stripped": false
}stripped=false(default) — full plain-text body per message (best for reading mail)stripped=true— quote/signature-stripped text (best when drafting in long threads)format=latest+latestN— first message + last N messages, with omission markers
Present message.text verbatim to the user — do not summarize snippets or bodies.
Step 3 — draft and send:
Reply in an existing thread →
multi_gmail_sendwithmessageIdfrom fetch /get_threadNew outbound email →
multi_gmail_send_new(nomessageId)
Optional: mode=full on fetch still auto-drafts every thread in one batch (legacy; can cause token overflow).
With mode=list, follow-up-labeled threads are excluded from normal inbox review. Optional markdown export is written unless writeMarkdownFile: false. Nothing is sent until you approve.
After review, per item you can:
sendorsend_newset_drafteditcancel/skip
Follow-up review
Ask:
Show due follow-upsWhat happens:
due reminders are loaded
the thread is refreshed from Gmail first
if the recipient already replied, the reminder is resolved automatically
otherwise a fresh follow-up draft is shown
Tool Reference
The MCP registers both prefixed and unprefixed names:
multi_gmail_fetchandfetchmulti_gmail_followup_dueandfollowup_dueetc.
In practice, most hosts will show the multi_gmail_* names.
Setup and status tools
multi_gmail_help
Shows the first-time setup flow.
Input: none
multi_gmail_status
Shows:
connected account
signer status
due follow-ups
last inbox batch
useful local paths
Input:
accountAliasoptionalchatScopeoptional
multi_gmail_connect
Starts Gmail login for one account and opens the browser.
Input:
commandrequired
Format:
Connect you@example.com personal
Connect you@example.com workmulti_gmail_connect_finish
Completes the login started by connect.
Input:
codeoptionalpendingAliasoptionalchatScopeoptional
Normally you do not need to paste the code manually; the local callback server completes it.
multi_gmail_accounts
Lists all saved local account aliases.
Input: none
multi_gmail_set_signer
Stores the display name used in draft replies for the current session.
Input:
namerequiredfollowUpLabeloptionalaccountAliasoptionalchatScopeoptional
multi_gmail_set_mode
Switches response mode for the current chat scope.
Input:
moderequired:standardorcompact
multi_gmail_diagnostics
Checks:
credentials file
accounts directory
reminder store
active account binding
Input:
accountAliasoptionalchatScopeoptional
multi_gmail_setup_labels
Ensures the configured Gmail labels exist.
Useful if labels do not appear after connect or fetch.
Input:
accountAliasoptionalchatScopeoptional
Inbox and thread tools
multi_gmail_fetch
Lists inbox threads for triage, or (legacy) batch-loads full threads and auto-drafts replies.
Recommended: mode=list (default), then get_thread per selected thread.
| Behavior |
| Metadata only: |
| Legacy: loads full bodies and drafts every thread in one call — token-heavy; avoid for normal inbox review. |
Important behavior:
maxResultsmeans unique inbox threadslistreturnsmessageId/threadIdforsendandget_threadincludeLatestBody(list only): optional latest-message plain body per thread, capped at 15 threads — still preferget_threadfor one threadResponse includes
gmailListQuery— the exact Gmailqstring sent to the API
| Behavior |
| Prepends inbox review filters ( |
| Passes |
Input:
modeoptional:listorfull, defaultlistmaxResultsoptional, default20, max100queryoptional Gmail search string (combined with inbox filters whenqueryMode=inbox)queryModeoptional:inboxorraw, defaultinboxincludeLatestBodyoptional, defaultfalse(list mode only)saveGmailDraftsoptional, defaultfalse(mainlyfullmode)writeMarkdownFileoptional, defaulttrue(fullmode / review export)accountAliasoptionalchatScopeoptional
Examples:
{
"mode": "list",
"maxResults": 10
}{
"mode": "list",
"maxResults": 15,
"query": "newer_than:7d"
}Sent-mail / historical analysis (raw Gmail query):
{
"mode": "list",
"queryMode": "raw",
"query": "in:sent after:2026/01/01 before:2026/04/01",
"maxResults": 50
}Legacy batch mode (avoid for daily triage):
{
"mode": "full",
"maxResults": 5,
"writeMarkdownFile": false
}multi_gmail_send
Sends one approved reply in an existing thread. Marks the source message read and returns IDs for follow-up threading.
For new outbound mail (no source message), use multi_gmail_send_new instead.
Input:
messageIdrequired — fromfetchorget_threadtorequiredsubjectrequiredbodyrequired unless legacyhtmlis setformatoptional:text/plain(default) ortext/html— whentext/html,bodyis the HTML part (plain part auto-generated)htmloptional — legacy HTML part (preferformat+body)cc/bccoptional — single email, comma-separated string, array, orName <email@example.com>(multiple recipients)quoteOriginaloptional, defaulttrue— append Gmail-style quoted parent history below your new body (false= new body only)accountAliasoptionalchatScopeoptional
Response includes: sentMessageId, threadId, isNewThread: false, markedReadMessageId.
Example (plain reply):
{
"messageId": "19e90840fbfd1961",
"to": "recipient@example.com",
"subject": "Re: Pricing",
"body": "Thanks — here is the updated quote."
}multi_gmail_send_new
Sends one approved new email. Use for standalone outbound mail or follow-ups in the same thread.
Input:
torequiredthreadIdoptional — from a priorsend_newresponse; adds this message to that Gmail thread (follow-up in same thread)subjectrequired — Unicode (–, ü, €, etc.) is RFC 2047–encoded automaticallybodyrequired unless legacyhtmlBodyis setformatoptional:text/plain(default) ortext/htmlhtmlBodyoptional — legacy HTML (preferformat+body)ccoptionalbccoptionalaccountAliasoptionalchatScopeoptional
Response includes: sentMessageId, threadId, isNewThread: true — store threadId for phase-2 threading.
Example (HTML outbound):
{
"to": "recipient@example.com",
"subject": "Product — pricing overview",
"format": "text/html",
"body": "<h1>Hello</h1><p>See the <a href=\"https://example.com/pricing\">pricing table</a>.</p>"
}multi_gmail_set_draft
Creates or updates a Gmail draft reply without sending.
Input:
messageIdrequiredtorequiredsubjectrequiredbodyrequired unless legacyhtmlis setformatoptional:text/plain(default) ortext/htmlhtmloptional — legacy HTML partcc/bccoptional — comma-separated string, array, orName <email@example.com>quoteOriginaloptional, defaulttrue— append quoted parent history (Gmail···expander)accountAliasoptionalchatScopeoptional
multi_gmail_get_thread
Loads one Gmail thread as an ordered transcript. Call after fetch mode=list when you need real message bodies.
| Behavior |
| All messages with bodies |
| First message + latest |
| Headers/dates only — no bodies |
Body options (when format is not metadata):
strippeddefaultfalse— full plain-text per messagestripped=true— removes quoted reply history and signatures (drafting in long threads)includeRaw=true— addsrawTextalongside strippedtextfor debugging
Input:
threadIdrequired — fromfetch,followup_due, orarchiveformatoptional:metadata,latest, orfull(defaultfull)latestNoptional, default5, max50(whenformat=latest)strippedoptional, defaultfalseincludeRawoptional, defaultfalseaccountAliasoptionalchatScopeoptional
Example (read full mail):
{
"threadId": "19e913bf5e640ea2",
"format": "full",
"stripped": false
}Example (draft in a long thread):
{
"threadId": "19e913bf5e640ea2",
"format": "full",
"stripped": true
}multi_gmail_archive
Archives one thread by removing the INBOX label.
Input:
threadIdrequiredaccountAliasoptionalchatScopeoptional
multi_gmail_fetch_drafts
Lists messages in Gmail Drafts.
Input:
maxResultsoptionalaccountAliasoptionalchatScopeoptional
multi_gmail_fetch_sent (deprecated)
Lists the latest messages in Gmail Sent without query filters.
Prefer multi_gmail_fetch with queryMode=raw and a Gmail query such as in:sent after:2026/01/01 before:2026/04/01 for filtered sent-mail and historical analysis.
Input:
maxResultsoptionalaccountAliasoptionalchatScopeoptional
Follow-up tools
multi_gmail_followup_trigger
Creates a new follow-up plan for a thread, or updates the existing open plan for that same thread.
Input:
messageIdrequiredpatternoptionaldaysListoptionalbusinessDaysOnlyoptional, defaultfalsedueWeekdayoptionalcreateGmailDraftoptional, defaultfalseaccountAliasoptionalchatScopeoptional
Rules:
use either
patternordaysListnot both
daysListmust be ascendingduplicates are not allowed
Examples:
{
"messageId": "gmail-message-id",
"daysList": [1, 3]
}{
"messageId": "gmail-message-id",
"pattern": "1, 3, 7 business days",
"businessDaysOnly": true
}Scheduling behavior:
first entry is due from now
later entries are chained
example:
[1, 3]means:follow-up 1 in 1 day
follow-up 2 in 3 days after follow-up 1 is sent
multi_gmail_followup_due
Lists due follow-up reminders for the active account.
Behavior:
refreshes the thread before returning results
includes full
threadContextskips reminders if the recipient already replied
Input:
accountAliasoptionalchatScopeoptional
multi_gmail_followup_send
Sends one approved follow-up email.
Input:
reminderIdrequiredtooptionalsubjectoptionalbodyoptional (unless legacyhtmlis set)formatoptional:text/plain(default) ortext/htmlhtmloptional — legacy HTML partcc/bccoptional — comma-separated string, array, orName <email@example.com>quoteOriginaloptional, defaulttrue— append quoted parent history below the follow-up bodyaccountAliasoptionalchatScopeoptional
Only use this after the user explicitly approves the draft.
multi_gmail_followup_cleanup
Deletes follow-up reminder records from the local store.
Input filters:
reminderIdsmessageIdfor Gmail internal message idmessageHeaderIdfor RFCMessage-IDfrom Gmail Show originalsourceThreadIdfollowUpChainIddeleteAllwithconfirm: truestatusescancelChainremoveGmailLabelaccountAliaschatScope
Examples:
Delete by RFC Message-ID:
{
"messageHeaderId": "<abc123@example.com>"
}Delete one chain:
{
"reminderIds": ["reminder-id"],
"cancelChain": true
}Delete all reminders for an account:
{
"deleteAll": true,
"confirm": true
}Multiple Accounts and Shared Sessions
accountAlias
Use accountAlias when you want to target a specific saved local account:
{
"accountAlias": "work"
}chatScope
Some MCP hosts reuse one server session across many chats.
In that case, pass the same chatScope on:
connectconnect_finishset_signerevery later Gmail tool in that same chat
Example:
{
"chatScope": "work-inbox"
}This keeps one chat’s active account binding separate from another chat’s.
Files and Data
Important local paths under $MULTI_GMAIL_MCP_HOME:
credentials.jsonGoogle OAuth client credentialsaccounts/saved Gmail OAuth tokens, one JSON file per aliasdata/followup-reminders.jsonlocal follow-up reminder storedata/inbox-reviews/latest-inbox-review.mdlatest markdown inbox review export
Project layout:
~/.multi-gmail-mcp/
├── credentials.json
├── accounts/
└── data/
├── followup-reminders.json
└── inbox-reviews/Useful env vars:
Name | Purpose |
| base directory for credentials, tokens, and local data |
| absolute or config-home-relative path to OAuth credentials |
| absolute or config-home-relative path to token files |
| absolute or config-home-relative reminder store path |
| absolute or config-home-relative inbox export directory |
Dependencies (for HTML bodies and quote stripping): email-reply-parser, planer, jsdom.
Gmail Labels
This MCP can create Gmail user labels automatically.
Expected labels:
Inbox-reviewMulti-Gmail-MCP Follow-up
Use multi_gmail_setup_labels if they do not appear.
Troubleshooting
Server not showing in Claude or Cursor
make sure
MULTI_GMAIL_MCP_HOMEpoints at your real config directorymake sure
node --versionis18+fully quit and reopen the app
if
npxis unavailable inside the app, install globally and use the full path tomulti-gmail-mcp
multi_gmail_status not available
Usually this means the MCP server did not start at all.
Check:
JSON config syntax
absolute path to the server entry
Node availability
app restart after config change
Token expired or auth errors
Re-authenticate:
rm ~/.multi-gmail-mcp/accounts/*.json
MULTI_GMAIL_MCP_HOME="$HOME/.multi-gmail-mcp" multi-gmail-mcp-authPermission or scope errors
Make sure:
Gmail API is enabled
OAuth client is a Desktop app
scopes include
gmail.modify,gmail.send, andgmail.settings.basic
Then re-authenticate (see Local Account Auth above).
Multiple accounts not working
run
multi_gmail_accountsverify the alias exists
re-authenticate missing accounts:
MULTI_GMAIL_MCP_HOME="$HOME/.multi-gmail-mcp" multi-gmail-mcp-auth --alias workLabels missing in Gmail
Run:
multi_gmail_setup_labelsIf that still fails, re-authenticate so the token includes gmail.modify.
Setup state unclear
Run:
multi_gmail_diagnosticsSecurity Notes
credentials.jsoncontains your Google OAuth client secretaccounts/contains Gmail refresh/access tokensnever commit either of those paths
.gitignorealready excludes themtoken files are written with mode
0600
This repository may also write:
local reminder data
local markdown inbox review exports
Treat those as sensitive personal data.
License
MIT
Company
Developed by NITSAN Technologies
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/japan08/MCP-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server