Skip to main content
Glama
dhagash2310

Gmail MCP Server

by dhagash2310
README.md
# Gmail MCP Server

[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/MCP-compatible-purple.svg)](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