邮件服务器服务

为Model Context Protocol提供的多账户邮件服务器,支持LLMs通过IMAP/SMTP进行读取、发送、搜索和组织邮件,具有连接池、速率限制和重试功能。

  • by boutquin
  • Go
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 boutquin/mcp-server-email

使用说明

mcp服务器电子邮件

多帐户电子邮件服务器 模型上下文协议。通过IMAP/SMTP,为LLM提供完整的电子邮件访问权限,包括读取、发送、搜索、组织,并具有连接池、速率限制和重试功能。设计为远程电子邮件的对应物 苹果桥 (本地Mail.app访问)。

快速开始

  1. 安装

    go install github.com/boutquin/mcp-server-email/cmd/mcp-server-email@latest
    
  2. 创建配置文件 (~/.config/mcp-email/accounts.json)

    对于知名提供商(Gmail、Outlook、Yahoo、iCloud、Fastmail、Zoho),主机和端口会从电子邮件域中自动检测到——只需提供凭据:

    [
      {
        "id": "hello",
        "email": "hello@gmail.com",
        "username": "hello@gmail.com",
        "password": "app-password-here"
      }
    ]
    

    对于自定义邮件服务器,请明确指定主机和端口:

    [
      {
        "id": "work",
        "email": "hello@example.com",
        "imap_host": "mail.example.com",
        "imap_port": 993,
        "smtp_host": "mail.example.com",
        "smtp_port": 465,
        "username": "hello@example.com",
        "password": "app-password-here"
      }
    ]
    
    chmod 600 ~/.config/mcp-email/accounts.json
    
  3. 添加到克劳德代码 (~/.claude.json)

    {
      "mcpServers": {
        "email": {
          "command": "mcp-server-email",
          "env": {
            "EMAIL_CONFIG_FILE": "~/.config/mcp-email/accounts.json"
          }
        }
      }
    }
    
  4. 重新启动Claude代码 --the email_* 工具现在可用。

安装

Go安装(推荐给Go开发人员)

go install github.com/boutquin/mcp-server-email/cmd/mcp-server-email@latest

自制(macOS/Linux)

brew install boutquin/tap/mcp-server-email

二进制下载

从下载适用于您平台的预构建二进制文件 GitHub 发布.

适用于:Linux(amd64、arm64)、macOS(amd64arm64)和Windows(amd64/arm64)。

码头工人

docker run --rm \
  -e EMAIL_ACCOUNTS='[{"id":"main","email":"user@example.com","imap_host":"mail.example.com","imap_port":993,"smtp_host":"mail.example.com","smtp_port":465,"username":"user@example.com","password":"app-password"}]' \
  ghcr.io/boutquin/mcp-server-email:latest

MCP捆绑包(克劳德桌面版)

下载 .mcpb 文件来自 发布 并在Claude Desktop中打开。

从源代码构建

git clone https://github.com/boutquin/mcp-server-email.git
cd mcp-server-email
go build -o mcp-server-email ./cmd/mcp-server-email

配置

帐户在启动时加载一次。更改需要重新启动服务器。

配置文件与环境变量

方法 最适合
EMAIL_CONFIG_FILE --JSON文件的路径 生产使用。文件可以被权限锁定(chmod 600)
EMAIL_ACCOUNTS --env-var中的内联JSON 测试、CI或容器化部署

如果两者都被设置, EMAIL_ACCOUNTS 优先。

帐户JSON模式

[
  {
    "id": "hello",
    "email": "hello@example.com",
    "imap_host": "mail.example.com",
    "imap_port": 993,
    "smtp_host": "mail.example.com",
    "smtp_port": 465,
    "username": "hello@example.com",
    "password": "app-password-here"
  }
]
字段 必填 描述
id 是 唯一帐户标识符
email 是 电子邮件地址
imap_host 否* IMAP服务器主机名
imap_port 无* IMAP端口(993=隐式TLS,143=STARTTLS)
smtp_host 否* SMTP服务器主机名
smtp_port 无* SMTP端口(465=隐式TLS,587=STARTTLS)
username 是 登录用户名
password 是** 应用程序密码或帐户密码
use_starttls 否 覆盖TLS自动检测(true/false)
insecure_skip_verify 否 跳过TLS证书验证(开发/测试)
auth_method 没有 "password" (默认)或 "oauth2"
oauth_client_id 否 OAuth2客户端ID(需要时 auth_method 是 "oauth2")
oauth_client_secret 否 OAuth2客户端机密
oauth_token_file 否 覆盖令牌文件路径

*对于知名提供商,会自动检测主机和端口(见下文)。自定义服务器需要。 **使用OAuth2身份验证时不需要。

提供商自动检测

当 imap_host/smtp_host 如果省略,服务器将检测电子邮件域中的设置:

提供商 域 IMAP SMTP
Gmail gmail.com, googlemail.com imap.gmail.com:993 smtp.gmail.com:587
展望 outlook.com, hotmail.com, live.com outlook.office365.com:993 smtp.office365.com:587
雅虎 yahoo.com imap.mail.yahoo.com:993 smtp.mail.yahoo.com:587
icloud icloud.com, me.com, mac.com imap.mail.me.com:993 smtp.mail.me.com:587
快速邮件 fastmail.com, fastmail.fm imap.fastmail.com:993 smtp.fastmail.com:587
佐霍 zoho.com, zohomail.com imap.zoho.com:993 smtp.zoho.com:587

配置中的显式主机/端口始终优先于自动检测。

TLS模式

从端口自动检测TLS模式:

端口 协议 模式
993 IMAP 隐式TLS
143 IMAP STARTTLS
465 SMTP 隐式TLS
587 SMTP STARTTLS

覆盖 "use_starttls": true 或 "use_starttls": false 在account对象中。省略自动检测(推荐)。

OAuth2身份验证

对于支持它的提供商(Gmail、Outlook),您可以使用OAuth2而不是应用程序密码。这使用设备代码流(RFC 8628)——不需要浏览器重定向。

  1. 创建OAuth2凭据 在提供商的开发人员控制台(谷歌云控制台或Azure AD)中

  2. 配置帐户 随着 auth_method: "oauth2":

    [
      {
        "id": "gmail",
        "email": "user@gmail.com",
        "username": "user@gmail.com",
        "auth_method": "oauth2",
        "oauth_client_id": "your-client-id.apps.googleusercontent.com",
        "oauth_client_secret": "your-client-secret"
      }
    ]
    
  3. 首次连接时,服务器启动设备代码流——将验证URL和代码打印到stderr。访问URL并输入代码进行授权。

  4. 令牌被持久化 在 ~/.config/mcp-email/tokens/ 并自动刷新。后续连接在没有重新授权的情况下重用存储的令牌。

支持的OAuth2提供程序: Gmail (gmail.com, googlemail.com)以及 展望 (outlook.com, hotmail.com, live.com).

环境变量

变量 必填 默认 描述
EMAIL_CONFIG_FILE 是* -- JSON配置文件的路径
EMAIL_ACCOUNTS 是* -- JSON帐户配置数组(内联)
EMAIL_DEFAULT_ACCOUNT 否 第一个帐户 默认帐户ID
EMAIL_IMAP_TIMEOUT_MS 没有 30000 IMAP操作超时(毫秒)
EMAIL_SMTP_TIMEOUT_MS 没有 30000 SMTP操作超时(毫秒)
EMAIL_IMAP_RATE_LIMIT 没有 60 IMAP请求/分钟/帐户
EMAIL_SMTP_RATE_LIMIT 没有 100 SMTP发送/小时/帐户
MAX_ATTACHMENT_SIZE_MB 没有 18 每个附件的最大大小(MB)
MAX_TOTAL_ATTACHMENT_SIZE_MB 没有 18 每封邮件的最大总附件大小(MB)
MAX_DOWNLOAD_SIZE_MB 没有 25 最大附件下载大小(MB)
EMAIL_POOL_CLOSE_TIMEOUT_MS 没有 5000 池关闭超时(ms)
EMAIL_DEBUG 没有 false 将日志记录调试到stderr
LOG_LEVEL 没有 info 日志级别: debug, info, warn, error
LOG_FORMAT 没有 json 日志格式: json 或 text

*其中之一 EMAIL_CONFIG_FILE 或 EMAIL_ACCOUNTS 是必需的。

配置文件权限

配置文件包含帐户密码。始终限制访问:

chmod 600 ~/.config/mcp-email/accounts.json

工具(22)

帐户和文件夹工具

工具 描述 关键参数
email_accounts 列出已配置的帐户及其连接状态 --
email_folders 列出所有未读/总计数的文件夹 account?
email_folder_create 创建新文件夹 name, account?

邮件列表

工具 描述 关键参数
email_list 列出文件夹中的邮件 folder?, limit?, offset?, includeBody?, account?
email_unread 列出未读邮件 folder?, limit?, includeBody?, account?
email_search 搜索主题和正文 query, from?, to?, since?, before?, folder?, limit?, includeBody?, account?

消息操作

工具 描述 关键参数
email_get 按ID获取完整消息 id
email_read_body 读取带有分页的电子邮件正文 id, offset?, limit?, format?
email_move 将邮件移动到文件夹 id, destination
email_copy 将邮件复制到文件夹 id, destination
email_delete 删除邮件(垃圾或永久删除) id, permanent?
email_mark_read 标记为已读/未读 id, read
email_flag 标志/非标志信息 id, flagged
email_reply 回复邮件(设置“回复对象”、“引用”、引用正文) id, body, all?, cc?, bcc?, isHtml?, account?
email_forward 转发邮件(重新附加原始附件) id, to, body?, cc?, bcc?, isHtml?, account?
email_batch 对多条消息进行批量操作 action, ids, destination?, permanent?, read?, flagged?

附件和螺纹

工具 描述 关键参数
email_attachment_list 列出邮件中的附件 id
email_attachment_get 按索引下载附件 id, index, saveTo?
email_thread 获取对话线索(在收件箱、已发送、存档和所有邮件中搜索) id

发送草稿

工具 描述 关键参数
email_send 通过SMTP发送,附带可选附件 to, subject, body, cc?, bcc?, replyTo?, isHtml?, attachments?, account?
email_draft_create 保存带有可选附件的草稿 to?, subject?, body?, cc?, bcc?, isHtml?, attachments?, account?
email_draft_send 发送现有草稿 id

全部可选 account params默认为配置的默认帐户。

搜索

email_search 搜索两者 主体与身体 使用IMAP SEARCH OR (SUBJECT "q") (BODY "q").

可选过滤器在身体扫描之前缩小服务器端的候选集:

筛选器 格式 示例
from 电子邮件地址或姓名 "alice@example.com"
to 电子邮件地址或姓名 "bob@example.com"
since YYYY-MM-DD "2026-01-01"
before YYYY-MM-DD "2026-02-01"

现有的操作超时(默认为30秒)阻止对大型邮箱进行挂起体搜索。

附件

email_send 和 email_draft_create 接受a attachments 参数——服务器主机上的文件引用数组:

{
  "attachments": [
    {"path": "/tmp/report.pdf"},
    {"path": "/tmp/data.csv", "filename": "Q1-data.csv", "content_type": "text/csv"}
  ]
}
参数 必填 说明
path 是 服务器主机上的绝对文件路径
filename 否 覆盖显示文件名(默认为basename path)
content_type 否 MIME类型(如果省略,则从文件扩展名中自动检测)

限制(默认值): 每个文件18 MB,总共18 MB(预base64编码;编码后保持在25 MB SMTP上限以下)。可通过以下方式配置 MAX_ATTACHMENT_SIZE_MB 和 MAX_TOTAL_ATTACHMENT_SIZE_MB 环境变量。

下载限制: 附件下载(email_attachment_get)默认情况下上限为25 MB,可通过以下方式配置 MAX_DOWNLOAD_SIZE_MB.

验证失败(丢失文件、非绝对路径、超出大小)返回 INVALID_ARGUMENT.

消息ID

邮件ID是编码帐户、邮箱和UID的复合字符串:

{account}:{mailbox}:{uid}

例子: hello:INBOX:12345

所有CRUD工具(email_get, email_move, email_copy, email_delete, email_mark_read, email_flag, email_draft_send)从ID中提取帐户和文件夹——不需要单独的参数。

错误代码

所有错误均作为MCP工具错误返回,并带有结构化代码前缀:

代码 含义
AUTH_FAILED IMAP/SMTP身份验证失败
CONNECTION_FAILED 无法连接到服务器
ACCOUNT_NOT_FOUND 未知帐户ID
FOLDER_NOT_FOUND 邮箱不存在
MESSAGE_NOT_FOUND 在邮箱中找不到UID
INVALID_ARGUMENT 参数缺失/无效(包括附件验证)
TIMEOUT 操作超时
INTERNAL 意外的服务器错误

资源

URI 描述
email://status 服务器版本、帐户连接状态、速率限制配置

与苹果桥的比较

此服务器和 苹果桥 分享A Email 模型和参数语义(limit, includeBody, folder, query)因此LLM可以与两者互换使用。主要区别:

方面 mcp服务器电子邮件 apple bridge
传输 IMAP/SMTP(远程) Mail.app(本地)
工具前缀 email_* mail_*
消息ID {account}:{mailbox}:{uid} RFC 5322消息ID
文件夹创建 支持 不支持(Mail.app需要用户界面)
复制邮件 支持 不支持
草稿发送 支持 不支持(Mail.app使用撰写UI)
附件(发送) 服务器主机上的文件路径 尚不支持

发展

先决条件

构建

go build ./...

单元测试

make test
# or: go test -race -count=1 ./...

单元测试使用模拟实现 imap.Operations 和 smtp.Operations 接口——不需要实时邮件服务器。

基准测试

go test -bench=. -benchmem ./...
基准 包 它衡量什么
BenchmarkPoolGetRelease imap 连接池获取/释放周期
BenchmarkExtractAttachments imap MIME附件提取
BenchmarkHtmlToText tools HTML到纯文本转换
BenchmarkLimiterAllow retry 速率限制器(顺序)
BenchmarkLimiterAllow_Parallel retry 速率限制器(并发)

模糊测试

Fuzz使用种子语料库瞄准舰船 testdata/fuzz/ 目录。运行特定目标:

go test -fuzz=FuzzParseMessageID ./internal/models/ -fuzztime=30s
目标 包 它模糊了什么
FuzzBuildSearchCriteria imap IMAP搜索查询生成器
FuzzExtractAttachmentByIndex imap 附件索引边界处理
FuzzExtractContentType imap MIME内容类型解析器
FuzzParseMessageID models 复合消息ID编解码器
FuzzHtmlToText tools HTML到文本清理程序
FuzzSplitAddresses tools 电子邮件地址列表拆分器

棉绒

make lint
# or: golangci-lint run ./...

集成测试

集成测试针对真实的邮件服务器执行完整的IMAP/SMTP堆栈。他们被隔离在后面 integration 构建标签和 永远不要跑 在...期间 go test ./....

邮件服务器:Greenmail

测试使用 绿色邮件,一个打包为Docker镜像的轻量级Java邮件服务器。影响运行方式的关键细节:

设置 价值 为什么重要
IMAPS端口 3993 Greenmail的SSL IMAP端口(不是993)。代码会自动从端口号检测TLS,因此测试会显式设置 UseStartTLS=false 在此非标准端口上强制隐式TLS
SMTPS端口 3465 Greenmail的SSL SMTP端口(不是465)。相同 UseStartTLS=false 以(权力)否决
绑定地址 0.0.0.0 Greenmail默认为 127.0.0.1 集装箱内,这使得Docker端口映射无声地失败(连接得到EOF)。你 必须 通过 -Dgreenmail.hostname=0.0.0.0.
用户名 test Greenmail使用 仅本地部分 (之前 @)作为登录用户名,而不是完整的电子邮件地址。如果用户是 test@example.com,IMAP/SMTP用户名为 test.
TLS证书 自签名 Greenmail生成自签名证书。测试集 InsecureSkipVerify: true 在帐户配置中接受它们。

快速启动(一个命令)

make test-integration

这将启动一个Greenmail容器,运行所有集成测试,然后拆除容器——无论通过/失败。

手动分步

如果你需要在不每次重新启动容器的情况下迭代测试:

  1. 启动Greenmail

    docker run -d --name greenmail \
      -p 3465:3465 -p 3993:3993 \
      -e "GREENMAIL_OPTS=-Dgreenmail.setup.test.all -Dgreenmail.users=test:password@example.com -Dgreenmail.hostname=0.0.0.0" \
      greenmail/standalone:2.1.0
    

    等待约3秒,让JVM启动。

  2. 运行集成测试

    TEST_IMAP_HOST=localhost TEST_IMAP_PORT=3993 \
    TEST_SMTP_HOST=localhost TEST_SMTP_PORT=3465 \
    TEST_EMAIL=test@example.com TEST_PASSWORD=password \
      go test -tags=integration -race -v ./...
    
  3. 拆除 完成后

    docker stop greenmail && docker rm greenmail
    

测试环境变量

变量 必填 默认 描述
TEST_IMAP_HOST 是* -- IMAP服务器主机名。如果未设置,则跳过测试。
TEST_IMAP_PORT 没有 3993 IMAPS端口
TEST_SMTP_HOST 是* -- SMTP服务器主机名。如果未设置,则跳过测试。
TEST_SMTP_PORT 没有 3465 SMTPS端口
TEST_EMAIL 没有 test@example.com 测试帐户的电子邮件地址
TEST_USERNAME 否 本地部分 TEST_EMAIL IMAP/SMTP登录用户名(Greenmail仅使用本地部分)
TEST_PASSWORD 没有 password 帐户密码

*如果对应 HOST 变量未设置,则跳过该测试文件的测试并显示消息(未失败)。

测试涵盖哪些内容

互联网消息访问协议 (internal/imap/integration_test.go --7次测试):

测试 它验证了什么
ConnectAndListFolders TLS连接、身份验证、文件夹列表、收件箱存在
SendAndListMessages SMTP发送→ IMAP接收往返,正文内容匹配
SearchBySubject 按主题字符串进行IMAP搜索
DeleteMessagePermanent 标记为已删除+删除,验证消息已消失
MoveMessage IMAP移动到另一个文件夹(如果服务器缺少MOVE扩展名,则跳过)
DraftWorkflow 保存草稿→ GetDraft→ DeleteDraft生命周期(如果没有APPENDUID,则跳过)
MarkReadAndFlag 设置读取/标记标志,通过GetMessage进行验证

SMTP (internal/smtp/integration_test.go --4次测试):

测试 它验证了什么
SendPlainText 纯文本电子邮件传递,通过IMAP验证正文内容
SendHTML HTML电子邮件传递,内容类型验证为 text/html
SendWithAttachment 带附件的多部分MIME,在元数据中验证文件名
RateLimitTokenConsumption 发送会消耗速率限制令牌

故障排除

症状 原因 修复
EOF 或 connection reset 已连接 Greenmail已绑定 127.0.0.1 容器内 添加 -Dgreenmail.hostname=0.0.0.0 到 GREENMAIL_OPTS
TLS handshake failure /证书错误 自签名证书被拒绝 测试配置已设置 InsecureSkipVerify: true --如果编写新的测试,也要这样做
Invalid login/password 使用完整电子邮件作为用户名 Greenmail只需要本地部分(test,不 test@example.com).集 TEST_USERNAME 或者让它默认。
STARTTLS 端口3993上出错 在隐式TLS端口上使用STARTTLS 测试配置集 UseStartTLS=false。不要使用端口3143/3025(纯端口,无TLS)。
测试以“未设置”跳过 TEST_IMAP_HOST / TEST_SMTP_HOST 未导出 导出环境变量或使用 make test-integration 目标
MoveMessage 测试跳过 Greenmail可能不支持MOVE 预期--测试使用 t.Skip()

持续集成

集成测试通过以下方式在GitHub Actions中自动运行 integration 工作中 .github/workflows/ci.yml。该作业使用Greenmail服务容器,无需手动设置Docker。有关确切的配置,请参阅工作流文件。

覆盖

要生成组合单元+集成覆盖率报告:

# With Greenmail running (see above):
TEST_IMAP_HOST=localhost TEST_IMAP_PORT=3993 \
TEST_SMTP_HOST=localhost TEST_SMTP_PORT=3465 \
TEST_EMAIL=test@example.com TEST_PASSWORD=password \
  go test -tags=integration -race -coverprofile=coverage.out ./...

go tool cover -func=coverage.out | tail -1   # total percentage
go tool cover -html=coverage.out             # open in browser

建筑

mcp-server-email/
├── cmd/mcp-server-email/     # Entry point
└── internal/
    ├── auth/                 # OAuth2 device code flow, XOAUTH2 SASL, token store
    ├── config/               # Multi-account configuration, provider auto-detection
    ├── imap/                 # IMAP client (split by concern), connection pool, Operations interface
    │   ├── client.go         # Client struct, lifecycle, shared helpers
    │   ├── client_messages.go # List, search, get, attachments
    │   ├── client_folders.go  # Folder ops, role cache
    │   ├── client_drafts.go   # Draft save/get/delete
    │   ├── client_flags.go    # Flags, move, copy, delete
    │   └── pool.go           # Connection pool with configurable close timeout
    ├── log/                  # Structured logging (slog) initialization
    ├── models/               # Email model, message ID codec, error types
    ├── resources/            # email://status resource
    ├── retry/                # Token-bucket rate limiter
    ├── smtp/                 # SMTP client, Operations interface
    └── tools/                # 22 MCP tool handlers + registration

工具处理程序通过以下方式与IMAP/SMTP客户端解耦 imap.Operations 和 smtp.Operations 接口,支持使用模拟进行全面的单元测试。

依赖项

此项目使用 go imap v2 (目前为v2.0.0-beta.8)。 v2 API还不稳定-在v2.0.0版本之前可能会发生突破性的变化。 我们确定了确切的版本 go.mod 并在稳定版发布后迅速升级。

许可证

麻省理工学院