A Model Context Protocol (MCP) server for handling SMTP/IMAP email operations. This server allows you to search past emails, send new emails, and manage multiple email accounts.
- Search Emails: Flexible search across all email fields (sender, recipient, subject, body, date range)
- Send Emails: Send emails with support for text, HTML, attachments, CC, and BCC
- Multi-Account Support: Manage multiple email accounts simultaneously
- Local Caching: SQLite-based cache for fast email searches
- Full-Text Search: Fast full-text search using SQLite FTS5
- Generic IMAP/SMTP: Works with any email provider that supports IMAP/SMTP
- Go 1.23 or higher
- Docker (for containerized deployment)
- Email account with IMAP/SMTP access (app passwords recommended)
Configuration is done via environment variables. You can configure either a single account or multiple accounts.
See .env.example for a complete example configuration file.
IMAP_HOST=imap.example.com
IMAP_PORT=993
IMAP_USERNAME=user@example.com
IMAP_PASSWORD=your_app_password
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=user@example.com
SMTP_PASSWORD=your_app_password
ACCOUNT_NAME=default# Account 1
ACCOUNT_1_NAME=work
ACCOUNT_1_IMAP_HOST=imap.work.com
ACCOUNT_1_IMAP_PORT=993
ACCOUNT_1_IMAP_USERNAME=user@work.com
ACCOUNT_1_IMAP_PASSWORD=your_app_password
ACCOUNT_1_SMTP_HOST=smtp.work.com
ACCOUNT_1_SMTP_PORT=587
ACCOUNT_1_SMTP_USERNAME=user@work.com
ACCOUNT_1_SMTP_PASSWORD=your_app_password
# Account 2
ACCOUNT_2_NAME=personal
ACCOUNT_2_IMAP_HOST=imap.gmail.com
ACCOUNT_2_IMAP_PORT=993
ACCOUNT_2_IMAP_USERNAME=user@gmail.com
ACCOUNT_2_IMAP_PASSWORD=your_app_password
ACCOUNT_2_SMTP_HOST=smtp.gmail.com
ACCOUNT_2_SMTP_PORT=587
ACCOUNT_2_SMTP_USERNAME=user@gmail.com
ACCOUNT_2_SMTP_PASSWORD=your_app_passwordCACHE_PATH=/data/email_cache.db
SEARCH_RESULT_LIMIT=100
LOG_LEVEL=info- IMAP:
imap.gmail.com:993 - SMTP:
smtp.gmail.com:587 - Note: Requires App Password (not regular password)
- IMAP:
outlook.office365.com:993 - SMTP:
smtp.office365.com:587
- IMAP:
imap.mail.yahoo.com:993 - SMTP:
smtp.mail.yahoo.com:587
List available mailboxes/folders for configured email accounts.
Parameters:
account_name(optional): Specific account name, or all accounts if omitted
Search cached emails with flexible filters.
Parameters:
account_name(optional): Filter by specific accountfolder(optional): Filter by folder/mailboxsender(optional): Filter by sender email/namerecipient(optional): Filter by recipient emailsubject(optional): Filter by subject (substring match)body(optional): Filter by body content (full-text search)date_from(optional): Start date (ISO 8601 format)date_to(optional): End date (ISO 8601 format)limit(optional): Result limit (default: 100, max: 1000)
Retrieve full email by ID from cache or IMAP.
Parameters:
email_id(required): Email ID (from search results)account_name(optional): Account name if needed
Send a new email with support for text, HTML, attachments, CC, BCC.
Parameters:
account_name(required): Account to send fromto(required): Recipient email address(es) (comma-separated)cc(optional): CC recipients (comma-separated)bcc(optional): BCC recipients (comma-separated)subject(required): Email subjectbody_text(optional): Plain text bodybody_html(optional): HTML bodyattachments(optional): Array of attachment paths/URLsreply_to(optional): Reply-To headerin_reply_to(optional): In-Reply-To header (for replies)
go mod download
go build -o mcp-email-server ./cmd/serverdocker build -t mcp-email-server ../mcp-email-serverdocker run -it --name mcp-email-container \
-e IMAP_HOST=imap.example.com \
-e IMAP_PORT=993 \
-e IMAP_USERNAME=user@example.com \
-e IMAP_PASSWORD=your_app_password \
-e SMTP_HOST=smtp.example.com \
-e SMTP_PORT=587 \
-e SMTP_USERNAME=user@example.com \
-e SMTP_PASSWORD=your_app_password \
-v $(pwd)/data:/data \
mcp-email-serverAlternatively, you can use an environment file:
# Copy the example file
cp .env.example .env
# Edit .env with your credentials
# Then run:
docker run -it --name mcp-email-container --env-file .env -v $(pwd)/data:/data mcp-email-serverNote: The --name flag creates a persistent container that maintains your email cache between VS Code sessions. If you need to restart the container, use docker restart mcp-email-container. To completely reset the cache, stop and remove the container with docker rm -f mcp-email-container.
To use this server with Claude Desktop or VS Code, you need to configure it in your mcp.json file.
Location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Location: .vscode/mcp.json in your project directory
Use this if you've built the server locally:
{
"mcpServers": {
"mcp-email": {
"command": "/absolute/path/to/mcp-email-server",
"env": {
"IMAP_HOST": "imap.gmail.com",
"IMAP_PORT": "993",
"IMAP_USERNAME": "your-email@gmail.com",
"IMAP_PASSWORD": "your-app-password",
"SMTP_HOST": "smtp.gmail.com",
"SMTP_PORT": "587",
"SMTP_USERNAME": "your-email@gmail.com",
"SMTP_PASSWORD": "your-app-password",
"CACHE_PATH": "/tmp/email_cache.db",
"SEARCH_RESULT_LIMIT": "100",
"LOG_LEVEL": "info"
}
}
}
}See mcp.json.example.local for a complete example.
Use this to run the server in a Docker container:
{
"mcpServers": {
"mcp-email": {
"command": "docker",
"args": [
"run",
"-i",
"--name", "mcp-email-container",
"-v", "/tmp:/data",
"-e", "IMAP_HOST=imap.gmail.com",
"-e", "IMAP_PORT=993",
"-e", "IMAP_USERNAME=your-email@gmail.com",
"-e", "IMAP_PASSWORD=your-app-password",
"-e", "SMTP_HOST=smtp.gmail.com",
"-e", "SMTP_PORT=587",
"-e", "SMTP_USERNAME=your-email@gmail.com",
"-e", "SMTP_PASSWORD=your-app-password",
"-e", "CACHE_PATH=/data/email_cache.db",
"-e", "SEARCH_RESULT_LIMIT=100",
"-e", "LOG_LEVEL=info",
"mcp-email-server:latest"
]
}
}
}See mcp.json.example.docker for a complete example.
Note: Make sure you've built the Docker image first:
docker build -t mcp-email-server:latest .For multiple email accounts, use the ACCOUNT_N_* environment variables:
{
"mcpServers": {
"mcp-email": {
"command": "/absolute/path/to/mcp-email-server",
"env": {
"ACCOUNT_1_NAME": "work",
"ACCOUNT_1_IMAP_HOST": "imap.work.com",
"ACCOUNT_1_IMAP_PORT": "993",
"ACCOUNT_1_IMAP_USERNAME": "user@work.com",
"ACCOUNT_1_IMAP_PASSWORD": "your-app-password",
"ACCOUNT_1_SMTP_HOST": "smtp.work.com",
"ACCOUNT_1_SMTP_PORT": "587",
"ACCOUNT_1_SMTP_USERNAME": "user@work.com",
"ACCOUNT_1_SMTP_PASSWORD": "your-app-password",
"ACCOUNT_2_NAME": "personal",
"ACCOUNT_2_IMAP_HOST": "imap.gmail.com",
"ACCOUNT_2_IMAP_PORT": "993",
"ACCOUNT_2_IMAP_USERNAME": "user@gmail.com",
"ACCOUNT_2_IMAP_PASSWORD": "your-app-password",
"ACCOUNT_2_SMTP_HOST": "smtp.gmail.com",
"ACCOUNT_2_SMTP_PORT": "587",
"ACCOUNT_2_SMTP_USERNAME": "user@gmail.com",
"ACCOUNT_2_SMTP_PASSWORD": "your-app-password",
"CACHE_PATH": "/tmp/email_cache.db",
"SEARCH_RESULT_LIMIT": "100",
"LOG_LEVEL": "info"
}
}
}
}See mcp.json.example.multi-account for a complete example.
mcp.json.example.local- Local execution with single accountmcp.json.example.docker- Docker execution with single account (env vars in args)mcp.json.example.docker-envfile- Docker execution using an env filemcp.json.example.multi-account- Local execution with multiple accounts
For a cleaner Docker configuration, you can use an environment file:
{
"mcpServers": {
"mcp-email": {
"command": "docker",
"args": [
"run",
"-i",
"--name", "mcp-email-container",
"--env-file", "/absolute/path/to/.env",
"-v", "/tmp:/data",
"mcp-email-server:latest"
]
}
}
}See mcp.json.example.docker-envfile for a complete example.
This approach keeps your credentials in a separate .env file (which should not be committed to version control).
- Choose your configuration (local or Docker)
- Copy the appropriate example file to your MCP config location
- Update the paths and credentials with your actual values
- Restart Claude Desktop or VS Code to load the configuration
- Never commit your actual
mcp.jsonwith real passwords to version control - Use app passwords instead of your regular email password
- Consider using environment variables or secrets management for production
mcp-email/
├── cmd/server/ # Main application entry point
├── internal/
│ ├── config/ # Configuration management
│ ├── email/ # IMAP/SMTP client implementations
│ ├── cache/ # SQLite cache layer
│ ├── mcp/ # MCP server implementation
│ └── tools/ # MCP tool implementations
├── pkg/types/ # Shared data types
└── Dockerfile # Docker container definition
go test ./...golangci-lint run --timeout=5mThis project uses GitHub Actions for continuous integration and releases.
- Runs on every push and pull request
- Tests on multiple Go versions (1.21, 1.22, 1.23)
- Runs linters and code quality checks
- Builds and validates on multiple platforms
- Builds and tests Docker image
- Automatically triggered on version tags (e.g.,
v1.0.0) - Validates semantic versioning (must be greater than previous tag)
- Builds binaries for all platforms (Linux, macOS, Windows - amd64, arm64)
- Publishes Docker images to GitHub Container Registry (and optionally Docker Hub)
- Creates GitHub releases with all artifacts
-
Create and push a version tag:
git tag -a v1.0.0 -m "Release v1.0.0" git push origin v1.0.0 -
The release workflow will automatically:
- Validate the version
- Build all binaries
- Create Docker images
- Publish to registries
- Create GitHub release
See RELEASE.md and .github/SETUP.md for detailed information.
MIT
Contributions are welcome! Please open an issue or submit a pull request.