gmail-mcp
A fully-featured Gmail plugin for Claude Code, implemented as a remote MCP server on Cloudflare Workers with Google OAuth.
No local Node process. No tokens on your laptop. Just deploy the Worker once, install the plugin, and Claude handles the OAuth consent on first use.
Features
Read & search
gmail_search — Gmail query syntax, metadata-only summaries (fast)
gmail_get_message — full body + attachments metadata
gmail_list_threads, gmail_get_thread
Send, reply, forward, drafts
gmail_send — plain text / HTML / multipart with attachments
gmail_reply — preserves threading headers & threadId
gmail_forward — proper "Forwarded message" quote
gmail_create_draft, gmail_update_draft, gmail_send_draft, gmail_delete_draft, gmail_list_drafts, gmail_get_draft
Labels & organization
gmail_list_labels, gmail_create_label, gmail_update_label, gmail_delete_label
gmail_modify_labels (single), gmail_batch_modify_labels (up to 1000), gmail_modify_thread_labels
gmail_trash, gmail_untrash, gmail_delete, gmail_trash_thread, gmail_untrash_thread
Attachments
gmail_get_attachment — inline base64 ≤ 1 MB, metadata-only above
Unsubscribe
gmail_inspect_unsubscribe — show available methods for a message
gmail_unsubscribe — prefers RFC 8058 one-click (HTTPS POST), falls back to mailto, otherwise returns the URL
Plugin extras
- Slash commands:
/gmail-inbox, /gmail-search, /gmail-compose, /gmail-triage, /gmail-unsubscribe
email-triage subagent for bulk inbox cleanup
skills/gmail/SKILL.md — usage guidance Claude auto-loads
Architecture
Claude Code ──HTTP MCP──▶ Cloudflare Worker ──HTTPS──▶ Gmail API
│
▼
Workers KV (grants, refresh tokens)
Durable Object (per-session McpAgent)
@cloudflare/workers-oauth-provider issues MCP-facing OAuth 2.1 tokens and transparently stores grants in KV.
agents/mcp's McpAgent gives each session a Durable Object with streamable HTTP transport.
- On first connect, Claude's MCP client performs the OAuth dance; the Worker bounces the user to Google for consent and stores the refresh token encrypted in KV.
- Google access tokens are refreshed automatically in the Gmail client wrapper.
Setup
1. Create a Google OAuth client
In Google Cloud Console:
- Create a Web application OAuth client.
- Add authorized redirect URI:
https://<your-worker-subdomain>.workers.dev/callback
- Enable the Gmail API in the same project.
- On the OAuth consent screen, add scopes:
.../auth/userinfo.email
.../auth/userinfo.profile
openid
.../auth/gmail.modify
.../auth/gmail.send
.../auth/gmail.labels
.../auth/gmail.compose
2. Deploy the Worker
cd worker
npm install
# One-time: create the KV namespace and paste the id into wrangler.toml
npx wrangler kv namespace create OAUTH_KV
# Set secrets
npx wrangler secret put GOOGLE_CLIENT_ID
npx wrangler secret put GOOGLE_CLIENT_SECRET
npx wrangler secret put COOKIE_ENCRYPTION_KEY # openssl rand -base64 32
npx wrangler deploy
3. Install the plugin in Claude Code
# From the directory above this repo:
claude plugin install ./gmail-mcp
Edit .mcp.json to point at your deployed Worker URL (or set GMAIL_MCP_URL):
{
"mcpServers": {
"gmail": {
"type": "http",
"url": "https://gmail-mcp.<your-subdomain>.workers.dev/mcp"
}
}
}
First time you use a Gmail tool, Claude will pop up the Google consent screen.
Local development
cd worker
cp .dev.vars.example .dev.vars # fill in real values
npm run dev # wrangler dev at http://localhost:8787
Point a local MCP client at http://localhost:8787/mcp. Use ngrok or a Cloudflare tunnel if you need an HTTPS redirect URI for Google OAuth locally.
Verification checklist
/gmail-inbox — triggers OAuth, returns unread messages.
/gmail-search from:me — returns sent mail metadata.
/gmail-compose send a test email to myself saying hi — creates draft, prompts for confirmation, sends.
- Send yourself a self-reply via
gmail_reply; check threading in the Gmail UI.
- Archive a message (
gmail_modify_labels removing INBOX) and un-archive (add INBOX).
- Create a label, apply it, delete it.
- Download an attachment under 1 MB; confirm base64 round-trips.
/gmail-unsubscribe <id of a newsletter> — inspect + unsubscribe.
/gmail-triage 20 — launches the subagent, categorizes, proposes and executes cleanup.
- Kill the Worker mid-session; reconnect; confirm the McpAgent Durable Object resumes.
Scopes requested