- Fixed reply threading — auto-resolves In-Reply-To and References headers so email replies land in the correct thread instead of creating orphaned messages (upstream PR 91, still pending) - Send-as alias support — optional from parameter for multi-identity email management (send from any configured Gmail alias) - Reply-all tool — replyall automatically fetches the original email, builds To/CC rec
Add this skill
npx mdskills install ArtyMcLabin/gmail-mcp-serverComprehensive Gmail MCP server with excellent security hardening, granular OAuth scoping, and robust threading/attachment support
This is an actively maintained fork of GongRzhe/Gmail-MCP-Server.
The original repository has been unmaintained since August 2025 — 7+ months with zero maintainer activity and 72+ unmerged pull requests. I use this MCP server daily as part of my Claude Code workflow and depend on it working correctly, so I picked it up.
Pull requests are welcome. If you've been sitting on fixes or features with nowhere to submit them, this is the place.
In-Reply-To and References headers so email replies land in the correct thread instead of creating orphaned messages (upstream PR #91, still pending)from parameter for multi-identity email management (send from any configured Gmail alias)reply_all automatically fetches the original email, builds To/CC recipient lists (excluding yourself), and sets proper threading headers (PR #3 by @MaxGhenis)list_filters — was returning empty array due to wrong response property name (PR #4 by @nicholas-anthony-ai)--scopes flag to request only the permissions you need, with automatic tool filtering (PR #6 by @tansanDOTeth)All features are production-tested in daily use.
A Model Context Protocol (MCP) server for Gmail integration in Claude Desktop with auto authentication support. This server enables AI assistants to manage Gmail through natural language interactions.
Create a Google Cloud Project and obtain credentials:
a. Create a Google Cloud Project:
b. Create OAuth 2.0 Credentials:
http://localhost:3000/oauth2callback to the authorized redirect URIsgcp-oauth.keys.jsonRun Authentication:
You can authenticate in two ways:
a. Global Authentication (Recommended):
# First time: Place gcp-oauth.keys.json in your home directory's .gmail-mcp folder
mkdir -p ~/.gmail-mcp
mv gcp-oauth.keys.json ~/.gmail-mcp/
# Run authentication from anywhere
npx @gongrzhe/server-gmail-autoauth-mcp auth
b. Local Authentication:
# Place gcp-oauth.keys.json in your current directory
# The file will be automatically copied to global config
npx @gongrzhe/server-gmail-autoauth-mcp auth
The authentication process will:
gcp-oauth.keys.json in the current directory or ~/.gmail-mcp/~/.gmail-mcp/~/.gmail-mcp/credentials.jsonNote:
- After successful authentication, credentials are stored globally in
~/.gmail-mcp/and can be used from any directory- Both Desktop app and Web application credentials are supported
- For Web application credentials, make sure to add
http://localhost:3000/oauth2callbackto your authorized redirect URIs
Configure in Claude Desktop:
{
"mcpServers": {
"gmail": {
"command": "npx",
"args": [
"@gongrzhe/server-gmail-autoauth-mcp"
]
}
}
}
If you prefer using Docker:
docker run -i --rm \
--mount type=bind,source=/path/to/gcp-oauth.keys.json,target=/gcp-oauth.keys.json \
-v mcp-gmail:/gmail-server \
-e GMAIL_OAUTH_PATH=/gcp-oauth.keys.json \
-e "GMAIL_CREDENTIALS_PATH=/gmail-server/credentials.json" \
-p 3000:3000 \
mcp/gmail auth
{
"mcpServers": {
"gmail": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"mcp-gmail:/gmail-server",
"-e",
"GMAIL_CREDENTIALS_PATH=/gmail-server/credentials.json",
"mcp/gmail"
]
}
}
}
For cloud server environments (like n8n), you can specify a custom callback URL during authentication:
npx @gongrzhe/server-gmail-autoauth-mcp auth https://gmail.gongrzhe.com/oauth2callback
Configure Reverse Proxy:
gmail.gongrzhe.com) to this portDNS Configuration:
Google Cloud Platform Setup:
https://gmail.gongrzhe.com/oauth2callback) to the authorized redirect URIs listRun Authentication:
npx @gongrzhe/server-gmail-autoauth-mcp auth https://gmail.gongrzhe.com/oauth2callback
Configure in your application:
{
"mcpServers": {
"gmail": {
"command": "npx",
"args": [
"@gongrzhe/server-gmail-autoauth-mcp"
]
}
}
}
This approach allows authentication flows to work properly in environments where localhost isn't accessible, such as containerized applications or cloud servers.
You can limit the server's Gmail access by specifying OAuth scopes during authentication. This controls which tools are available to the LLM, reducing the attack surface for sensitive operations.
| Scope | Description |
|---|---|
gmail.readonly | Read-only access to emails (search, read, download attachments) |
gmail.modify | Full read/write access to emails (superset of readonly - includes sending, modifying, deleting) |
gmail.compose | Create drafts and send emails only |
gmail.send | Send emails only |
gmail.labels | Manage labels only |
gmail.settings.basic | Manage filters and settings |
Note:
gmail.modifyis a superset that includes all read capabilities. You don't needgmail.readonlyif you havegmail.modify.
Use the --scopes flag to request only the permissions you need:
# Read-only access (recommended for safe browsing)
npx @gongrzhe/server-gmail-autoauth-mcp auth --scopes=gmail.readonly
# Read-only with filter management
npx @gongrzhe/server-gmail-autoauth-mcp auth --scopes=gmail.readonly,gmail.settings.basic
# Full access (default behavior)
npx @gongrzhe/server-gmail-autoauth-mcp auth --scopes=gmail.modify,gmail.settings.basic
If no --scopes flag is provided, the server defaults to gmail.modify,gmail.settings.basic for full functionality.
The server automatically filters available tools based on your authorized scopes:
| Tools | Required Scope (any) |
|---|---|
read_email, search_emails, download_attachment | gmail.readonly or gmail.modify |
list_email_labels | gmail.readonly, gmail.modify, or gmail.labels |
send_email, draft_email, reply_all | gmail.modify, gmail.compose, or gmail.send |
modify_email, delete_email, batch_modify_emails, batch_delete_emails | gmail.modify |
create_label, update_label, delete_label, get_or_create_label | gmail.modify or gmail.labels |
list_filters, get_filter, create_filter, delete_filter, create_filter_from_template | gmail.settings.basic |
To change your scopes, simply run the auth command again with different scopes. This will replace your existing credentials.
To use this MCP server with Claude Code, add it to your MCP settings.
First, authenticate with read-only scope:
npx @gongrzhe/server-gmail-autoauth-mcp auth --scopes=gmail.readonly
Then add to your Claude Code MCP settings (~/.claude/mcp_settings.json or project-level .mcp.json):
{
"mcpServers": {
"gmail": {
"command": "npx",
"args": ["@gongrzhe/server-gmail-autoauth-mcp"]
}
}
}
With read-only scopes, only these 4 tools will be available to Claude:
read_email - Read email contentsearch_emails - Search your inboxlist_email_labels - List available labelsdownload_attachment - Download attachmentsFor full Gmail management capabilities:
npx @gongrzhe/server-gmail-autoauth-mcp auth --scopes=gmail.modify,gmail.settings.basic
{
"mcpServers": {
"gmail": {
"command": "npx",
"args": ["@gongrzhe/server-gmail-autoauth-mcp"]
}
}
}
This enables all 20 tools including sending emails, managing labels, creating filters, reply-all, and batch operations.
The server provides the following tools that can be used through Claude Desktop:
send_email)Sends a new email immediately. Supports plain text, HTML, or multipart emails with optional file attachments.
Basic Email:
{
"to": ["recipient@example.com"],
"subject": "Meeting Tomorrow",
"body": "Hi,\n\nJust a reminder about our meeting tomorrow at 10 AM.\n\nBest regards",
"cc": ["cc@example.com"],
"bcc": ["bcc@example.com"],
"mimeType": "text/plain"
}
Email with Attachments:
{
"to": ["recipient@example.com"],
"subject": "Project Files",
"body": "Hi,\n\nPlease find the project files attached.\n\nBest regards",
"attachments": [
"/path/to/document.pdf",
"/path/to/spreadsheet.xlsx",
"/path/to/presentation.pptx"
]
}
HTML Email Example:
{
"to": ["recipient@example.com"],
"subject": "Meeting Tomorrow",
"mimeType": "text/html",
"body": "Meeting ReminderJust a reminder about our meeting tomorrow at 10 AM.
Best regards
"
}
Multipart Email Example (HTML + Plain Text):
{
"to": ["recipient@example.com"],
"subject": "Meeting Tomorrow",
"mimeType": "multipart/alternative",
"body": "Hi,\n\nJust a reminder about our meeting tomorrow at 10 AM.\n\nBest regards",
"htmlBody": "Meeting ReminderJust a reminder about our meeting tomorrow at 10 AM.
Best regards
"
}
draft_email)Creates a draft email without sending it. Also supports attachments.
{
"to": ["recipient@example.com"],
"subject": "Draft Report",
"body": "Here's the draft report for your review.",
"cc": ["manager@example.com"],
"attachments": ["/path/to/draft_report.docx"]
}
read_email)Retrieves the content of a specific email by its ID. Now shows enhanced attachment information.
{
"messageId": "182ab45cd67ef"
}
Enhanced Response includes attachment details:
Subject: Project Files
From: sender@example.com
To: recipient@example.com
Date: Thu, 19 Jun 2025 10:30:00 -0400
Email body content here...
Attachments (2):
- document.pdf (application/pdf, 245 KB, ID: ANGjdJ9fkTs-i3GCQo5o97f_itG...)
- spreadsheet.xlsx (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, 89 KB, ID: BWHkeL8gkUt-j4HDRp6o98g_juI...)
download_attachment)NEW: Downloads email attachments to your local filesystem.
{
"messageId": "182ab45cd67ef",
"attachmentId": "ANGjdJ9fkTs-i3GCQo5o97f_itG...",
"savePath": "/path/to/downloads",
"filename": "downloaded_document.pdf"
}
Parameters:
messageId: The ID of the email containing the attachmentattachmentId: The attachment ID (shown in enhanced email display)savePath: Directory to save the file (optional, defaults to current directory)filename: Custom filename (optional, uses original filename if not provided)search_emails)Searches for emails using Gmail search syntax.
{
"query": "from:sender@example.com after:2024/01/01 has:attachment",
"maxResults": 10
}
modify_email)Adds or removes labels from emails (move to different folders, archive, etc.).
{
"messageId": "182ab45cd67ef",
"addLabelIds": ["IMPORTANT"],
"removeLabelIds": ["INBOX"]
}
delete_email)Permanently deletes an email.
{
"messageId": "182ab45cd67ef"
}
list_email_labels)Retrieves all available Gmail labels.
{}
create_label)Creates a new Gmail label.
{
"name": "Important Projects",
"messageListVisibility": "show",
"labelListVisibility": "labelShow"
}
update_label)Updates an existing Gmail label.
{
"id": "Label_1234567890",
"name": "Urgent Projects",
"messageListVisibility": "show",
"labelListVisibility": "labelShow"
}
delete_label)Deletes a Gmail label.
{
"id": "Label_1234567890"
}
get_or_create_label)Gets an existing label by name or creates it if it doesn't exist.
{
"name": "Project XYZ",
"messageListVisibility": "show",
"labelListVisibility": "labelShow"
}
batch_modify_emails)Modifies labels for multiple emails in efficient batches.
{
"messageIds": ["182ab45cd67ef", "182ab45cd67eg", "182ab45cd67eh"],
"addLabelIds": ["IMPORTANT"],
"removeLabelIds": ["INBOX"],
"batchSize": 50
}
batch_delete_emails)Permanently deletes multiple emails in efficient batches.
{
"messageIds": ["182ab45cd67ef", "182ab45cd67eg", "182ab45cd67eh"],
"batchSize": 50
}
create_filter)Creates a new Gmail filter with custom criteria and actions.
{
"criteria": {
"from": "newsletter@company.com",
"hasAttachment": false
},
"action": {
"addLabelIds": ["Label_Newsletter"],
"removeLabelIds": ["INBOX"]
}
}
list_filters)Retrieves all Gmail filters.
{}
get_filter)Gets details of a specific Gmail filter.
{
"filterId": "ANe1Bmj1234567890"
}
delete_filter)Deletes a Gmail filter.
{
"filterId": "ANe1Bmj1234567890"
}
create_filter_from_template)Creates a filter using pre-defined templates for common scenarios.
{
"template": "fromSender",
"parameters": {
"senderEmail": "notifications@github.com",
"labelIds": ["Label_GitHub"],
"archive": true
}
}
reply_all)Replies to all recipients of an email. Automatically fetches the original email to build the recipient list and sets proper threading headers (In-Reply-To, References, threadId).
How it works:
messageIdsend_email pipeline (supports attachments, HTML, multipart){
"messageId": "182ab45cd67ef",
"body": "Thanks for the update, everyone. I'll review and get back to you.",
"mimeType": "text/plain"
}
With HTML and attachments:
{
"messageId": "182ab45cd67ef",
"body": "Plain text fallback",
"htmlBody": "Thanks for the update. See attached notes.
",
"mimeType": "multipart/alternative",
"attachments": ["/path/to/notes.pdf"]
}
Parameters:
messageId (required): ID of the email to reply tobody (required): Reply body (plain text, or fallback when using multipart)htmlBody (optional): HTML version of the reply bodymimeType (optional): text/plain (default), text/html, or multipart/alternativeattachments (optional): Array of file paths to attachYou can create filters based on various criteria:
| Criteria | Example | Description |
|---|---|---|
from | "sender@example.com" | Emails from a specific sender |
to | "recipient@example.com" | Emails sent to a specific recipient |
subject | "Meeting" | Emails with specific text in subject |
query | "has:attachment" | Gmail search query syntax |
negatedQuery | "spam" | Text that must NOT be present |
hasAttachment | true | Emails with attachments |
size | 10485760 | Email size in bytes |
sizeComparison | "larger" | Size comparison (larger, smaller) |
Filters can perform the following actions:
| Action | Example | Description |
|---|---|---|
addLabelIds | ["IMPORTANT", "Label_Work"] | Add labels to matching emails |
removeLabelIds | ["INBOX", "UNREAD"] | Remove labels from matching emails |
forward | "backup@example.com" | Forward emails to another address |
The server includes pre-built templates for common filtering scenarios:
fromSender)Filters emails from a specific sender and optionally archives them.
{
"template": "fromSender",
"parameters": {
"senderEmail": "newsletter@company.com",
"labelIds": ["Label_Newsletter"],
"archive": true
}
}
withSubject)Filters emails with specific subject text and optionally marks as read.
{
"template": "withSubject",
"parameters": {
"subjectText": "[URGENT]",
"labelIds": ["Label_Urgent"],
"markAsRead": false
}
}
withAttachments)Filters all emails with attachments.
{
"template": "withAttachments",
"parameters": {
"labelIds": ["Label_Attachments"]
}
}
largeEmails)Filters emails larger than a specified size.
{
"template": "largeEmails",
"parameters": {
"sizeInBytes": 10485760,
"labelIds": ["Label_Large"]
}
}
containingText)Filters emails containing specific text and optionally marks as important.
{
"template": "containingText",
"parameters": {
"searchText": "invoice",
"labelIds": ["Label_Finance"],
"markImportant": true
}
}
mailingList)Filters mailing list emails and optionally archives them.
{
"template": "mailingList",
"parameters": {
"listIdentifier": "dev-team",
"labelIds": ["Label_DevTeam"],
"archive": true
}
}
Here are some practical filter examples:
Auto-organize newsletters:
{
"criteria": {
"from": "newsletter@company.com"
},
"action": {
"addLabelIds": ["Label_Newsletter"],
"removeLabelIds": ["INBOX"]
}
}
Handle promotional emails:
{
"criteria": {
"query": "unsubscribe OR promotional"
},
"action": {
"addLabelIds": ["Label_Promotions"],
"removeLabelIds": ["INBOX", "UNREAD"]
}
}
Priority emails from boss:
{
"criteria": {
"from": "boss@company.com"
},
"action": {
"addLabelIds": ["IMPORTANT", "Label_Boss"]
}
}
Large attachments:
{
"criteria": {
"size": 10485760,
"sizeComparison": "larger",
"hasAttachment": true
},
"action": {
"addLabelIds": ["Label_LargeFiles"]
}
}
The search_emails tool supports Gmail's powerful search operators:
| Operator | Example | Description |
|---|---|---|
from: | from:john@example.com | Emails from a specific sender |
to: | to:mary@example.com | Emails sent to a specific recipient |
subject: | subject:"meeting notes" | Emails with specific text in the subject |
has:attachment | has:attachment | Emails with attachments |
after: | after:2024/01/01 | Emails received after a date |
before: | before:2024/02/01 | Emails received before a date |
is: | is:unread | Emails with a specific state |
label: | label:work | Emails with a specific label |
You can combine multiple operators: from:john@example.com after:2024/01/01 has:attachment
The server provides comprehensive attachment functionality:
attachments array when sending or drafting emailsSupported File Types: All standard file types including PDF, DOCX, XLSX, PPTX, images (PNG, JPG, GIF), archives (ZIP, RAR), and more.
The server intelligently extracts email content from complex MIME structures:
The server fully supports non-ASCII characters in email subjects and content, including:
The server provides a complete set of tools for managing Gmail labels:
Label visibility settings include:
messageListVisibility: Controls whether the label appears in the message list (show or hide)labelListVisibility: Controls how the label appears in the label list (labelShow, labelShowIfUnread, or labelHide)These label management features enable sophisticated organization of emails directly through Claude, without needing to switch to the Gmail interface.
The server includes efficient batch processing capabilities:
~/.gmail-mcp/)OAuth Keys Not Found
gcp-oauth.keys.json is in either your current directory or ~/.gmail-mcp/Invalid Credentials Format
web or installed credentialsPort Already in Use
Batch Operation Failures
Attachment Issues
Contributions are welcome! Please feel free to submit a Pull Request.
CI requires README updates — every push to main and every PR must include a README.md change (even a version bump or changelog entry). This ensures documentation stays current as the codebase evolves.
To bypass for commits that genuinely don't need a docs update (dependency bumps, CI config changes), include [skip-readme] or [no-readme] in your commit message or PR title.
The evals package loads an mcp client that then runs the index.ts file, so there is no need to rebuild between tests. You can load environment variables by prefixing the npx command. Full documentation can be found here.
OPENAI_API_KEY=your-key npx mcp-eval src/evals/evals.ts src/index.ts
MIT
If you encounter any issues or have questions, please file an issue.
Install via CLI
npx mdskills install ArtyMcLabin/gmail-mcp-serverMeeting Reminder is a free, open-source AI agent skill. - Fixed reply threading — auto-resolves In-Reply-To and References headers so email replies land in the correct thread instead of creating orphaned messages (upstream PR 91, still pending) - Send-as alias support — optional from parameter for multi-identity email management (send from any configured Gmail alias) - Reply-all tool — replyall automatically fetches the original email, builds To/CC rec
Install Meeting Reminder with a single command:
npx mdskills install ArtyMcLabin/gmail-mcp-serverThis downloads the skill files into your project and your AI agent picks them up automatically.
Meeting Reminder works with Claude Code, Claude Desktop, Cursor, Vscode Copilot, Windsurf, Continue Dev, Gemini Cli, Amp, Roo Code, Goose. Skills use the open SKILL.md format which is compatible with any AI coding agent that reads markdown instructions.