# Gmail MCP Server
An MCP (Model Context Protocol) server that lets an AI assistant:
- Read your unread Gmail messages via the Gmail API
- Create properly threaded **draft replies** in Gmail
Built for the Anthropic programme foundation project as an end-to-end example.
---
## Features
### `get_unread_emails(maxResults: int = 10)`
Fetches unread emails from your inbox and returns a JSON structure:
```json
{
"emails": [
{
"id": "string",
"threadId": "string",
"from": "string",
"subject": "string",
"snippet": "string",
"internalDate": "string"
}
]
}
```
Fields:
- `id` – Gmail message ID
- `threadId` – Gmail thread ID (used when replying)
- `from` – sender
- `subject` – email subject
- `snippet` – short preview of the message
- `internalDate` – message timestamp (ms since epoch, as string)
### `create_draft_reply(threadId: str, replyBody: str)`
Creates a **draft reply** in the specified Gmail thread.
Returns a JSON structure:
```json
{
"draftId": "string | null",
"threadId": "string",
"to": "string",
"subject": "string"
}
```
- Correctly threads the reply using `In-Reply-To` and `References` headers.
- Leaves the draft in your Gmail Drafts folder for manual review / sending.
OAuth tokens are stored locally in `token.json` and refreshed automatically.
---
## Architecture / Tech Stack
- **Language:** Python 3
- **MCP server:** [`mcp` Python SDK (FastMCP)](https://pypi.org/project/mcp/)
- **Gmail API client:** `google-api-python-client`, `google-auth-oauthlib`
- **Client:** Claude Desktop using MCP over stdio
---
## Prerequisites
- Python 3.10+ installed
- Claude Desktop installed
- A Google account with access to Gmail
- A Google Cloud project with the Gmail API enabled
---
## Setup
1. **Clone the repository and create a virtual environment**
```bash
git clone <your-repo-url> gmail-mcp-server
cd gmail-mcp-server
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
pip install -r requirements.txt
```
2. **Create a Google Cloud project & enable Gmail API**
- Go to the Google Cloud Console.
- Create (or select) a project.
- Enable **Gmail API** for that project.
- Configure the OAuth consent screen (External / Testing is fine for personal use).
3. **Create OAuth credentials**
- In **APIs & Services → Credentials**, create an **OAuth client ID**.
- Application type: **Desktop app**.
- Download the JSON file and save it in the project root as:
```text
credentials.json
```
4. **First-time Gmail authentication (optional sanity check)**
The project includes a small script to verify Gmail is configured correctly:
```bash
source .venv/bin/activate
python debug_gmail.py
```
This will:
- Open a browser window asking you to sign in and approve Gmail scopes.
- Save a local `token.json` file for future runs.
- Print the IDs of your unread messages.
5. **Ignore local secrets and environment-specific files**
Make sure your `.gitignore` (in this repo) includes at least:
```gitignore
.venv/
__pycache__/
credentials.json
token.json
*.log
```
These files must **never** be committed to GitHub.
---
## Claude Desktop Configuration
Claude Desktop uses `claude_desktop_config.json` to know how to launch MCP servers.
On macOS this file is usually at:
```text
~/Library/Application Support/Claude/claude_desktop_config.json
```
Add (or merge) the following configuration:
```json
{
"mcpServers": {
"gmail-mcp-server": {
"command": "/Users/<you>/Code/gmail-mcp-server/.venv/bin/python",
"args": [
"/Users/<you>/Code/gmail-mcp-server/server.py"
],
"env": {
"GMAIL_CREDENTIALS_PATH": "/Users/<you>/Code/gmail-mcp-server/credentials.json"
}
}
}
}
```
Replace `/Users/<you>/Code/gmail-mcp-server` with the actual path to this project on your machine.
After editing the file, **quit and restart Claude Desktop** so it picks up the new MCP server.
---
## Usage in Claude
Once Claude Desktop is restarted, open a new chat and try:
### List and summarise unread emails
> “Use the `gmail-mcp-server` tools to call `get_unread_emails` with `maxResults` 5, then summarise the emails.”
Claude will:
- Call the `get_unread_emails` tool.
- Receive the JSON list of unread emails.
- Summarise them in natural language.
### Inspect raw JSON (for debugging / demo)
> “Call `get_unread_emails` with `maxResults` 3 and show me the raw JSON output.”
### Create a draft reply
1. First fetch unread emails and inspect the JSON to find a `threadId`.
2. Then:
> “Use the `gmail-mcp-server` tools to call `create_draft_reply` with this `threadId`: `<PASTE_THREAD_ID>` and a reply body that politely confirms I received their email and proposes a call next week. Tell me what `draftId` was created.”
3. Open Gmail → **Drafts** to see the newly created reply in the correct thread.
---
## Screenshots (for project submission)
Suggested screenshots to include in your submission / repo:
- Claude calling `get_unread_emails` and showing the JSON result.
- Claude summarising the unread emails.
- Claude calling `create_draft_reply` and reporting the created `draftId`.
- Gmail UI showing the draft reply in the correct thread.
Place them in a `screenshots/` folder and reference them in your application as needed.
---
## Security Notes
- This server is intended for **local, personal use** as a learning/demo project.
- `credentials.json` and `token.json` are sensitive and must remain local.
- Scopes are limited to:
- `gmail.readonly` – reading messages
- `gmail.compose` – creating drafts
- The server does **not** send credentials or email content to any third-party service other than Gmail and the local Claude Desktop client.