Gmail MCP Server
README.md
# Gmail MCP Server
A custom MCP server that gives Claude full Gmail control — send directly (no drafts), read, reply, search, label, and delete — over stdio for Claude Desktop and Cowork.
---
## Folder Structure
```
gmail-mcp-server/
├── src/
│ ├── server.ts ← MCP entry point, registers all tools
│ ├── auth.ts ← OAuth2 flow + token refresh
│ ├── gmail-client.ts ← Gmail API wrapper
│ ├── templates.ts ← HTML email templates
│ ├── config.ts ← Env var loader
│ ├── logger.ts ← Structured stderr logger
│ └── tools/
│ ├── send-email.ts ← send_email
│ ├── send-bulk-email.ts ← send_bulk_email
│ ├── send-template-email.ts← send_template_email + list_templates
│ ├── list-emails.ts ← list_emails, get_email, reply_email
│ └── search-emails.ts ← search_emails, list_labels, add_label, move_email, delete_email
├── .env.example
├── claude_desktop_config.example.json
├── tsconfig.json
└── package.json
```
---
## Step 1 — Google Cloud Console Setup (One-time)
1. Go to https://console.cloud.google.com
2. Create a new project (or use existing)
3. Enable the **Gmail API**:
- APIs & Services → Library → search "Gmail API" → Enable
4. Create OAuth2 credentials:
- APIs & Services → Credentials → Create Credentials → OAuth client ID
- Application type: **Desktop app**
- Name: `gmail-mcp-server`
- Click **Create** → Copy the **Client ID** and **Client Secret**
5. Configure OAuth consent screen:
- OAuth consent screen → External → Add your Gmail as a test user
- Add scopes: `gmail.send`, `gmail.readonly`, `gmail.modify`
---
## Step 2 — Project Setup
```bash
# 1. Install dependencies
npm install
# 2. Create your .env file
cp .env.example .env
# 3. Edit .env and fill in your credentials
# GOOGLE_CLIENT_ID=your_client_id
# GOOGLE_CLIENT_SECRET=your_client_secret
# SENDER_NAME=Your Name
```
---
## Step 3 — Authenticate (One-time)
```bash
npm run auth
```
This will:
1. Print a Google auth URL
2. You open it in your browser, sign in, approve permissions
3. Paste the code back into the terminal
4. `token.json` is saved — never needs to be repeated
---
## Step 4 — Build
```bash
npm run build
```
This compiles TypeScript → `dist/` folder.
---
## Step 5 — Connect to Claude Desktop
Edit your Claude Desktop config file:
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
Add the gmail server block (replace paths with your actual absolute paths):
```json
{
"mcpServers": {
"gmail": {
"command": "node",
"args": ["/Users/yourname/gmail-mcp-server/dist/server.js"],
"env": {
"GOOGLE_CLIENT_ID": "your_client_id",
"GOOGLE_CLIENT_SECRET": "your_client_secret",
"TOKEN_PATH": "/Users/yourname/gmail-mcp-server/token.json",
"SENDER_NAME": "Your Name",
"LOG_LEVEL": "info"
}
}
}
}
```
**Restart Claude Desktop.** The gmail tools will appear in Claude's tool list.
---
## Step 6 — Connect to Cowork
In Cowork, add a local MCP server with:
- **Command:** `node /absolute/path/to/gmail-mcp-server/dist/server.js`
- **Environment variables:** same as above
---
## Available Tools
| Tool | What it does |
|---|---|
| `send_email` | Send directly to one or more recipients |
| `send_bulk_email` | Send same email to up to 50 recipients |
| `send_template_email` | Send HTML email using a template |
| `list_templates` | See all templates and their variables |
| `list_emails` | List inbox / any label with optional query |
| `get_email` | Read full email by message ID |
| `reply_email` | Reply in-thread to an email |
| `search_emails` | Full Gmail search query support |
| `list_labels` | See all labels and their IDs |
| `add_label` | Add labels to an email |
| `move_email` | Move / archive / mark read |
| `delete_email` | Move to Trash |
---
## Example Prompts for Claude
```
Send an email to john@example.com with subject "Hello" and body "Let's connect!"
Search my emails for invoices from last month
Reply to message ID <id> saying "Thanks, I'll review this today"
Send the welcome template to sarah@example.com with name="Sarah" and company="Acme"
List my unread emails in INBOX
Move email <id> to archive (remove INBOX label)
```
---
## Adding New Templates
Edit `src/templates.ts` and add a new entry to the `TEMPLATES` object.
Then rebuild: `npm run build`
---
## Development (no build needed)
```bash
npm run dev # runs via tsx directly
```
---
## Troubleshooting
| Problem | Fix |
|---|---|
| `Missing required env var` | Check your `.env` file or the env block in Claude Desktop config |
| `Token expired` | Run `npm run auth` again |
| `Permission denied` on Gmail API | Make sure Gmail API is enabled in Google Cloud Console |
| Claude doesn't see tools | Restart Claude Desktop after editing config |
| Server crashes silently | Check `LOG_LEVEL=debug` and watch stderr output |
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues