Provides read-only access to Gmail, enabling users to list messages, search using Gmail query syntax, and read full email content with support for label-based filtering and automatic Markdown conversion.
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 MCP ServerSummarize my unread emails from today"
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
A Model Context Protocol (MCP) server that provides read-only Gmail access to Claude CLI with label-based filtering and container deployment support.
Why Use This?
Security first: Read-only access means Claude cannot send, delete, or modify your emails. Label filtering lets you restrict which emails are visible.
Summarize important information: Let Claude read and summarize emails so you can quickly understand what matters.
Never miss important emails: Avoid overlooks by having Claude search and highlight critical information buried in your inbox.
Save time: Quickly find and understand email content without manual searching through hundreds of messages.
Quick start:
Configure Claude CLI to trust your certificate (if self-signed):
export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pemAdd the server:
claude mcp add --transport http gmail https://localhost:3000/mcp?allowed_labels=INBOX
Then ask Claude: "Summarize my unread emails from today" or "Find all emails about the project deadline"
Pro tip: Create a custom slash command for frequent tasks. Add to .claude/commands/email-summary.md:
Then use /email-summary anytime.
Claude CLI Integration
Certificate Configuration
For self-signed or internal CA certificates, configure Claude CLI to trust them:
Alternatively, add to ~/.claude/settings.json:
Note: The settings.json env configuration may not be applied due to a potential Claude CLI bug. If you experience certificate errors, use the shell environment variable approach instead.
Add Server via Command Line
Label filtering via URL: Configure which Gmail labels Claude can access using the allowed_labels query parameter. Use comma-separated label names (e.g., INBOX,STARRED,IMPORTANT). This parameter is required.
Manual Configuration
Claude CLI configuration is stored at ~/.claude.json:
Integration Steps
Ensure the service is running:
curl http://localhost:3001/healthExpected response:
{"status":"ok"}Add the server (see above)
Authenticate:
Start Claude Code:
claudeRun
/mcpcommandSelect the gmail server
Choose "Authenticate"
Complete Google OAuth in browser
Verify tools are available: Ask Claude: "What Gmail tools do you have?"
Claude should list three Gmail tools:
list_messagesread_messagesearch_messages
Available Tools
1. list_messages
Lists Gmail messages filtered by allowed labels.
Parameters:
maxResults(number, optional): Maximum number of messages to return (default: 10)pageToken(string, optional): Page token for pagination
Returns:
Array of message summaries containing:
id: Message IDthreadId: Thread IDsnippet: Message previewlabelIds: Array of label IDsfrom: Sender email addresssubject: Email subjectdate: Send date
2. read_message
Reads the full content of a specific message.
Parameters:
messageId(string, required): The ID of the message to readmaxSize(number, optional): Maximum body size in characters. If exceeded, body is truncated.
Returns:
Full message object containing:
id: Message IDthreadId: Thread IDlabelIds: Array of label IDsfrom: Sender email addressto: Recipient email addresssubject: Email subjectdate: Send datebody: Full email body (Markdown format)bodySize: Original body size in characterstruncated: Whether body was truncatedsnippet: Message preview
Note: This tool validates that the message has at least one allowed label before returning content. HTML-only emails are automatically converted to Markdown for better readability and token efficiency.
3. search_messages
Searches messages using Gmail query syntax.
Parameters:
query(string, required): Gmail search query (e.g., "from:example@gmail.com subject:invoice")maxResults(number, optional): Maximum number of messages to return (default: 10)pageToken(string, optional): Page token for pagination
Returns:
Array of matching message summaries (same format as
list_messages)
Note: Label filtering is automatically applied to search results.
Usage Examples
Example 1: List Recent Emails
Claude will return a list of 5 messages showing ID, subject, sender, and date.
Example 2: Read Specific Message
Claude will return the full email content including headers and body.
Example 3: Search Emails
Claude will return all matching messages from that sender (filtered by allowed labels).
Example 4: Complex Search
Claude will return matching messages using Gmail's search syntax.
Label Filtering
Label filtering allows you to control which emails Claude can access by specifying a whitelist of allowed labels.
Configuration
Label filtering is configured per-user via the MCP server URL query parameter allowed_labels:
Or in Claude CLI config:
Label ID Formats
System Labels (uppercase):
INBOX- InboxSENT- Sent mailDRAFT- DraftsTRASH- TrashSPAM- SpamIMPORTANT- ImportantSTARRED- StarredUNREAD- Unread
Category Labels:
CATEGORY_PERSONALCATEGORY_SOCIALCATEGORY_PROMOTIONSCATEGORY_UPDATESCATEGORY_FORUMS
Custom Labels:
Use your custom label names directly (e.g., Work, Personal). The server resolves names to IDs automatically.
How Filtering Works
Label filtering is applied at three levels:
list_messages: Only returns messages that have at least one allowed label
read_message: Validates the message has an allowed label before returning content
search_messages: Automatically adds label filter to the search query
The allowed_labels parameter is required on /mcp endpoint. If empty or missing, returns 400 error.
Examples
Allow only inbox and starred:
Allow inbox and a custom label:
Allow work-related categories:
Updating Labels
To change allowed_labels, update the URL in Claude CLI config:
Option 1: Edit config file
Edit ~/.claude.json and modify the URL:
Option 2: Remove and re-add server
Troubleshooting
Common Issues
"Not authenticated" error:
Solution: Re-authenticate via Claude CLI:
Run
/mcpcommand in Claude CodeSelect the gmail server
Choose "Authenticate"
Complete Google OAuth in browser
"403 Forbidden" error:
Solution: Check that you've enabled the Gmail API and configured the correct OAuth scope (gmail.readonly).
"Quota exceeded" error:
Solution: Check your Gmail API usage in Google Cloud Console:
Select your project
Navigate to "APIs & Services" > "Dashboard"
Check Gmail API quotas
Default quota is 1 billion units per day, which should be sufficient for personal use.
"Connection refused" error:
Solution: Verify the service is running:
"Timeout" error when token invalid:
Claude CLI may report a timeout instead of authentication error when the MCP server returns 401 (token decryption failed or refresh token revoked).
Solution: Re-authenticate via Claude CLI:
Run
/mcpcommand in Claude CodeSelect the gmail server
Choose "Authenticate"
Complete Google OAuth in browser
Tools not appearing in Claude CLI:
Solution:
Verify the config.json format is correct
Check that the URL is accessible:
curl http://localhost:3000/healthRestart Claude CLI
Check Claude CLI logs for errors
Server Administration
The following sections are for administrators deploying and managing the MCP server.
Features
Stateless architecture - Encrypted bearer tokens (JWE) with no server-side session storage
Multi-tenant OAuth 2.0 - Multiple clients with separate Gmail accounts
Server-side Google callback - Google redirects to server, not directly to client
Per-user label filtering - Each user configures their own allowed labels
Transparent token refresh - Automatic Google token refresh on each request
Three MCP tools: list messages, read message content, search messages
Structured logging - Pino logger with JSON output in production
Unit tests - Vitest test suite for auth modules
HTTPS transport for secure remote deployment
Docker ready with health checks
Architecture
The server uses a stateless architecture where Google OAuth tokens are encrypted into a JWE (JSON Web Encryption) bearer token returned to Claude CLI. On each request, the server decrypts the token, refreshes the Google access token if expired, and executes Gmail API calls.
Three MCP tools are available:
list_messages: List Gmail messages filtered by allowed labelsread_message: Read full content of a specific messagesearch_messages: Search messages using Gmail query syntax
All communication happens over HTTPS. Credentials and encryption keys are loaded from files specified via environment variables.
Prerequisites
Node.js >= 22.0.0
Docker (for containerized deployment)
Gmail account
Google Cloud Console account (free tier sufficient)
Claude CLI installed
Google Cloud Console Setup
Step 1: Create Google Cloud Project
Navigate to https://console.cloud.google.com
Click the project dropdown in the top navigation bar
Click "New Project"
Enter project name: "Gmail MCP Server" (or any name you prefer)
Note the Project ID (must be globally unique)
Click "Create"
Note: The free tier is sufficient for personal use.
Step 2: Enable Gmail API
In Google Cloud Console, ensure your project is selected
Navigate to "APIs & Services" > "Library" (left sidebar)
Search for "Gmail API"
Click on "Gmail API" from the results
Click the "Enable" button
Wait for the API to be enabled (~30 seconds)
Note: There's no cost for enabling the API; it uses pay-per-use pricing.
Step 3: Configure OAuth Consent Screen
Navigate to "APIs & Services" > "OAuth consent screen"
Select user type:
Choose "External" if using a personal Gmail account
Choose "Internal" if using Google Workspace
Click "Create"
Fill in the App information:
App name: "Gmail MCP Server"
User support email: Your email address
Developer contact: Your email address
Click "Save and Continue"
Add scopes:
Click "Add or Remove Scopes"
Search for "gmail.readonly"
Check the box for:
https://www.googleapis.com/auth/gmail.readonlyClick "Update"
Click "Save and Continue"
Add test users:
Click "Add Users"
Enter your Gmail address
Click "Add"
Click "Save and Continue"
Review the summary and click "Back to Dashboard"
Important: The read-only scope (gmail.readonly) is the most secure option and is all that's needed.
Step 4: Create OAuth 2.0 Credentials
Navigate to "APIs & Services" > "Credentials"
Click "Create Credentials" > "OAuth client ID"
If prompted to configure the consent screen, it should already be done
Application type: Select "Web application"
Name: "Gmail MCP Server"
Add Authorized redirect URI: The URL where your MCP server's callback endpoint is accessible
This must be the actual URL reachable from user's browser after Google login
Production:
https://mcp.example.com/callbackLocal testing:
http://localhost:3000/callback
Click "Create"
Click "Download JSON" to download credentials file
Save the file as
credentials.jsonin yourcredentials/directory
Important:
The redirect URI in credentials must exactly match what's configured in Google Cloud Console
Keep credentials secure and never commit them to version control
The downloaded file format:
For Docker deployment, mount this file as a volume or use container secrets.
Installation & Setup
Clone or Download
If you have this project locally, navigate to the project directory:
Install Dependencies
Authentication Flow (MCP OAuth 2.1)
The server implements the MCP Authorization Specification using OAuth 2.1 with PKCE. This creates a two-tier OAuth flow: Claude CLI authenticates with the Gmail MCP Server, which in turn authenticates with Google.
Step-by-Step Flow
1. Discovery & Client Registration
Claude CLI discovers the server's OAuth capabilities:
Fetches
/.well-known/oauth-authorization-serverfor OAuth metadataFetches
/.well-known/oauth-protected-resourcefor resource metadataPerforms Dynamic Client Registration at
/register(RFC 7591)
2. Authorization Request (Claude CLI → Server → Browser)
Claude CLI initiates OAuth 2.1 with PKCE:
Claude CLI opens browser to
/authorizewithcode_challengeServer stores pending request (client ID, redirect URI, code challenge)
Server responds with HTTP 302 redirect to Google OAuth (browser follows automatically)
3. Google Authentication (Browser → Google → Server → Browser)
User authenticates with Google:
User logs in and grants
gmail.readonlypermissionGoogle responds with HTTP 302 redirect to
/callback(browser follows)Server exchanges Google authorization code for Google access/refresh tokens
Server generates an MCP authorization code
Server responds with HTTP 302 redirect to Claude CLI callback (browser follows)
4. Token Exchange (Claude CLI → Server)
Claude CLI completes the OAuth flow:
Exchanges MCP authorization code for access token at
/tokenServer validates PKCE
code_verifierusing SHA-256 against storedcode_challengeServer encrypts Google tokens + user email into a JWE (JSON Web Encryption) token
Server returns the encrypted JWE as the MCP bearer token
5. Authenticated MCP Requests (Stateless)
Claude CLI uses the bearer token:
Sends requests to
/mcp?allowed_labels=...withAuthorization: Bearer <encrypted-jwe>Server decrypts the JWE to extract Google tokens
Server refreshes Google access token if expired (transparent to client)
Server executes Gmail API calls and returns results
Claude CLI Authentication
The easiest way to authenticate is using Claude CLI's built-in OAuth support:
Add the server to Claude CLI:
claude mcp add --transport http gmail https://localhost:3000/mcp?allowed_labels=INBOXIn Claude Code, run:
/mcpSelect the gmail server and choose "Authenticate"
Complete the Google OAuth flow in your browser
Claude CLI automatically handles token storage and refresh.
Quick Start (Local Development)
For local development and testing:
1. Build the Project
2. Start the Server
The server will start on port 3000 (or the port specified in the PORT environment variable).
3. Test the Server
Health check:
Expected response:
Test MCP tools list:
You should see four tools listed: list_messages, read_message, search_messages, logout.
4. Development Mode
For development with auto-reload:
Environment Variables
Variable | Required | Default | Description |
| Yes | - | Path to Google OAuth credentials JSON file |
| Yes | - | Path to file containing 32-byte encryption key (hex or base64) |
| Yes | - | Path to TLS private key file (PEM) |
| Yes | - | Path to TLS certificate file (PEM) |
| No | 3000 | HTTPS server port |
| No | localhost | Server hostname |
| No | 86400 | MCP session TTL in seconds (default: 24 hours) |
| No | info | Log level (trace, debug, info, warn, error, fatal) |
| No | - | Set to "production" for JSON log output |
Note: Label filtering is configured per-client via URL query parameter allowed_labels. This parameter is required and cannot be empty.
Security Considerations
OAuth Scope
This server uses the gmail.readonly scope, which provides:
Read-only access to Gmail messages and metadata
No ability to send, delete, or modify emails
No access to Gmail settings or account information
This is the most secure scope for accessing Gmail data.
Credential Storage
Local Development:
Credentials stored in
credentials/directoryDirectory is excluded from git via
.gitignoreNever commit
credentials/to version control
Container Deployment:
Use container secrets or mounted volumes for credentials
Ensure credentials file is read-only
Use environment variables for configuration
Token Management
MCP bearer token is an encrypted JWE containing Google tokens and user email
Stateless design: Server has no persistent storage for authenticated requests
Google access tokens expire after 1 hour (auto-refreshed transparently on each request)
Google refresh tokens are long-lived (until manually revoked by user)
Encryption key is required (
TOKEN_ENCRYPTION_PATH) - key rotation invalidates all tokensRe-authentication required when: refresh token revoked, encryption key rotated, or token corrupted
OAuth Security Measures
The server implements several OAuth 2.1 security measures:
PKCE S256 verification: Code verifier is validated using SHA-256 hash comparison
Redirect URI validation: Only registered redirect URIs are accepted during authorization
Encrypted bearer tokens: JWE tokens use AES-256-GCM encryption (dir/A256GCM)
State parameter validation: OAuth state uses UUID format with strict parsing
Authorization code single-use: Codes are deleted immediately after exchange
Best Practices
Never commit secrets: Ensure
credentials/is in.gitignoreUse Docker secrets: Always use secrets for production deployments
Rotate tokens regularly: Regenerate OAuth tokens periodically
Limit network exposure: Restrict access to localhost or use a reverse proxy with HTTPS
Monitor API quotas: Check Google Cloud Console for Gmail API usage
Use TLS: Deploy behind a reverse proxy with HTTPS for remote access
Audit access: Review OAuth consent screen and authorized applications in your Google account
Gmail API Quotas
Default quota: 1 billion units per day
Personal use should stay well within limits
Monitor usage in Google Cloud Console
The server implements no additional rate limiting
Development
Local Development Setup
Install dependencies:
npm installRun in development mode (with auto-reload):
npm run devAuthenticate via Claude CLI when first accessing the server
Running Tests
Run unit tests:
Run tests in watch mode:
Run tests with coverage:
Building
Build the project:
Test the compiled output:
Making Changes
Modify source files in
src/Run tests with
npm testTest locally with
npm run devBuild with
npm run buildRebuild Docker image and redeploy
License & Contributing
This project is licensed under the MIT License.
Contributing
Contributions are welcome! Please:
Fork the repository
Create a feature branch
Make your changes
Submit a pull request
Support
For issues or questions:
Check service logs:
docker service logs gmail-mcpVerify secrets:
docker secret lsTest health endpoint:
curl http://localhost:3000/healthCheck Gmail API quotas in Google Cloud Console
Verify token validity by regenerating locally