Gmail Multi-Inbox MCP Server
Enables AI assistants to manage multiple Gmail accounts simultaneously with built-in OAuth authentication, supporting email reading, sending, drafts, labels, and account management.
README
Gmail Multi-Inbox MCP Server
A Model Context Protocol (MCP) server that enables AI assistants to manage multiple Gmail accounts simultaneously with built-in OAuth authentication.
Why This MCP Server?
Unlike existing Gmail MCP servers, this implementation offers:
- Multi-Account Support: Manage multiple Gmail accounts from a single MCP server instance
- Intelligent Aggregation: Read and search across all accounts simultaneously
- Built-in OAuth Flow: Complete authentication setup through MCP tools - no manual token generation
- Type-Safe: Built with TypeScript for reliability and better IDE support
- Auto Token Refresh: Handles token expiration automatically and saves refreshed tokens
- Comprehensive API: Full Gmail API coverage including labels, threads, drafts, and more
Table of Contents
- Features
- Prerequisites
- Installation
- Google Cloud Setup
- Configuration
- Railway / SSE Deployment
- OAuth Onboarding
- Usage Examples
- API Reference
- Troubleshooting
- Contributing
- License
Features
Read Operations
list_accounts- View all configured accounts and their statusread_emails- Fetch recent emails (aggregates across all accounts by default)search_emails- Search using Gmail query syntax across multiple accountsget_email_thread- Retrieve complete conversation threadsget_labels- List all labels for an account
Write Operations
send_email- Send emails from any configured account, with optional local file attachmentscreate_draft- Create draft messages, with optional local file attachmentsdelete_drafts- Permanently delete one or more drafts by draft IDmark_as_read- Mark messages as readarchive_emails- Archive messages (remove from inbox)trash_emails- Move messages to trash
Label Management
add_labels- Apply labels to messagesremove_labels- Remove labels from messagescreate_label- Create new custom labelsdelete_label- Delete existing labels
Account Management
begin_account_auth- Start OAuth flow for new accountfinish_account_auth- Complete OAuth and save credentials
Prerequisites
- Node.js 20+ (Download)
- A Google Cloud Project with Gmail API enabled
- OAuth 2.0 Credentials (Desktop application type)
Installation
# Clone the repository
git clone https://github.com/tszaks/gmail-multi-inbox-mcp.git
cd gmail-multi-inbox-mcp
# Install dependencies
npm install
# Build the TypeScript code
npm run build
Google Cloud Setup
Before using this MCP server, you need to set up a Google Cloud project:
1. Create a Google Cloud Project
- Go to Google Cloud Console
- Create a new project or select an existing one
- Note your project ID
2. Enable Gmail API
- In your project, go to APIs & Services > Library
- Search for "Gmail API"
- Click Enable
3. Create OAuth 2.0 Credentials
- Go to APIs & Services > Credentials
- Click + CREATE CREDENTIALS > OAuth client ID
- If prompted, configure the OAuth consent screen:
- Choose "External" user type
- Fill in required fields (app name, support email)
- Add your email to test users
- For application type, select Desktop app
- Give it a name (e.g., "Gmail MCP Client")
- Click Create
- Download the JSON file - you'll need this for authentication
4. OAuth Consent Screen Setup
- Go to APIs & Services > OAuth consent screen
- Add the following scopes:
https://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/userinfo.email
- Add your Gmail address(es) as test users
Configuration
Add to Your MCP Settings
Add this server to your .mcp.json configuration file (adjust path to match your installation):
{
"mcpServers": {
"gmail-multi": {
"command": "node",
"args": [
"/path/to/gmail-multi-inbox-mcp/dist/index.js"
]
}
}
}
Custom Config Directory (Optional)
To use a custom directory for storing account data:
{
"mcpServers": {
"gmail-multi": {
"command": "node",
"args": [
"/path/to/gmail-multi-inbox-mcp/dist/index.js"
],
"env": {
"GMAILMCPCONFIG_DIR": "/custom/path/.gmail-multi-mcp"
}
}
}
}
The server also accepts the legacy GMAIL_MCP_CONFIG_DIR env var.
Directory Structure
Default configuration location: ~/.gmail-multi-mcp/
~/.gmail-multi-mcp/
├── accounts.json # Master account list
└── accounts/
├── personal/
│ ├── credentials.json # OAuth client credentials
│ ├── token.json # Access/refresh tokens
│ └── meta.json # Account metadata
└── work/
├── credentials.json
├── token.json
└── meta.json
accounts.json Format
{
"defaultAccount": "personal",
"accounts": [
{
"id": "personal",
"email": "user@gmail.com",
"displayName": "Personal Gmail",
"enabled": true,
"credentialPath": "~/.gmail-multi-mcp/accounts/personal/credentials.json",
"tokenPath": "~/.gmail-multi-mcp/accounts/personal/token.json"
},
{
"id": "work",
"email": "user@company.com",
"displayName": "Work Email",
"enabled": true,
"credentialPath": "~/.gmail-multi-mcp/accounts/work/credentials.json",
"tokenPath": "~/.gmail-multi-mcp/accounts/work/token.json"
}
]
}
Railway / SSE Deployment
This server can run as either stdio MCP or an SSE-backed HTTP server.
- Set
MCP_TRANSPORT=sseto force HTTP/SSE mode. - If
PORTis present, the server automatically switches to SSE mode. - The SSE endpoint is served at
/sseand message posts are accepted at/messages. - Configuration still respects
GMAILMCPCONFIG_DIRandGMAIL_MCP_CONFIG_DIR.
For Railway, point the start command at npm start or node dist/index.js and let Railway provide PORT.
OAuth Onboarding
Authenticate accounts directly through MCP tools:
Step 1: Start Authentication
Call the begin_account_auth tool with your OAuth credentials:
{
"account_id": "personal",
"email": "user@gmail.com",
"credentials_json": {
"installed": {
"client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uris": ["http://localhost"]
}
}
}
Or use a file path:
{
"account_id": "personal",
"email": "user@gmail.com",
"credentials_path": "/path/to/credentials.json"
}
The tool returns a Google OAuth URL. Open this URL in your browser.
Step 2: Complete Authentication
- In your browser, sign in with the Gmail account
- Grant the requested permissions
- Google redirects you to a localhost URL with a
codeparameter - Copy the authorization code from the URL
Call finish_account_auth:
{
"account_id": "personal",
"authorization_code": "4/0AfJoh..."
}
Your account is now authenticated and ready to use.
Usage Examples
Example 1: Read Recent Emails from All Accounts
// Aggregates across all enabled accounts
{
"max_results": 20,
"include_body": true
}
// Returns emails with source account indicated
Example 2: Search Across Multiple Accounts
{
"query": "from:boss@company.com is:unread",
"max_results": 10
}
// Searches all enabled accounts, merges and sorts results
Example 3: Send Email from Specific Account
{
"account": "work",
"to": "colleague@company.com",
"subject": "Project Update",
"body": "Here's the latest on the project...",
"html": false
}
Example 4: Read Only from One Account
{
"account": "personal",
"max_results": 10,
"query": "label:important"
}
Example 5: Manage Labels
// Create a new label
{
"account": "personal",
"name": "Urgent-2026"
}
// Add label to messages
{
"account": "personal",
"message_ids": ["msg123", "msg456"],
"label_ids": ["Label_789"]
}
Example 6: Delete Drafts
// Delete one or more drafts by their draft IDs (returned by create_draft)
{
"account": "personal",
"draft_ids": ["r5457071851533655344", "r774137312565667821"]
}
API Reference
Read Operations
list_accounts
Returns all configured accounts with health status.
Parameters: None
Returns:
{
accounts: Array<{
id: string
email: string
displayName: string
enabled: boolean
hasValidToken: boolean
}>
}
read_emails
Fetch recent emails with optional filtering.
Parameters:
account(optional): Account ID to read from. Omit to aggregate all accounts.max_results(optional, default: 20): Number of emails to return (1-100)query(optional): Gmail search queryinclude_body(optional, default: false): Include plaintext body extraction
Returns: Array of email objects with metadata, headers, and optional body
search_emails
Search emails using Gmail query syntax.
Parameters:
query(required): Gmail search queryaccount(optional): Account ID to search. Omit to search all accounts.max_results(optional, default: 25): Maximum results (1-100)
Returns: Array of matching emails
get_email_thread
Retrieve a complete email thread.
Parameters:
account(required): Account IDthread_id(required): Gmail thread ID
Returns: Thread object with all messages
get_labels
List all labels for an account.
Parameters:
account(required): Account ID
Returns: Array of label objects with IDs and names
Write Operations
send_email
Send an email from a specific account.
Parameters:
account(required): Account IDto(required): Recipient email address(es)subject(required): Email subjectbody(required): Email bodycc(optional): CC recipientsbcc(optional): BCC recipientshtml(optional, default: false): Send as HTMLattachments(optional): Array of local file attachments. Each item supports:path(required): Absolute or local filesystem pathfilename(optional): Override the filename shown in Gmailcontent_type(optional): Override the MIME type, for exampleapplication/pdf
Returns: Sent message details
create_draft
Create a draft email.
Parameters: Same as send_email
Returns: Draft details including draft_id and thread_id
delete_drafts
Permanently delete one or more drafts. Uses draft IDs as returned by create_draft. Note: draft IDs differ from message IDs and cannot be used with trash_emails.
Parameters:
account(required): Account IDdraft_ids(required): Array of draft IDs to delete
Returns: Count of deleted drafts
mark_as_read
Mark messages as read.
Parameters:
account(required): Account IDmessage_ids(required): Array of message IDs
archive_emails
Archive messages (remove INBOX label).
Parameters:
account(required): Account IDmessage_ids(required): Array of message IDs
trash_emails
Move messages to trash.
Parameters:
account(required): Account IDmessage_ids(required): Array of message IDs
Label Operations
add_labels
Add labels to messages.
Parameters:
account(required): Account IDmessage_ids(required): Array of message IDslabel_ids(required): Array of label IDs
remove_labels
Remove labels from messages.
Parameters:
account(required): Account IDmessage_ids(required): Array of message IDslabel_ids(required): Array of label IDs
create_label
Create a new Gmail label.
Parameters:
account(required): Account IDname(required): Label namelabel_list_visibility(optional, default: "labelShow")message_list_visibility(optional, default: "show")
delete_label
Delete a Gmail label.
Parameters:
account(required): Account IDlabel_id(required): Label ID to delete
Troubleshooting
"Invalid grant" Error
This usually means your authorization code has expired. Authorization codes are single-use and expire after a few minutes.
Solution: Run begin_account_auth again to get a fresh OAuth URL and authorization code.
"Token has been expired or revoked"
Your refresh token is no longer valid.
Solution:
- Delete the
token.jsonfile for the affected account - Run the OAuth flow again (
begin_account_auththenfinish_account_auth)
"Insufficient permissions"
The OAuth token doesn't have the required scopes.
Solution:
- Check your Google Cloud OAuth consent screen has all required scopes
- Re-run the OAuth flow to grant new permissions
- Required scopes:
https://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/userinfo.email
Account Not Found
The specified account ID doesn't exist in accounts.json.
Solution:
- Run
list_accountsto see available accounts - Ensure you completed OAuth onboarding for the account
- Check that the account is
enabled: trueinaccounts.json
Rate Limiting
Gmail API has rate limits (daily quota and per-user quotas).
Solution:
- Check your quota at Google Cloud Console
- Implement exponential backoff in your application
- Consider applying for increased quota if needed
Contributing
Contributions are welcome. Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit your changes (
git commit -m 'Add your feature') - Push to the branch (
git push origin feature/your-feature) - Open a Pull Request
Development Scripts
# Watch mode for development
npm run dev
# Type checking
npm run typecheck
# Build for production
npm run build
# Run the server
npm run start
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built with the Model Context Protocol SDK
- Uses Google APIs Node.js Client
Links
Built by Tyler Szakacs
Quickstart TL;DR
npm install
npm run build
node dist/index.js
Then add the server to MCP config and onboard each account with begin_account_auth + finish_account_auth.
How It Works (TL;DR)
- Server stores account-level credentials/tokens in local config directory
- OAuth flow is handled via MCP tools
- Read/search can aggregate across all enabled accounts
- Gmail API calls execute per selected account
LLM Quick Copy
Use the copy button on this code block in GitHub.
Repo: gmail-multi-inbox-mcp
Goal: Multi-account Gmail MCP with built-in OAuth onboarding.
Setup:
1) npm install && npm run build
2) Add to MCP config
3) Run begin_account_auth + finish_account_auth for each inbox
Use:
- list_accounts to verify health
- read_emails/search_emails aggregated or per account
- send_email/create_draft/delete_drafts/label tools for write actions
How it works:
- Node MCP server maintains per-account token files and calls Gmail API
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.