gmail-mcp CLAUDE.md

A local service that lets an AI agent work with multiple Gmail accounts through one interface, with login tokens stored locally.

In plain words
What is it for?
Adding, listing, and removing Gmail accounts, routing requests to a chosen inbox, searching all connected accounts, and reading or processing Gmail messages.
Why use it?
It avoids limiting the agent to one Gmail account at a time and makes it possible to search across several inboxes.

Instructions file

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/cunicopia-dev/gmail-mcp/claude-md
Clone the repo
git clone --depth 1 https://github.com/cunicopia-dev/gmail-mcp
Per session 3,556 This file is loaded in full into every session.
When invoked 3,556 The same file — it is already loaded in full.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.03556 $0.03556
Opus 5 $0.01778 $0.01778
Sonnet 5 $0.00711 $0.00711
Haiku 4.5 $0.00356 $0.00356

Measured 2d ago against content hash 5c84a25307a3, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

gmail-mcp CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

CLAUDE.md · 243 lines

How it starts

The opening of the file, as written. The whole thing — 243 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Gmail MCP — Development Guide

What it is

A local stdio MCP server giving an AI agent unified access to multiple Gmail accounts at once. The native Anthropic Gmail connector binds one account per OAuth grant; this server holds refresh tokens for N accounts in a local SQLite store and routes each tool call to the right inbox via an account argument. search_all_accounts fans one query across every inbox.

Layout

src/gmail_mcp/
  server.py   — MCP server entry point, tool registration, dispatch, per-account routing
  auth.py     — gmail-mcp-auth CLI: browser OAuth bootstrap (NOT an MCP tool)
  store.py    — SQLite token store (accounts table keyed by email)
  gmail.py    — per-account service build + token refresh; pure MIME parsing/formatting
  config.py   — path resolution (DB, client secret) + SCOPES constant
tests/        — pytest; Gmail client is mocked, no live network

Module responsibilities

Module Purpose
server.py Registers MCP tools, dispatches calls, resolves account → service. All Gmail network I/O runs in asyncio.to_thread (the google client is sync).
auth.py add / list / remove subcommands. add runs InstalledAppFlow.run_local_server, reads the granted email from users.getProfile, upserts into the store.
store.py TokenStore CRUD over sqlite3. upsert preserves added_at; touch stamps last_used_at; update_token persists refreshed access tokens.
gmail.py build_service(account, store) builds google-auth Credentials, refreshes if stale, persists the new token, returns a Gmail client. Plus pure helpers — parse_message, extract_body_and_attachments, strip_html, resolve_label_ids, build_mime_message, sanitize_filename, screen_attachment, decode_b64url_bytes, formatters.
config.py db_path(), client_secret_path(), attachments_dir(), max_attachment_bytes(), SCOPES.

OAuth model

  • Auth is a CLI, not a tool — the OAuth flow needs a browser, which an MCP tool can't drive. gmail-mcp-auth add runs the installed-app loopback flow and stores the refresh token.
  • Client config comes from a downloaded Google "Desktop app" OAuth client JSON at ~/.gmail-mcp/client_secret.json (env GMAIL_MCP_CLIENT_SECRET). Never hardcode client_id/client_secret.
  • Token store: SQLite at ~/.gmail-mcp/tokens.db (env GMAIL_MCP_DB). Keyed by email. Holds refresh_token + last access-token blob + scopes.
  • Refresh: google-auth's Request transport refreshes the access token on demand; build_service persists the refreshed blob back to the DB.
  • Scopes (one constant, config.SCOPES): gmail.readonly, gmail.compose, gmail.modify, gmail.settings.basic. Granular — NOT full mail.google.com, and no gmail.send / no gmail.settings.sharing (see Security model). Widening SCOPES does NOT retro-grant existing accounts — each must re-run gmail-mcp-auth add to re-consent, or the new tool returns 403 insufficient scope.

Read the full file on GitHub · 243 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 243 lines · 3,556 tokens per session scan A 5c84a25307a3

Subscribe to this mod's changes

gmail-mcp CLAUDE.md is an instructions file published in the GitHub repository cunicopia-dev/gmail-mcp (3 stars, last pushed 5d ago), licensed MIT. It adds 3,556 tokens to every session, about $0.0178 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.