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.
Read & search
gmail_search— Gmail query syntax, metadata-only summaries (fast)gmail_get_message— full body + attachments metadatagmail_list_threads,gmail_get_thread
Send, reply, forward, drafts
gmail_send— plain text / HTML / multipart with attachmentsgmail_reply— preserves threading headers & threadIdgmail_forward— proper "Forwarded message" quotegmail_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_labelgmail_modify_labels(single),gmail_batch_modify_labels(up to 1000),gmail_modify_thread_labelsgmail_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 messagegmail_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-triagesubagent for bulk inbox cleanupskills/gmail/SKILL.md— usage guidance Claude auto-loads
Claude Code ──HTTP MCP──▶ Cloudflare Worker ──HTTPS──▶ Gmail API
│
▼
Workers KV (grants, refresh tokens)
Durable Object (per-session McpAgent)
@cloudflare/workers-oauth-providerissues MCP-facing OAuth 2.1 tokens and transparently stores grants in KV.agents/mcp'sMcpAgentgives 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.
- 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.profileopenid.../auth/gmail.modify.../auth/gmail.send.../auth/gmail.labels.../auth/gmail.compose
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# From the directory above this repo:
claude plugin install ./gmail-mcpEdit .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.
cd worker
cp .dev.vars.example .dev.vars # fill in real values
npm run dev # wrangler dev at http://localhost:8787Point 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.
/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_labelsremovingINBOX) and un-archive (addINBOX). - 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.
openid email profile— identify the user for the MCP token mapping.gmail.modify— read + label + trash.gmail.send— send composed mail.gmail.labels— create/edit/delete labels.gmail.compose— create drafts.
This plugin never requests gmail.readonly (too restrictive) or full mail.google.com (too broad).
MIT.