邮件服务

一个用于处理SMTP/IMAP电子邮件操作的MCP服务器,支持邮件搜索、发送、草稿管理和多账户管理,适用于需要集成电子邮件功能的AI助手与自动化场景。

  • by Tillman32
  • Go
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 MorphStack/mcp-email

使用说明

MCP Email Server

A Model Context Protocol (MCP) server for handling SMTP/IMAP email operations. This server allows you to search past emails, send new emails, manage multiple email accounts, and work with drafts directly in your email client.

Features

  • 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
  • Draft Support: Create, read, send, and delete drafts that appear in your email client's Drafts folder
  • 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

Requirements

  • Go 1.23 or higher
  • Docker (for containerized deployment)
  • Email account with IMAP/SMTP access (app passwords recommended)

Configuration

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.

Single Account Configuration

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

Multiple Accounts Configuration

# 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_password

Optional Configuration

CACHE_PATH=/data/email_cache.db
SEARCH_RESULT_LIMIT=100
LOG_LEVEL=info

Common Email Provider Settings

Gmail

  • IMAP: imap.gmail.com:993
  • SMTP: smtp.gmail.com:587
  • Note: Requires App Password (not regular password)

Outlook/Office365

  • IMAP: outlook.office365.com:993
  • SMTP: smtp.office365.com:587

Yahoo

  • IMAP: imap.mail.yahoo.com:993
  • SMTP: smtp.mail.yahoo.com:587

MCP Tools

list_folders

List available mailboxes/folders for configured email accounts.

Parameters:

  • account_name (optional): Specific account name, or all accounts if omitted

search_emails

Search cached emails with flexible filters.

Parameters:

  • account_name (optional): Filter by specific account
  • folder (optional): Filter by folder/mailbox
  • sender (optional): Filter by sender email/name
  • recipient (optional): Filter by recipient email
  • subject (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)

get_email

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_email

Send a new email with support for text, HTML, attachments, CC, BCC.

Parameters:

  • account_name (required): Account to send from
  • to (required): Recipient email address(es) (comma-separated)
  • cc (optional): CC recipients (comma-separated)
  • bcc (optional): BCC recipients (comma-separated)
  • subject (required): Email subject
  • body_text (optional): Plain text body
  • body_html (optional): HTML body
  • attachments (optional): Array of attachment paths/URLs
  • reply_to (optional): Reply-To header
  • in_reply_to (optional): In-Reply-To header (for replies)

Attachments accept local file paths (read from the machine running the server) and http(s) URLs (fetched with a 15s timeout). Limits: max 10 files, 10MB per file, 25MB total. MIME types are detected from the extension/content. Previously the attachments parameter was accepted but silently ignored — files are now actually attached.

create_draft

Create a draft email and store it in the email client's Drafts folder. The draft appears in your email client (Gmail, Outlook, etc.) exactly as if you had composed it there — it is not sent.

Parameters:

  • account_name (required): Account to create the draft in
  • folder (optional): Drafts folder name (default: Drafts; Gmail uses [Gmail]/Drafts)
  • to (optional): Recipient email address(es) (comma-separated)
  • cc (optional): CC recipients (comma-separated)
  • bcc (optional): BCC recipients (comma-separated)
  • subject (optional): Email subject
  • body_text (optional): Plain text body
  • body_html (optional): HTML body
  • reply_to (optional): Reply-To header
  • in_reply_to (optional): In-Reply-To header (for replies)
  • attachments (optional): Files to attach — local paths or http(s) URLs (max 10MB each, 10 files / 25MB total)

Requires at least one of subject, body_text, body_html, or attachments.

list_drafts

List drafts stored in the email client's Drafts folder. Returns each draft's UID (used to send/delete it), subject, recipients, a body snippet, plus attachment_count and an attachments array (filename, mime_type, size).

Parameters:

  • account_name (required): Account to list drafts from
  • folder (optional): Drafts folder name (default: Drafts; Gmail uses [Gmail]/Drafts)

get_draft

Retrieve the full contents of a single draft by UID (from list_drafts), including the full plain-text and HTML body plus an attachments array (filename, mime_type, size).

Parameters:

  • account_name (required): Account the draft belongs to
  • uid (required): Draft UID (from list_drafts)
  • folder (optional): Drafts folder name (default: Drafts)

send_draft

Send an existing draft by UID and, by default, delete it from the Drafts folder afterward. This is how a user asks an agent to "send that draft I saved". The stored message bytes are sent as-is, so attachments survive the round trip.

Parameters:

  • account_name (required): Account to send the draft from
  • uid (required): Draft UID (from list_drafts)
  • folder (optional): Drafts folder name (default: Drafts)
  • delete_after_send (optional): Delete the draft from the Drafts folder after sending (default: true)

delete_draft

Permanently delete a draft by UID from the email client's Drafts folder.

Parameters:

  • account_name (required): Account the draft belongs to
  • uid (required): Draft UID (from list_drafts)
  • folder (optional): Drafts folder name (default: Drafts)

Note: The default drafts folder is Drafts. Gmail stores drafts in [Gmail]/Drafts — pass folder accordingly, or run list_folders to discover the correct folder name for your provider.

Building

Prerequisites

  • Go 1.23 or higher — required to compile the server from source. Install with your package manager (apt install golang-go, brew install go, etc.), or from https://go.dev/dl.
  • An email account with IMAP/SMTP access (app passwords recommended).

Build from Source

# Clone the repository
git clone https://github.com/Tillman32/mcp-email.git
cd mcp-email

# Download dependencies
go mod download

# Build the server binary
go build -o mcp-email-server ./cmd/server

# Verify it built
./mcp-email-server --version

The resulting mcp-email-server binary is self-contained — you can copy it to /usr/local/bin/ and reference it from your MCP config:

sudo cp mcp-email-server /usr/local/bin/

Docker Build

docker build -t mcp-email-server .

Running

Local Run

./mcp-email-server

Docker Run

docker 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-server

Alternatively, 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-server

Note: 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.

MCP Configuration

To use this server with Claude Desktop or VS Code, you need to configure it in your mcp.json file.

Claude Desktop Configuration

Location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

VS Code Configuration

Location: .vscode/mcp.json in your project directory

Configuration Examples

1. Local Execution (Single Account)

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.

2. Docker Execution (Single Account)

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 .

3. Multi-Account Configuration

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.

Example Files

  • mcp.json.example.local - Local execution with single account
  • mcp.json.example.docker - Docker execution with single account (env vars in args)
  • mcp.json.example.docker-envfile - Docker execution using an env file
  • mcp.json.example.multi-account - Local execution with multiple accounts

Using Docker with Environment File

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).

Setup Instructions

  1. Choose your configuration (local or Docker)
  2. Copy the appropriate example file to your MCP config location
  3. Update the paths and credentials with your actual values
  4. Restart Claude Desktop or VS Code to load the configuration

Security Notes

  • Never commit your actual mcp.json with real passwords to version control
  • Use app passwords instead of your regular email password
  • Consider using environment variables or secrets management for production

Using with Hermes Agent

Hermes Agent has a built-in MCP client that discovers a server's tools at startup and exposes them as first-class tools (prefixed mcp_email_*) the agent can call in any conversation.

1. Install Go and build the binary

Hermes host machines need Go 1.23+ to compile the server. Build and install the binary:

# Build (see "Building" above for details)
git clone https://github.com/Tillman32/mcp-email.git
cd mcp-email
go mod download
go build -o mcp-email-server ./cmd/server

# Install somewhere on PATH
sudo cp mcp-email-server /usr/local/bin/

2. Add the server to Hermes config

Edit ~/.hermes/config.yaml and add an entry under mcp_servers. Point command at the installed binary and provide your account credentials via env (use app passwords, not your real email password):

mcp_servers:
  email:
    command: "/usr/local/bin/mcp-email-server"
    env:
      IMAP_HOST: "imap.gmail.com"
      IMAP_PORT: "993"
      IMAP_USERNAME: "you@gmail.com"
      IMAP_PASSWORD: "your-app-password"
      SMTP_HOST: "smtp.gmail.com"
      SMTP_PORT: "587"
      SMTP_USERNAME: "you@gmail.com"
      SMTP_PASSWORD: "your-app-password"
      CACHE_PATH: "/var/lib/mcp-email/email_cache.db"
      SEARCH_RESULT_LIMIT: "100"
      LOG_LEVEL: "info"

Security: Hermes only passes environment variables you explicitly list under env to the subprocess — it does not leak your shell environment. Store secrets as normal YAML values here, or reference your secret manager. Never commit your real config.yaml.

3. Restart Hermes and verify

hermes mcp list          # should list the email server
hermes mcp test email    # test the connection

Then start a new session (/new or relaunch). On startup Hermes connects to the server and registers its tools with the mcp_email_ prefix. Verify with:

hermes tools list | grep mcp_email

You should see: mcp_email_create_draft, mcp_email_list_drafts, mcp_email_get_draft, mcp_email_send_draft, mcp_email_delete_draft, mcp_email_search_emails, mcp_email_send_email, mcp_email_list_folders, and mcp_email_get_email.

4. Use it in conversation

Once connected, you can just ask Hermes to work with your email:

  • "Create a draft to Sarah about the project update, subject 'Status update', saying the build passed."
  • "What drafts do I have saved?"
  • "Send the draft about the project update."
  • "Delete the draft titled 'meeting notes'."
  • "Search my inbox for invoices from last month."

Multi-account configuration

For multiple accounts, use the ACCOUNT_N_* environment variables in the same env block (see Multiple Accounts Configuration) and pass the relevant account_name to each tool call.

Development

Project Structure

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

Testing

go test ./...

Linting

golangci-lint run --timeout=5m

CI/CD

This project uses GitHub Actions for continuous integration and releases.

CI Workflow

  • 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

Release Workflow

  • 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

Creating a Release

  1. Create and push a version tag:

    git tag -a v1.0.0 -m "Release v1.0.0"
    git push origin v1.0.0
    
  2. 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.

License

MIT

Contributing

Contributions are welcome! Please open an issue or submit a pull request.