Multi-account Gmail MCP server on Cloudflare Workers — one deployment, one Google sign-in per connection, any MCP client
git clone https://github.com/mkpoli/gmail-mcp{
"mcpServers": {
"gmail-mcp": {
"command": "node",
"args": ["/path/to/gmail-mcp/dist/index.js"]
}
}
}MCP Servers overview
<div align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="./docs/logo-dark.svg"> <source media="(prefers-color-scheme: light)" srcset="./docs/logo-light.svg"> <img src="./docs/logo-light.svg" alt="gmail-mcp" width="520"> </picture> **Gmail for your AI assistant — several accounts at once, on a server you own.** [](./LICENSE) [](https://developers.cloudflare.com/workers/) [](https://modelcontextprotocol.io/) [](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1) [](#what-it-can-do) [](#how-it-was-tested) *[日本語版](./README.ja.md) · [简体中文](./README.zh.md)* </div> <p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="./docs/demo-dark.svg"> <source media="(prefers-color-scheme: light)" srcset="./docs/demo-light.svg"> <img src="./docs/demo-light.svg" alt="An assistant searches a work and a personal mailbox, then replies to a thread with an attachment" width="760"> </picture> </p> **gmail-mcp** connects Gmail to Claude and any other [MCP](https://modelcontextprotocol.io/) client. It can **search and read** mail, **send and reply-all** with quoted history, **forward**, handle **attachments and inline images**, and manage drafts, labels, and threads — across **several Google accounts at the same time**. It runs as a remote server on **your own Cloudflare Worker**, so the same connection answers from Claude Code on a laptop, claude.ai in a browser, and Claude on a phone. Each connection signs in to **one** Google account, and the Google refresh token stays in **your** Cloudflare account. Two things push people here. The Gmail connectors built into Claude and Google read mail and write drafts, but **cannot send**, and hold one Google account per assistant account. Servers that can send are usually local processes — fine at a desk, invisible from a phone. --- ## How it compares <p align="center"> <img src="./docs/comparison-en.svg" alt="gmail-mcp compared with built-in connectors, google_workspace_mcp, and Gmail-MCP-Server" width="880"> </p> <details> <summary><b>A longer comparison</b> — six projects, twelve rows</summary> <br> | | **gmail-mcp** | [Claude](https://claude.com/connectors/gmail) · [Google](https://developers.google.com/workspace/gmail/api/guides/configure-mcp-server) built-in | [taylorwilsdon/<br>google_workspace_mcp](https://github.com/taylorwilsdon/google_workspace_mcp) | [ArtyMcLabin/<br>Gmail-MCP-Server](https://github.com/ArtyMcLabin/Gmail-MCP-Server) | [shinzo-labs/<br>gmail-mcp](https://github.com/shinzo-labs/gmail-mcp) | [aaronsb/<br>google-workspace-mcp](https://github.com/aaronsb/google-workspace-mcp) | | :-- | :-: | :-: | :-: | :-: | :-: | :-: | | Where it runs | Cloudflare Workers | vendor-hosted | your server or local | local | local | local | | Reachable from a phone | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | Several mailboxes at once | ✅ bound per connection | ❌ | ✅ chosen per call | ❌ aliases only | ❌ | ✅ chosen per call | | Send mail | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | | Attachments · inline `cid:` images | ✅ | undocumented | ✅ | ✅ | ❌ | ✅ | | Reply-all with quoted history | ✅ | ❌ | drafts only | no quoting | ❌ | ✅ | | Forward | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | | Honors each part's charset | ✅ | — | ❌ UTF-8 assumed | ❌ UTF-8 assumed | ❌ | ❌ | | Rejects CRLF header injection | ✅ | — | ✅ framework | ✅ strips | ❌ **none** | ✅ | | Mailbox settings (filters, vacation) | ❌ out of scope | ❌ | filters | filters | ✅ | ❌ | | Tool count | 24 | 11–16 | 14 (Gmail) | 30 | 64 | 11 | | Who holds your refresh token | you | vendor | you | you | you | you | [`google_workspace_mcp`](https://github.com/taylorwilsdon/google_workspace_mcp) is the most complete project here. It covers all of Workspace rather than Gmail alone, and it appends your Gmail signature and pulls attachments straight from a URL, neither of which gmail-mcp does. [`shinzo-labs/gmail-mcp`](https://github.com/shinzo-labs/gmail-mcp) reaches vacation responders, delegates, and S/MIME through its 64 tools; those live under `gmail.settings.*`, a scope gmail-mcp never requests, so they stay beyond its reach whatever happens to a grant. Two design differences decide most of the rest. Routing accounts by a call argument lets one grant touch every connected mailbox, while binding the mailbox to the connection means a wrong argument reaches nothing. And on reading, the local servers decode every part as UTF-8: ISO-2022-JP and Shift_JIS mail arrives garbled, and long messages that Gmail stores as attachment blobs come back with an empty body. </details> --- ## Deploy it About ten minutes. You need a Cloudflare account, [bun](https://bun.sh), and a Google account. A domain on the Cloudflare account is optional — without one the Worker answers on `workers.dev`. ### 1 · Create a Google OAuth client ```sh PROJECT="gmail-mcp-$(openssl rand -hex 3)" gcloud auth login gcloud projects create "$PROJECT" --name="gmail-mcp" gcloud config set project "$PROJECT" gcloud services enable gmail.googleapis.com ``` Google exposes no API for the next two steps, so they happen in the [Cloud console](https://console.cloud.google.com/): - [**OAuth consent screen**](https://console.cloud.google.com/auth/overview) → *External*. While the app is unverified, add each mailbox you plan to connect under **Test users**. - [**Credentials**](https://console.cloud.google.com/apis/credentials) **→ Create credentials → OAuth client ID** → *Web application*, with `https://<your-host>/callback` as an authorized redirect URI. Keep the client ID and secret. `<your-host>` is the domain you point at the Worker, or the `workers.dev` hostname it gets otherwise. Deploying first and coming back to fill this in works — the guide the Worker serves at `/` shows the exact value. ### 2 · Deploy the Worker [](https://deploy.workers.cloudflare.com/?url=https://github.com/mkpoli/gmail-mcp) The button copies the repository into your GitHub account, creates the KV namespace and the Durable Object, and asks for the four secrets. It deploys to `workers.dev`; a custom domain is attached afterwards under **Settings → Domains & Routes**. From a terminal instead: ```sh git clone https://github.com/mkpoli/gmail-mcp && cd gmail-mcp bun install bun run setup ``` `bun run setup` asks which domain to answer on, creates or reuses the `OAUTH_KV` namespace, takes the client ID and secret, generates a cookie key, and deploys. Those first two answers land in `wrangler.local.jsonc`, which git ignores — `wrangler.jsonc` names no account's namespace and no one's domain, so a clone deploys anywhere. Re-running setup to rotate a single secret is safe. ### 3 · Connect a client Leave the client ID and secret fields empty — MCP clients register themselves. ```sh claude mcp add --transport http gmail-personal https://<your-host>/mcp claude mcp add --transport http gmail-work https://<your-host>/mcp/work ``` Run `/mcp` in Claude Code to sign each connection in to its Google account. In claude.ai it is **Settings → Connectors → Add custom connector** with the same URL. Any single-segment label works after `/mcp/`, which is how one deployment serves several mailboxes to clients that reject two servers sharing a URL. Your deployment serves this guide at `https://<your-host>/`. --- ## What it can do <table> <tr><th align="left">📖 Read</th><th align="left">✍️ Write</th><th align="left">🏷 Organize</th></tr> <tr valign="top"> <td> `whoami`<br> `search_messages`<br> `get_message`<br> `get_thread`<br> `get_attachment` </td> <td> `send_message`<br> `reply_all`<br> `forward_message`<br> `create_draft`<br> `update_draft`<br> `send_draft`<br> `delete_draft`<br> `list_drafts`<br> `stage_attachment_begin`<br> `stage_attachment_append`<br> `stage_attachment_finish` </td> <td> `list_labels`<br> `create_label`<br> `update_label`<br> `delete_label`<br> `modify_labels`<br> `modify_thread_labels`<br> `batch_modify_messages`<br> `trash_message` · `untrash_message`<br> `trash_thread` · `untrash_thread` </td> </tr> </table> Messages leave the way a mail client sends them: plain text with an HTML alternative, file attachments, and inline images referenced by `cid:`, nested as `multipart/mixed › multipart/related › multipart/alternative`. Subjects and display names use RFC 2047, filenames use RFC 2231, so Japanese, Chinese, and emoji survive the trip. `reply_all` reads the original's `Reply-To`, `From`, `To`, and `Cc`, drops your own address and any address you send mail as, answers from the one the sender wrote to, carries the `References` chain, and quotes the original in whichever parts you send. `forward_message` reproduces the forwarded envelope and can re-attach the original's files. `create_draft` with `replyToMessageId` writes the reply as a draft to edit before sending: it joins the original's thread, carries `In-Reply-To` and `References`, derives the reply-all recipients and the `Re:` subject, and quotes the original. `update_draft` changes only the fields it is given; recipients, text, files added by hand in any client, and the thread the draft answers are read back and kept. A file whose base64 will not fit through tool arguments is staged instead: `stage_attachment_begin` returns an upload URL that takes the raw bytes in one `curl -T`, `stage_attachment_append` takes base64 in chunks, and every `attachments` field accepts the resulting `stagingId`. Reading is bounded on purpose: message and thread bodies have character budgets, a whole response
What people ask about gmail-mcp
What is mkpoli/gmail-mcp?
+
mkpoli/gmail-mcp is mcp servers for the Claude AI ecosystem. Multi-account Gmail MCP server on Cloudflare Workers — one deployment, one Google sign-in per connection, any MCP client It has 5 GitHub stars and was last updated today.
How do I install gmail-mcp?
+
You can install gmail-mcp by cloning the repository (https://github.com/mkpoli/gmail-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is mkpoli/gmail-mcp safe to use?
+
mkpoli/gmail-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains mkpoli/gmail-mcp?
+
mkpoli/gmail-mcp is maintained by mkpoli. The last recorded GitHub activity is from today, with 9 open issues.
Are there alternatives to gmail-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy gmail-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/mkpoli-gmail-mcp)<a href="https://claudewave.com/repo/mkpoli-gmail-mcp"><img src="https://claudewave.com/api/badge/mkpoli-gmail-mcp" alt="Featured on ClaudeWave: mkpoli/gmail-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!