AIMM — Gmail MCP Setup Guide

Connect Claude to your Gmail accounts — read, send, search, and manage email across multiple inboxes without leaving Claude.

~60 min total setup · Runs locally · Node.js 18+ required · Free (no API costs)


Step 1 — Google Cloud: Create OAuth Credentials (~20 min)

You need one Google Cloud project that covers all your accounts. You don’t need a separate project per inbox.

Create the project

  1. Go to console.cloud.google.com → create a new project (e.g. “Gmail MCP”)
  2. Go to APIs & Services → Library → search “Gmail API” → Enable
  3. Search “People API” → Enable (required for contact group lookups)
  1. Go to APIs & Services → OAuth consent screen → choose External → fill in app name → Save
  2. Under Test users, add every email address you plan to connect — including the real sign-in address behind any aliases

Alias accounts: If any email is a “Send mail as” alias (e.g. support@yourdomain.com forwards to a Gmail account), add the backing Gmail address as a test user — Google won’t recognise the alias as a sign-in username.

Create OAuth credentials

  1. Go to APIs & Services → Credentials → Create Credentials → OAuth client ID
  2. Application type: Desktop app — do not choose “Web application” (it adds unnecessary redirect URI complexity)
  3. Click Download JSON — you’ll place this file in the repo shortly

The downloaded file is your credentials.json. Keep it secret — it grants access to create OAuth tokens for your accounts.


Step 2 — Install the Gmail MCP Server (~10 min)

Clone the repo and install dependencies. No build step needed — the server runs TypeScript directly via tsx.

git clone https://github.com/coreyepstein/advanced-gmail-mcp
cd advanced-gmail-mcp
npm install

Place your credentials file

cp ~/Downloads/client_secret_*.json ./credentials.json
chmod 600 credentials.json

Create the tokens directory

mkdir -p tokens
chmod 700 tokens

Security: credentials.json and tokens/ are already in .gitignore. Never commit them. The chmod commands lock them so only your user can read them.


Step 3 — Configure Your Accounts (~5 min)

cp accounts.example.json accounts.json

Edit accounts.json:

{
  "accounts": [
    {
      "email": "you@gmail.com",
      "alias": "personal",
      "name": "Your Name"
    },
    {
      "email": "support@yourdomain.com",
      "alias": "support",
      "name": "Support Team"
    },
    {
      "email": "admin@yourcompany.com",
      "alias": "work",
      "name": "Work Admin"
    }
  ],
  "default": "personal"
}

Field reference

FieldPurpose
emailSets the From: address on outbound mail — use the alias address here, not the backing Gmail
aliasShort name used in Claude prompts: “send from my work account”
nameDisplay name in the From header — e.g. “Support Team <support@yourdomain.com>“
defaultWhich account is used when none is specified

Alias emails: If support@yourdomain.com is a “Send mail as” alias, keep it in the email field so outbound mail uses that address. Gmail will honour it as long as the alias is verified under Settings → Accounts and Import → Send mail as.


Step 4 — Authenticate Each Account (~15 min)

Run the auth flow once per account. Each opens a browser URL — sign in and approve, then the token is saved automatically.

# Authenticate one account at a time
npx tsx src/auth.ts personal
npx tsx src/auth.ts work
npx tsx src/auth.ts support
 
# Or authenticate all accounts in sequence
npx tsx src/auth.ts
 
# Check status of all accounts
npx tsx src/auth.ts --check

Alias accounts — critical gotcha: If an email in your accounts.json is a “Send mail as” alias (not a real Google login), the auth screen will show “Couldn’t find your Google Account.” To fix:

  1. Temporarily change email in accounts.json to the backing Gmail address
  2. Run the auth flow — sign in with the backing account
  3. Change email back to the alias address

The token file is named after the alias, not the email — so it will still load correctly.

Lock your tokens

chmod 600 tokens/*.json

Tokens are long-lived. You’ll rarely need to re-authenticate unless you revoke access in Google account settings or add new OAuth scopes.


Step 5 — Wire Up Claude Desktop (~5 min)

Edit your Claude Desktop config at:

~/Library/Application Support/Claude/claude_desktop_config.json

Add a single gmail entry under mcpServers — one server handles all accounts:

{
  "mcpServers": {
    "gmail": {
      "command": "/opt/homebrew/bin/npx",
      "args": [
        "tsx",
        "/absolute/path/to/advanced-gmail-mcp/src/server.ts"
      ]
    }
  }
}

Use the absolute path to server.ts — relative paths break when Claude is invoked from different directories. Run pwd inside the repo folder to get the full path.

One server, all accounts. Unlike other Gmail MCPs, this server is multi-account aware. You route per-call by passing account: "alias" in each tool call — no separate server entry per inbox.

Restart Claude Desktop. The gmail tools will appear in Claude’s tool list.


Step 6 — Fix Deliverability (Custom Domains) (~5 min)

If you’re sending from a custom domain alias (e.g. support@yourdomain.com), outbound mail may land in spam. Fix: add Google’s sending servers to your domain’s SPF record.

Check your current SPF record

dig TXT yourdomain.com +short

Look for a line starting with v=spf1.

Update the SPF record

Add include:_spf.google.com before the final ~all or -all:

# Before
v=spf1 include:_spf.mx.cloudflare.net ~all

# After
v=spf1 include:_spf.mx.cloudflare.net include:_spf.google.com ~all

Update this in your DNS provider (Cloudflare, Route53, etc.). Propagates in minutes on Cloudflare.

Gmail-only accounts (e.g. loudalo@gmail.com) don’t need this — Google already authorises its own servers for gmail.com.


Step 7 — Verify Everything Works (~5 min)

With Claude Desktop restarted, try these prompts:

Read email:

List the 5 most recent unread emails in my personal inbox.

Send email:

Send a test email from my work account to yourself at your personal address.
Subject: MCP test. Body: It works.

Search:

Search my support inbox for emails from this week that mention "invoice".

Expected From header: If you set a name field, sent mail should show Your Name <you@domain.com> in the recipient’s inbox — not a garbled alias.

If something fails:

cat ~/Library/Logs/Claude/mcp*.log | tail -50

Look for [gmail] Server started and connected successfully. If absent, check the path in your config and that npm install completed cleanly.


Step 8 (Bonus) — Build a Newsletter Skill (~30 min)

Once the MCP is running, you can build a Claude skill that turns a markdown email body into a branded HTML newsletter and sends it to a contact group — all from a single prompt.

How it works

  • You say “send this to my [group name] list” and paste or describe the content
  • The skill calls get_contact_group to fetch all members of a named Google Contacts group
  • Converts your markdown body → styled HTML using your own branded template
  • Shows a preview (subject, recipient count, snippet) and waits for confirmation
  • Sends individually to each member — not BCC — so each person gets a personal send

What you need to build it

  1. An HTML email template — your branded shell with a {{BODY_HTML}} placeholder where the converted content goes
  2. A Google Contacts group — create one in contacts.google.com and add your list members. The group name is what you’ll pass to get_contact_group.
  3. A skill file (~/.claude/skills/your-newsletter/SKILL.md) — instructs Claude to: collect subject + markdown body, fetch the contact group, convert markdown to HTML, inject into your template, preview, confirm, then send.

Markdown → HTML conversion rules for the skill

Tell Claude in your skill instructions to convert using these patterns:

- Blank line between paragraphs → <p style="margin:0 0 20px 0;">...</p>
- **bold** → <strong>
- *italic* → <em>
- - list item → <ul><li>
- ## heading → <p><strong>heading</strong></p>
- [text](url) → <a href="url">text</a>
- --- → <hr>

People API required. The get_contact_group tool uses Google’s People API. Make sure it’s enabled in your Google Cloud project (Step 1) and that your OAuth token includes the contacts.readonly scope. If you added this scope after your initial auth, delete your token file and re-run the auth flow for that account.


Built by AIMM — AI Leaders Mastermind · Questions? Ask in the group.