Gmail MCP Server
A Model Context Protocol server that lets an AI assistant (Claude Desktop, Claude API, etc.) read unread Gmail messages and create threaded draft replies — without ever sending email automatically.
---
What this server does
| Tool | Description | |------|-------------| | get_unread_emails | Returns up to 50 unread inbox messages: sender, subject, date, body, and IDs | | create_draft_reply | Saves a threaded draft reply in Gmail Drafts (user must send manually) | | get_reply_context | (Stretch goal) Returns a style guide, templates, and knowledge-base snippets to guide better replies |
The server communicates with Claude Desktop over stdio using the MCP JSON-RPC protocol. It never sends email — only creates drafts.
---
Prerequisites
- Python 3.10+
- A Google account
- Claude Desktop installed
---
Quick start
1. Clone and install
git clone <this-repo>
cd gmail-mcp-server
bash scripts/setup.sh
source .venv/bin/activate
2. Set up Gmail API credentials
Follow the detailed guide in docs/gmail_api_setup.md.
Summary:
- Create a Google Cloud project.
- Enable the Gmail API.
- Configure the OAuth consent screen (External, test mode is fine).
- Add scopes:
gmail.readonly+gmail.compose. - Create an OAuth 2.0 Desktop App credential.
- Download
credentials.json→ place in project root.
3. Authenticate
python scripts/auth_check.py
A browser window opens. Sign in and approve access. token.pickle is saved.
4. Test the server manually
# Start the server (press Ctrl-C to stop)
gmail-mcp
The server waits for JSON-RPC on stdin. You can send a test message:
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | gmail-mcp
5. Configure Claude Desktop
Edit claude_desktop_config.json (see docs/claude_desktop_config.md):
{
"mcpServers": {
"gmail": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["-m", "gmail_mcp_server.server"],
"cwd": "/absolute/path/to/gmail-mcp-server",
"env": {
"GMAIL_CREDENTIALS_PATH": "/absolute/path/to/credentials.json",
"GMAIL_TOKEN_PATH": "/absolute/path/to/token.pickle"
}
}
}
}
Restart Claude Desktop. The gmail tools will appear automatically.
---
Example Claude prompts
Check my unread emails and tell me which ones need urgent attention.
I have an unread email about a refund request. Draft a polite reply
using our style guide, then save it as a draft.
Fetch my 5 newest unread emails. For each one, tell me the sender,
subject, and a one-sentence summary.
Use get_reply_context to see our templates, then create a draft reply
to the meeting invite email.
---
Project structure
gmail-mcp-server/
├── src/
│ └── gmail_mcp_server/
│ ├── __init__.py
│ ├── server.py # MCP server entry point & tool definitions
│ ├── auth.py # OAuth 2.0 credential management
│ ├── gmail_tools.py # Gmail API logic (read emails, create drafts)
│ └── context.py # Stretch-goal: style guide, templates, KB search
├── context/
│ ├── style_guide.md # Writing style guide (edit to match your voice)
│ ├── templates.json # Reply templates
│ └── knowledge_base/ # .md/.txt files Claude can search
├── scripts/
│ ├── setup.sh # One-time environment setup
│ └── auth_check.py # OAuth flow + credential verification
├── docs/
│ ├── mcp_concepts.md # How MCP tools work (detailed explanation)
│ ├── gmail_api_setup.md # Step-by-step Google Cloud setup
│ └── claude_desktop_config.md # Claude Desktop config + example prompts
├── pyproject.toml
├── .env.example
└── .gitignore
---
How MCP tools work (summary)
MCP tools are callable functions that an LLM can invoke via JSON-RPC:
- Discovery — Claude calls
tools/list; the server returns tool names,
descriptions, and JSON Schemas for their arguments.
- Decision — The LLM decides which tool to call based on the description
and the user's request.
- Invocation — Claude calls
tools/callwith the tool name and arguments. - Result — The server returns a
TextContentblock (JSON string) that
Claude reads and incorporates into its response.
See docs/mcp_concepts.md for a full explanation with sequence diagrams and annotated code.
---
Stretch goal: external context
The get_reply_context tool pulls in:
- Style guide (
context/style_guide.md) – tone, structure, phrases to use/avoid. - Templates (
context/templates.json) – starting points for common reply types. - Knowledge base (
context/knowledge_base/) – searched by keyword.
To connect real cloud sources:
- Google Docs – enable the Docs API, add
documents.readonlyscope,
fetch document content via docs.documents().get().
- Notion – install
notion-client, query a database with your integration token. - Vector search – replace
search_knowledge_base()incontext.pywith
chromadb or hnswlib for semantic search over larger document sets.
---
Security notes
credentials.jsonandtoken.pickleare in.gitignore— never commit them.- The server only requests
gmail.readonlyandgmail.composescopes. - No email is ever sent automatically;
create_draft_replyonly calls
drafts.create, not messages.send.
- The OAuth consent screen is in "Testing" mode by default — only you can authenticate.
---
Troubleshooting
| Problem | Fix | |---------|-----| | Tools don't appear in Claude Desktop | Check command path uses .venv/bin/python; restart Claude Desktop | | credentials.json not found | Download from Google Cloud Console and place in project root | | Access blocked in browser | Add your email to Test Users in OAuth consent screen | | Token revoked error | Delete token.pickle and re-run auth_check.py | | Empty email body | Email may be HTML-only; gmail_tools.py extracts text/plain parts |
For more, see docs/gmail_api_setup.md.
---
License
MIT






