gmail-mcp
Provides full control over Gmail for AI agents, including reading, composing, labeling, filtering, threading, and account management tools.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@gmail-mcpshow me my unread emails from yesterday"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Gmail MCP Server
Full Gmail control for any MCP-compatible AI agent. Exposes ~40 tools covering reading, composing, labeling, filtering, threading, and account management — works with Claude, Cursor, Copilot, Goose, OpenCode, and any agent that speaks the MCP stdio protocol.
Requirements
Python 3.10+
A Google account
Any MCP-compatible AI agent (Claude Code, Cursor, Copilot, Goose, OpenCode, etc.)
Related MCP server: Gmail MCP Server
Quick Install (Linux)
Detects Arch or Ubuntu/Debian automatically, creates a virtualenv, installs deps, sets credential permissions, and prints the MCP config snippet ready to paste:
bash install.shManual steps follow below if you prefer full control.
1. Python Dependencies
pip install -r requirements.txtrequirements.txt:
mcp
google-api-python-client
google-auth-oauthlib
google-auth-httplib22. Google Cloud Console Setup
2.1 Create a Project
Click the project dropdown (top-left) → New Project
Name it (e.g.
gmail-mcp) → CreateMake sure the new project is selected in the dropdown
2.2 Enable the Gmail API
Go to APIs & Services → Library
Search for
Gmail API→ click it → Enable
2.3 Configure the OAuth Consent Screen
Go to APIs & Services → OAuth consent screen
Choose External → Create
Fill in:
App name: anything (e.g.
Gmail MCP)User support email: your Gmail address
Developer contact email: your Gmail address
Click Save and Continue through Scopes (skip adding scopes here)
On the Test users page → Add users → add your Gmail address
Click Save and Continue → Back to Dashboard
Important: While the app is in Testing mode only the users listed here can authenticate. The app does not need to be published.
2.4 Add Required OAuth Scopes
Go to APIs & Services → OAuth consent screen → Edit App
On the Scopes step → Add or Remove Scopes
Search for and select each of the following:
Scope
Why
https://mail.google.com/Full read/write/delete/send access
https://www.googleapis.com/auth/gmail.settings.basicCreate/manage filters and labels
Click Update → Save and Continue
gmail.settings.basicis required specifically forfilters.create/filters.delete.mail.google.comalone is not sufficient for filter management despite appearing to be a superset scope.
2.5 Create OAuth Credentials
Go to APIs & Services → Credentials
+ Create Credentials → OAuth client ID
Application type: Desktop app
Name: anything → Create
Click Download JSON on the resulting dialog
Save the downloaded file as
credentials.jsonin this project directory
3. First-Run Authentication
Run the server once manually to trigger the OAuth browser flow:
python server.pyA browser window opens. Log in with the Google account added as a test user and grant both requested permissions.
This writes token.pickle to the project directory. Subsequent runs use this token silently (auto-refreshed by Google's OAuth library).
If you change the requested scopes (e.g. add gmail.settings.basic later), the old token must be deleted:
rm token.pickle
python server.py4. Register with AI Coding Assistants
All tools below use the same MCP stdio transport. The only difference between them is where the config file lives.
Common values to substitute throughout:
PYTHON→ full path to the Python binary with dependencies (e.g./home/user/.local/share/mamba/bin/python)SERVER→ full path toserver.py(e.g./home/user/gmail/server.py)
Claude Code
~/.claude.json:
{
"mcpServers": {
"gmail": {
"type": "stdio",
"command": "PYTHON",
"args": ["SERVER"],
"env": {}
}
}
}~/.claude/settings.json:
{
"mcpServers": {
"gmail": {
"command": "PYTHON",
"args": ["SERVER"]
}
}
}Restart Claude Code after editing.
Cursor
Global config ~/.cursor/mcp.json (or per-project .cursor/mcp.json):
{
"mcpServers": {
"gmail": {
"command": "PYTHON",
"args": ["SERVER"]
}
}
}Reload via Cursor Settings → MCP or restart Cursor.
Windsurf (Codeium)
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"gmail": {
"command": "PYTHON",
"args": ["SERVER"]
}
}
}Reload via Windsurf Settings → MCP Servers → Refresh.
GitHub Copilot (VS Code)
VS Code 1.99+ supports MCP natively. Add to your User settings.json (Ctrl+Shift+P → Open User Settings JSON):
{
"mcp": {
"servers": {
"gmail": {
"type": "stdio",
"command": "PYTHON",
"args": ["SERVER"]
}
}
}
}Or create a workspace-scoped .vscode/mcp.json:
{
"servers": {
"gmail": {
"type": "stdio",
"command": "PYTHON",
"args": ["SERVER"]
}
}
}Copilot picks it up automatically. No restart needed.
Cline (VS Code extension)
Open the Cline sidebar → MCP Servers tab → Edit MCP Settings.
This opens cline_mcp_settings.json. Add:
{
"mcpServers": {
"gmail": {
"command": "PYTHON",
"args": ["SERVER"],
"disabled": false,
"autoApprove": []
}
}
}Linux path: ~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
Continue.dev
~/.continue/config.json:
{
"mcpServers": [
{
"name": "gmail",
"command": "PYTHON",
"args": ["SERVER"]
}
]
}Or ~/.continue/config.yaml:
mcpServers:
- name: gmail
command: PYTHON
args:
- SERVERReload with Ctrl+Shift+P → Continue: Reload Config.
Zed
~/.config/zed/settings.json:
{
"context_servers": {
"gmail": {
"command": {
"path": "PYTHON",
"args": ["SERVER"],
"env": {}
},
"settings": {}
}
}
}Zed reloads context servers automatically on save.
Amazon Q Developer
~/.aws/amazonq/mcp.json:
{
"mcpServers": {
"gmail": {
"command": "PYTHON",
"args": ["SERVER"]
}
}
}Restart the Q Developer extension or CLI after editing.
Goose (Block)
~/.config/goose/config.yaml:
extensions:
gmail:
name: gmail
type: stdio
cmd: PYTHON
args:
- SERVER
enabled: trueRun goose session — Goose loads extensions at startup.
OpenCode (SST)
~/.config/opencode/config.json:
{
"mcp": {
"gmail": {
"command": "PYTHON",
"args": ["SERVER"]
}
}
}5. Using Programmatically
Anthropic Python SDK
pip install anthropicimport anthropic
client = anthropic.Anthropic()
with client.beta.messages.stream(
model="claude-opus-4-8",
max_tokens=4096,
mcp_servers=[{
"type": "stdio",
"command": "PYTHON",
"args": ["SERVER"],
}],
messages=[{"role": "user", "content": "List my last 5 unread emails."}],
betas=["mcp-client-2025-04-04"],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)OpenAI Agents SDK
pip install openai-agentsimport asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
async def main():
async with MCPServerStdio(
params={"command": "PYTHON", "args": ["SERVER"]}
) as mcp:
agent = Agent(
name="gmail-agent",
instructions="You manage Gmail for the user.",
mcp_servers=[mcp],
)
result = await Runner.run(agent, "List my last 5 unread emails.")
print(result.final_output)
asyncio.run(main())Claude Code CLI (subprocess / headless)
claude --mcp-config /path/to/mcp-config.json \
-p "Summarize my unread emails from today."mcp-config.json:
{
"mcpServers": {
"gmail": {
"type": "stdio",
"command": "PYTHON",
"args": ["SERVER"]
}
}
}Token handling in headless / CI environments
The OAuth flow requires a browser the first time. For agents running headlessly:
Run the browser flow once on a machine with a display to produce
token.pickleCopy
token.pickleandcredentials.jsonto the headless machineThe server auto-refreshes the token via the stored refresh token — no browser needed after that
chmod 600 credentials.json token.pickleDo not pass secrets via environment variables.
6. Available Tools
Reading
Tool | Description |
| List/search messages (Gmail search syntax) |
| Full plain-text content of a message |
| HTML body of a message |
| List conversation threads |
| Full thread with all messages |
| List attachments on a message |
| Download attachment to local path |
Composing & Sending
Tool | Description |
| Send a new email |
| Reply to a thread |
| Forward a message |
| Save a draft |
| List drafts |
| Delete a draft |
Organization
Tool | Description |
| Move to trash |
| Restore from trash |
| Delete bypassing trash |
| Archive (remove from inbox) |
| Mark as spam |
| Mark as read |
| Mark as unread |
| Star a message |
| Unstar a message |
| Apply label by ID |
| Remove label by ID |
| Trash multiple messages |
| Permanently delete multiple messages |
| Archive multiple messages |
| Mark multiple messages read |
| Trash all messages matching a search |
| Archive all messages matching a search |
Labels
Tool | Description |
| List all labels (system + user) |
| Create a label (supports |
| Delete a label by ID |
| Rename a label |
Filters
Tool | Description |
| List all Gmail filters |
| Create a filter (from/to/subject/query + label actions) |
| Delete a filter by ID |
Account & Export
Tool | Description |
| Email address, message count, storage quota |
| Export all messages to JSON file (paginated) |
| Check progress of an ongoing export |
7. Troubleshooting
403 insufficientPermissions on filter operations
The token was created without gmail.settings.basic. Delete it and re-authenticate:
rm token.pickle
python server.pyVerify SCOPES in server.py contains both scopes:
SCOPES = [
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.settings.basic",
]Token has been expired or revoked
Delete token.pickle and re-authenticate. This happens if access is revoked in Google account settings or if the app has been inactive for 6+ months in testing mode.
redirect_uri_mismatch
The OAuth client must be type Desktop app, not Web application. Delete the existing client ID and create a new one with the correct type.
MCP tools not appearing in Claude Code
Confirm
credentials.jsonandtoken.pickleexist in the project directoryRun
python server.pymanually to check for import errorsRestart Claude Code after editing
~/.claude.jsonCheck that the Python path in the MCP config points to the environment where dependencies are installed
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ensismoebius/gmail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server