# π§ Gmail MCP Server
[](https://www.typescriptlang.org/)
[](https://modelcontextprotocol.org/)
[](https://developers.google.com/gmail/api)
[](LICENSE)
A powerful MCP (Model Context Protocol) server that enables AI assistants to
interact with Gmail through OAuth2 authentication **with safety-first design**.
Built with TypeScript and designed for seamless integration with Claude Desktop
and other MCP-compatible clients.
## π Table of Contents
- [Features](#-features)
- [Prerequisites](#-prerequisites)
- [Installation](#-installation)
- [Configuration](#-configuration)
- [Google Cloud Setup](#1-google-cloud-console-setup)
- [OAuth2 Credentials](#2-create-oauth2-credentials)
- [Generate Refresh Token](#3-generate-refresh-token)
- [Usage](#-usage)
- [Standalone Server](#standalone-server)
- [Claude Desktop Integration](#claude-desktop-integration)
- [Available Tools](#-available-tools)
- [Examples](#-examples)
- [Troubleshooting](#-troubleshooting)
- [Development](#-development)
## β¨ Features
- π‘οΈ **Safety First** - Draft-only mode by default prevents accidental email sends
- π **Smart Drafts** - Create drafts for new emails and replies with custom content
- π¬ **List Emails** - Retrieve recent emails with advanced filtering options
- π **Get Email Details** - Fetch complete email content including attachments info
- π **Search Emails** - Use Gmail's powerful search syntax to find specific emails
- βοΈ **Send Emails** - Direct sending (disabled by default, enable with caution)
- π **Secure OAuth2** - Industry-standard authentication with refresh token support
- π― **Type-Safe** - Full TypeScript implementation with strict typing
- π **High Performance** - Optimized with parallel processing and smart caching
## π Prerequisites
Before you begin, ensure you have:
- **Node.js** 18.0 or higher
- **npm** or **yarn** package manager
- **Google Account** with Gmail enabled
- **Google Cloud Console** access
- **Claude Desktop** (optional, for integration)
## π¦ Installation
1. **Clone the repository:**
```bash
git clone https://github.com/JaviEzpeleta/gmail-mcp-server.git
cd gmail-mcp-server
```
2. **Install dependencies:**
```bash
npm install
```
3. **Create environment file:**
```bash
cp .env.example .env
```
> **π‘οΈ Security Note**: By default, direct email sending is disabled for safety. The server will create drafts instead, which you can review and send manually from Gmail.
## βοΈ Configuration
### 1. Google Cloud Console Setup
1. **Create or select a project:**
- Go to [Google Cloud Console](https://console.cloud.google.com/)
- Click on the project dropdown and select "New Project"
- Give your project a name (e.g., "Gmail MCP Server")
- Click "Create"
2. **Enable Gmail API:**
- In the sidebar, navigate to **APIs & Services** β **Library**
- Search for "Gmail API"
- Click on **Gmail API** from the results
- Click **Enable**
- Wait for the API to be enabled (usually takes a few seconds)
### 2. Create OAuth2 Credentials
1. **Configure OAuth consent screen:**
- Go to **APIs & Services** β **OAuth consent screen**
- Select "External" user type (unless you have a Google Workspace account)
- Fill in the required fields:
- App name: "Gmail MCP Server"
- User support email: Your email
- Developer contact: Your email
- Add scopes:
- `https://www.googleapis.com/auth/gmail.readonly`
- `https://www.googleapis.com/auth/gmail.send`
- `https://www.googleapis.com/auth/gmail.modify`
- Add test users (important!):
- Add your Gmail address and any other accounts you want to use
- Save and continue through all steps
2. **Create OAuth client:**
- Go to **APIs & Services** β **Credentials**
- Click **+ CREATE CREDENTIALS** β **OAuth client ID**
- Application type: **Web application** β οΈ (NOT Desktop app)
- Name: "Gmail MCP Web Client"
- **Configure Authorized redirect URIs:**
- Click **+ ADD URI**
- Add: `http://localhost:8765/oauth2callback` (default port)
- If you plan to use a custom port, add: `http://localhost:YOUR_PORT/oauth2callback`
- Click **Create**
- **Download the credentials** (you'll see a download button or JSON option)
- Save the `client_id` and `client_secret` from the downloaded file
> **β οΈ Important**: Desktop app type doesn't allow custom redirect URIs, but we need `localhost:PORT/oauth2callback` for the OAuth flow to work. That's why we use **Web application** instead.
### 3. Generate Refresh Token
1. **Add credentials to .env:**
```bash
GMAIL_CLIENT_ID=your_client_id_here
GMAIL_CLIENT_SECRET=your_client_secret_here
GMAIL_REFRESH_TOKEN=
# Security: Keep this false unless you need direct sending
GMAIL_ALLOW_DIRECT_SEND=false
# OAuth setup port (must match the redirect URI you configured above)
OAUTH_REDIRECT_PORT=8765
```
> **π‘ Port Configuration**: The `OAUTH_REDIRECT_PORT` must match the port you configured in the Google Cloud Console redirect URI. If you used `http://localhost:8765/oauth2callback`, keep it as 8765. If you used a different port, update this value accordingly.
2. **Run the setup script:**
```bash
npm run setup
# or
npm run dev src/get-refresh-token-desktop.ts
```
3. **Authorize the application:**
- A browser window will open automatically
- Sign in with your Google account
- Grant all requested permissions
- You'll be redirected to a success page
4. **Save the refresh token:**
- The terminal will display your refresh token
- Copy the complete `GMAIL_REFRESH_TOKEN` value
- Add it to your `.env` file
## π Usage
### Standalone Server
1. **Build the project:**
```bash
npm run build
```
2. **Start the server:**
```bash
npm start
```
The server will start and listen for MCP commands via stdio.
### Claude Desktop Integration
1. **Build the project first:**
```bash
npm run build
```
2. **Locate Claude Desktop config:**
- **macOS**:
`~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
3. **Edit the configuration file:**
```json
{
"mcpServers": {
"gmail": {
"command": "node",
"args": ["/absolute/path/to/gmail-mcp-server/dist/index.js"],
"env": {
"GMAIL_CLIENT_ID": "your_client_id",
"GMAIL_CLIENT_SECRET": "your_client_secret",
"GMAIL_REFRESH_TOKEN": "your_refresh_token",
"GMAIL_ALLOW_DIRECT_SEND": "false"
}
}
}
}
```
4. **Restart Claude Desktop**
5. **Verify the connection:**
- Open Claude Desktop
- Look for the π icon indicating MCP connection
- Try: "List my recent emails"
## π οΈ Available Tools
> **π‘οΈ Safety Notice**: Tools marked with π‘οΈ create drafts by default for your safety. Direct sending tools marked with π¨ are disabled by default.
### π¬ list_emails
List recent emails with optional filtering.
**Parameters:**
- `maxResults` (number, 1-100): Maximum emails to return (default: 10)
- `query` (string): Gmail search query (e.g., "is:unread")
- `includeSpamTrash` (boolean): Include SPAM/TRASH folders (default: false)
**Example:**
```
List my 5 most recent unread emails
```
### π get_email_details
Get complete details and content of a specific email.
**Parameters:**
- `emailId` (string, required): The email ID to retrieve
- `format` (string): Level of detail - "full", "minimal", or "metadata"
(default: "full")
**Example:**
```
Get the full content of email ID 18abc123def
```
### π‘οΈ create_draft
Create an email draft with optional CC/BCC recipients (recommended for AI assistants).
**Parameters:**
- `to` (string, required): Recipient email address
- `subject` (string, required): Email subject
- `body` (string, required): Email body (plain text or HTML)
- `cc` (string): CC recipients (comma-separated)
- `bcc` (string): BCC recipients (comma-separated)
**Example:**
```
Create a draft email to john@example.com with subject "Meeting Tomorrow" and body "Let's meet at 10 AM"
```
### π¨ send_email (Disabled by Default)
Send an email directly with optional CC/BCC recipients.
**β οΈ Security Warning**: This tool is disabled by default. Set `GMAIL_ALLOW_DIRECT_SEND=true` to enable.
**Parameters:**
- `to` (string, required): Recipient email address
- `subject` (string, required): Email subject
- `body` (string, required): Email body (plain text or HTML)
- `cc` (string): CC recipients (comma-separated)
- `bcc` (string): BCC recipients (comma-separated)
**Example:**
```
Send an email to john@example.com with subject "Meeting Tomorrow" and body "Let's meet at 10 AM"
```
### π search_emails
Search emails using Gmail's advanced search syntax.
**Parameters:**
- `query` (string, required): Gmail search query
- `maxResults` (number, 1-100): Maximum results (default: 10)
- `includeSpamTrash` (boolean): Include SPAM/TRASH (default: false)
**Example Gmail search queries:**
- `from:user@example.com` - Emails from a specific sender
- `subject:"important meeting"` - Emails with exact phrase in subject
- `has:attachment` - Emails with attachments
- `is:unread` - Unread emails
- `newer_than:2d` - Emails from last 2 days
- `label:work` - Emails with specific label
### π‘οΈ find_and_draft_reply
Find the latest email from a sender and create a draft reply with optional custom content.
**Parameters:**
- `senderName` (string, required): Sender name or email address
- `replyBody` (string, optional): Custom reply content (template used if not provided)
**Example:**
```
Create a draft reply to the latest email from John Smith saying "Thanks for your message. I'll get back to you soon."
```
## π Examples
### Basic Usage Examples
**List recent emails:**
```
Show me my 10 most recent emails
```
**Search for specific emails:**
```
Search for emails from alice@example.com with attachments
```
**Create a draft email:**
```
Create a draft email to bob@example.com saying "Thanks for your help!"
```
**Create a draft reply:**
```
Draft a reply to the latest email from support@company.com
```
### Advanced Usage Examples
**Complex search:**
```
Find all unread emails from the last week with "invoice" in the subject
```
**Draft with CC:**
```
Create a draft email to team@company.com with CC to manager@company.com about the project update
```
**Get email details:**
```
Show me the full content of the most recent email from my boss
```
## π§ Troubleshooting
### Common Issues and Solutions
#### β Error: Missing required environment variables
**Solution:** Ensure all required environment variables are set in your `.env` file:
- `GMAIL_CLIENT_ID`
- `GMAIL_CLIENT_SECRET`
- `GMAIL_REFRESH_TOKEN`
- `GMAIL_ALLOW_DIRECT_SEND` (optional, defaults to `false`)
- `OAUTH_REDIRECT_PORT` (optional, defaults to `8765`)
#### β Error: redirect_uri_mismatch
**Problem:** OAuth setup fails with "The redirect URI in the request does not match the ones authorized for the OAuth client."
**Solution:**
1. Go to Google Cloud Console β APIs & Services β Credentials
2. Click on your OAuth client
3. In "Authorized redirect URIs", ensure you have: `http://localhost:8765/oauth2callback`
4. If using a custom port, add: `http://localhost:YOUR_PORT/oauth2callback`
5. Make sure your `.env` file has the matching `OAUTH_REDIRECT_PORT=8765`
6. **Important**: OAuth client must be **Web application** type, not Desktop app
> This error commonly occurs when following old documentation that suggests using "Desktop app" type, which doesn't support custom redirect URIs.
#### π‘οΈ Security: Direct email sending is disabled
**This is normal and safe behavior.** By default, the server creates drafts instead of sending emails directly.
**Solutions:**
- **Recommended**: Use `create_draft` tool instead of `send_email`
- **Alternative**: Set `GMAIL_ALLOW_DIRECT_SEND=true` in your `.env` file (not recommended for AI assistants)
#### β Error 403: access_denied
**Solution:**
1. Go to Google Cloud Console β OAuth consent screen
2. Add your email as a test user
3. Re-run the token generation process
#### β Error: invalid_grant
**Solution:** Your refresh token has expired or is invalid
1. Delete the old refresh token from `.env`
2. Run `npm run setup` again
3. Complete the authorization flow
4. Update `.env` with the new token
#### β Gmail API not enabled
**Solution:**
1. Go to Google Cloud Console
2. Navigate to APIs & Services β Library
3. Search for "Gmail API"
4. Click Enable
#### β Claude Desktop doesn't show the MCP server
**Solution:**
1. Verify the config file path is correct
2. Ensure all paths in the config are absolute paths
3. Check that the built files exist in `dist/`
4. Restart Claude Desktop completely
5. Check Claude Desktop logs for errors
#### β Rate limit exceeded
**Solution:**
- Gmail API has quotas (250 quota units per user per second)
- Implement exponential backoff for retries
- Reduce the number of parallel requests
## π Security Guidelines
### Draft-First Approach
This server implements a **safety-first design** to prevent accidental email sends:
- **Default behavior**: Creates drafts that require manual review
- **Protection**: `send_email` tool is disabled by default
- **User control**: Explicit environment variable required for direct sending
### Recommended Usage
β
**Safe for AI assistants:**
- `create_draft` - Creates email drafts
- `find_and_draft_reply` - Creates reply drafts
- `list_emails`, `search_emails`, `get_email_details` - Read-only operations
β οΈ **Use with caution:**
- `send_email` - Only enable if you fully trust the AI assistant and understand the risks
### Best Practices
1. **Keep `GMAIL_ALLOW_DIRECT_SEND=false`** unless absolutely necessary
2. **Review all drafts** before sending manually from Gmail
3. **Test thoroughly** in a safe environment before production use
4. **Monitor usage** and check for unexpected behavior
## π¨ Development
### Available Scripts
```bash
# Development with hot reload
npm run dev
# Build TypeScript to JavaScript
npm run build
# Start production server
npm start
# Generate OAuth refresh token
npm run setup
# Run tests
npm test
# Lint code
npm run lint
```
### Project Structure
```
gmail-mcp-server/
βββ src/
β βββ index.ts # Main server implementation
β βββ get-refresh-token-desktop.ts # OAuth setup utility
βββ dist/ # Compiled JavaScript (generated)
βββ examples/ # Usage examples
βββ docs/ # Additional documentation
βββ .env.example # Environment variables template
βββ tsconfig.json # TypeScript configuration
βββ package.json # Project dependencies
βββ README.md # This file
```
### Testing
Test the connection and basic functionality:
```bash
# Test Gmail connection
npm run dev test-gmail-connection.ts
# Test with MCP client
npm run dev test-list-emails.js
```
## π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## π License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
for details.
## π Acknowledgments
- [Google Gmail API](https://developers.google.com/gmail/api) for email
functionality
- [Model Context Protocol](https://modelcontextprotocol.org/) for the MCP
specification
- [Anthropic](https://anthropic.com/) for Claude and MCP development
## π Support
For issues, questions, or suggestions:
- Open an issue on
[GitHub](https://github.com/JaviEzpeleta/gmail-mcp-server/issues)
- Check existing issues for solutions
- Read the
[Gmail API documentation](https://developers.google.com/gmail/api/guides)
---
Made with β€οΈ by [Javi Ezpeleta](https://github.com/JaviEzpeleta)