Gmail MCP Server
by dhagash2310
README.md
# Gmail MCP Server
[](https://www.python.org/downloads/)
[](LICENSE)
[](https://modelcontextprotocol.io)
A privacy-first [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude controlled, read-only access to your Gmail inbox. You define exactly which emails Claude can see — nothing else is exposed.
## Why this is different
Most Gmail MCP servers give Claude unrestricted access to your entire inbox. This one doesn't.
| Feature | gmail-mcp | Others |
|---------|-----------|--------|
| Filter by sender domain | Yes | No |
| Filter by label, date, subject, size | Yes | No |
| Block specific subject keywords | Yes | No |
| Per-request body privacy control | Yes | No |
| Access log (no email content) | Yes | No |
| Read-only OAuth scope | Yes | Some |
Your `config/filters.yaml` acts as a firewall — Claude's query is always ANDed with your rules, and it cannot be bypassed even if Claude tries to access a specific message ID directly.
---
## Prerequisites
### 1. Google API credentials
1. Go to [Google Cloud Console](https://console.cloud.google.com)
2. Create a new project (or select an existing one)
3. Enable the **Gmail API**: APIs & Services → Enable APIs → search "Gmail API" → Enable
4. Create OAuth credentials: APIs & Services → Credentials → Create Credentials → OAuth Client ID
- Application type: **Desktop app**
- Download the JSON file
5. Save it to `~/.gmail_mcp/credentials.json`
### 2. Configure your filters
Edit `config/filters.yaml` to control which emails Claude can access.
The file is heavily commented — every option is explained inline.
```yaml
filters:
from_addresses: ["trusted@example.com"] # Only emails from these senders
labels: ["INBOX"] # Only emails with these labels
unread_only: false # Set true for unread only
date_after: "2025-01-01" # Ignore older emails
subject_exclude: ["unsubscribe"] # Skip marketing emails
max_results: 50 # Cap per request
privacy:
allow_full_body: false # Keep false unless you need it
```
---
## Option A — Claude Desktop (local, no tunnel needed)
Best for: everyday use with the Claude Desktop app on Mac or Windows.
The server runs as a local subprocess over `stdio` — no port, no URL, no Docker required.
**Install:**
```bash
git clone https://github.com/dhagash2310/gmail-mcp.git
cd gmail-mcp
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
```
**First run (OAuth login):**
```bash
gmail-mcp
```
A browser window opens. Log in and grant access. Your token is saved to `~/.gmail_mcp/token.json`.
**Add to Claude Desktop:**
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) or
`%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"gmail": {
"command": "/path/to/gmail-mcp/.venv/bin/gmail-mcp",
"env": {
"GMAIL_CREDENTIALS_PATH": "/Users/you/.gmail_mcp/credentials.json",
"GMAIL_FILTER_CONFIG_PATH": "/path/to/gmail-mcp/config/filters.yaml"
}
}
}
}
```
Restart Claude Desktop. The Gmail tools will appear automatically.
---
## Option B — Docker + ngrok (Claude.ai browser version)
Best for: using the server with Claude.ai in your browser, or any other MCP-compatible web client (ChatGPT, etc.).
Claude.ai is a cloud app and cannot reach `localhost` directly, so you run the server in HTTP mode and use [ngrok](https://ngrok.com) to give it a public HTTPS URL.
### Step 1 — Complete OAuth login (first time only)
The container handles headless auth — it prints a URL for you to open in your browser and paste the code back.
```bash
mkdir -p ~/.gmail_mcp
cp /path/to/your/credentials.json ~/.gmail_mcp/credentials.json
docker compose run --rm gmail-mcp
# Opens a URL — open it in your browser, approve access, paste the code back
# Token is saved to ~/.gmail_mcp/token.json
```
### Step 2 — Start the server
```bash
docker compose up -d
# Server runs at http://localhost:8000/mcp
```
### Step 3 — Expose with ngrok
```bash
# Install ngrok: https://ngrok.com/download or brew install ngrok
ngrok http 8000
# You'll see a public URL like: https://abc123.ngrok-free.app
```
### Step 4 — Connect Claude.ai
1. Go to **claude.ai → Settings → Connectors**
2. Click **Add custom connector**
3. Enter your ngrok URL with the `/mcp` path:
```
https://abc123.ngrok-free.app/mcp
```
4. Save — the Gmail tools will appear in your next conversation.
> **Note:** The ngrok URL changes each time you restart ngrok (on the free plan). You'll need to update the connector URL in Claude.ai when that happens. A paid ngrok plan gives you a stable domain.
### Updating filters without restarting
The `config/filters.yaml` file is mounted into the container. Edit it on your host machine and call the `apply_filters` tool in Claude to reload it — no restart needed.
---
## Available Tools
| Tool | Description |
|------|-------------|
| `preview_filters` | Show active filter rules without fetching any email |
| `apply_filters` | Reload and display the current filter configuration |
| `fetch_emails` | Fetch emails matching your filter config |
| `search_emails` | Search emails — your query is ANDed with the active filters |
| `get_email_metadata` | Get details for a specific email (filter-verified) |
---
## Privacy & Security
- **Read-only access**: Only `gmail.readonly` scope is requested — Claude cannot send, delete, or modify emails
- **Filter enforcement**: Every tool call enforces your `filters.yaml` rules before returning data
- **No body by default**: Only metadata and 200-character snippets are returned unless you enable `allow_full_body` in `filters.yaml`
- **Access logging**: Every tool call is logged to `~/.gmail_mcp/access.log` (no email content in the log)
- **Local only**: No data is sent to any third-party service — the server runs entirely on your machine
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues