DMS Gmail MCP
by yiannisdms
README.md
# DMS Gmail MCP — one connector, all three mailboxes
A custom remote MCP server that gives Claude read access to **all three** DMS Gmail
accounts at once — `dmstunedgr@gmail.com`, `yiannis@dmstuned.eu`, `gdimas.mib@gmail.com` —
instead of the built-in connector's one-account-at-a-time limit.
Tools exposed to Claude:
- `gmail_list_accounts` — see the configured mailboxes
- `gmail_search_threads` — Gmail query syntax, per account **or `all`**
- `gmail_search_all_accounts` — one call, searches all three and merges
- `gmail_get_thread` / `gmail_get_message` — full bodies
- `gmail_list_labels` — labels per account
- `gmail_create_draft` — draft an email (nothing sent)
- `gmail_reply` — reply in-thread; **draft by default**, `send:true` to deliver
- `gmail_send_message` — send immediately
Scopes: `gmail.readonly` + `gmail.compose` + `gmail.send`. Read + drafting + sending; no deleting.
Reply/send tools are UTF-8 safe (Greek / emoji). `gmail_reply` defaults to a **draft** so nothing
leaves your outbox unless you (or you tell Claude to) set `send:true`.
> Upgrading from the read-only v1? The added scopes mean you must **re-run `npm run get-token`
> for each account** to grant compose/send, then replace the refresh tokens.
---
## Setup — 4 steps (~20 min, once)
### 1) Create ONE Google OAuth app (covers all 3 mailboxes)
1. Go to **console.cloud.google.com** → create/select a project.
2. **APIs & Services → Enable APIs** → enable **Gmail API**.
3. **APIs & Services → OAuth consent screen** → External → add your email as a **Test user** (add all 3 addresses as test users so each can authorize).
4. **APIs & Services → Credentials → Create credentials → OAuth client ID → Desktop app** (simplest — allows the `localhost` redirect the token script uses).
5. Copy the **Client ID** and **Client secret** → these become `OAUTH_CLIENT_ID` / `OAUTH_CLIENT_SECRET`.
### 2) Mint a refresh token per mailbox
On your machine (Node 18+):
```bash
npm install
OAUTH_CLIENT_ID=xxx OAUTH_CLIENT_SECRET=yyy npm run get-token
```
It prints a URL. Open it **in a browser logged into the mailbox you're adding**, approve
read-only Gmail, and it prints a `refresh_token`. Repeat for all three accounts (log into a
different account each time — an incognito window per account is easiest).
### 3) Fill env vars
Copy `.env.example` → `.env` and paste in the client id/secret, the three refresh tokens
(inside `GMAIL_ACCOUNTS`), and a long random `MCP_AUTH_TOKEN` you invent.
### 4) Deploy (pick one — you need a public HTTPS URL)
**Render — one click (uses the included `render.yaml`):**
1. Push this folder to a GitHub repo (your `yiannisdms` account).
2. render.com → **New → Blueprint** → point at the repo. Render reads `render.yaml`,
builds the `Dockerfile`, and prompts you to fill the 4 secret env vars.
3. Deploy → you get `https://dms-gmail-mcp.onrender.com`. `/health` is the health check.
(Manual alternative: New → **Web Service** → Docker runtime → add the env vars by hand.)
**Railway / Fly.io:** same idea — Docker deploy, set the env vars, grab the public URL.
**Your own Raspberry Pi (you already have Tailscale):** `docker build -t dms-gmail-mcp . && docker run -p 8787:8787 --env-file .env dms-gmail-mcp`, then expose it with a Cloudflare Tunnel or Tailscale Funnel to get a public HTTPS URL.
> Vercel note: Vercel is serverless, so this Express/long-lived pattern isn't the natural fit —
> Render/Railway/Fly/your Pi are simpler for an MCP server. (Ping me if you specifically want a Vercel build; it needs the serverless adapter.)
---
## Add it to Claude
1. Verify it's alive: open `https://YOUR-URL/health` → should show `{"ok":true,"accounts":[...]}`.
2. In Claude: **Customize → Connectors → "+" → Add custom connector**.
3. **URL:** `https://YOUR-URL/mcp?token=YOUR_MCP_AUTH_TOKEN`
4. Add → enable it. Ask Claude: *"list my gmail accounts"* then *"search all accounts for subject:NEW LEAD newer_than:30d"*.
---
## Local test
```bash
npm install && npm run build && node --env-file .env dist/index.js
# then, in another terminal:
npx @modelcontextprotocol/inspector # point it at http://localhost:8787/mcp
```
## Security notes
- Keep `MCP_AUTH_TOKEN` secret — anyone with the URL+token can read the mailboxes.
- Scope is read-only; rotate a refresh token by re-running `get-token` and replacing it.
- Nothing is stored server-side; each request authenticates fresh with Google.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues