mcpField
J
JMAP mail

JMAP mail

本地服务
github.com通信协作14 天前更新

关于 JMAP mail

JMAP mail 是可自托管的 MCP 服务,让 AI 助手访问 JMAP 邮件服务器,读取、整理、起草和发送邮件。它根据邮箱地址发现服务器并通过 OAuth 登录,无需手动配置 URL 或令牌。

主要功能

  1. 01根据邮箱地址发现 JMAP 服务
  2. 02搜索和读取邮件及会话
  3. 03整理邮件并管理附件
  4. 04创建草稿并发送经确认的邮件
  5. 05管理休假回复和 Sieve 规则

适用场景

  1. 01按发件人、主题或日期搜索邮箱
  2. 02移动邮件并更新已读或标记状态
  3. 03起草带附件的回复
  4. 04管理自动休假回复和过滤规则

MCP 相关

它通过本地 stdio 或受保护的 HTTP 桥接服务连接 MCP 客户端与 JMAP 邮箱。服务器处理 OAuth 凭据,并向客户端提供邮件工具和状态资源。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
ocighcr.io/kolapsis/jmap-mcp:0.3.0
mcpbjmap-mcp.mcpb

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

jmap-mcp

CI Release Go Reference License

一款 MCP 服务,可让 AI 助手(Claude.ai、Claude Code、Claude Desktop 或任意 MCP 客户端)访问托管在 JMAP 服务(RFC 8620、RFC 8621)上的邮箱,首先支持 Stalwart。

用户提供电子邮件地址,并在其邮件服务自己的页面上登录。无需配置其他任何内容:没有服务 URL、令牌或 API 密钥。

为什么选择它

  • 自主掌控。 邮件留在你的服务上。此桥接服务可自托管,不存储任何邮件,只保留加密的 OAuth 令牌。
  • 零配置。 根据电子邮件地址查找 JMAP 服务(先使用 DNS SRV,再使用 /.well-known/jmap),从标准元数据查找其 OAuth 服务,并动态注册桥接服务。密钥会在首次启动时生成。
  • 纯净的 OAuth,不转发令牌。 MCP 客户端获取由桥接服务为其签发的令牌;邮件服务令牌不会离开桥接服务,符合 MCP 授权规范的要求。 将 Client ID 留空时,它可以作为 Claude.ai 自定义连接器使用。
  • 支持任意 JMAP 服务。 它并非 Stalwart 专属:任何支持 JMAP,且其 OAuth 服务支持 RFC 8414 元数据和 RFC 7591 动态注册的服务都可以使用。

现有的 JMAP MCP 服务(mikluko/jmap-mcp、wyattjoh/jmap-mcp、agent-jmap-mcp、fastmail-blade-mcp)都需要在配置中提供服务 URL 和静态令牌,而且都无法作为连接器添加到 Claude.ai 中。

工具

为 Agent 设计的精简界面:紧凑的 JSON 结果、全程支持分页、正文转换为文本,并通过明确标志指示是否已截断。

工具功能
list_accounts已连接的账户和默认账户(set_default 可更改默认账户)。
connect_account仅限本地模式:通过电子邮件地址连接账户(使用浏览器或设备代码)。
list_mailboxes邮箱及其角色(收件箱、已发送、草稿、垃圾箱、归档、垃圾邮件)、路径、邮件总数和未读数。
list_identities发件人身份。服务器公布发送功能时注册。
search_emails按文本、发件人、收件人、主题、邮箱、日期、未读状态、标记状态、附件和大小搜索;支持排序、位置和数量限制。返回摘要。
get_email标头、纯文本正文(没有文本部分时会将 HTML 转换为文本)、附件列表。支持 max_body_length。
get_thread按顺序显示对话,可返回摘要或完整邮件。
get_attachment文本和小型图片直接内嵌;其他附件返回有效期为 15 分钟的签名 URL(HTTP 模式)或私有临时文件(本地模式)。
update_emails标记为已读、未读、已加标记或已取消标记。
move_emails将邮件移至通过 ID、角色或名称指定的邮箱。
delete_emails默认移至垃圾箱;permanent 会在用户确认后永久删除。
create_draft新建邮件或回复:In-Reply-To、References、Re: 主题、引用内容、回复所有收件人,以及通过 JMAP 上传的附件。
send_email发送草稿,或撰写并发送邮件。除非启用 --enable-send,否则此功能不可用;每封邮件都需用户确认。
vacation_response读取或更改外出自动回复(更改需确认)。服务器公布此功能时注册。
sieve_scripts列出、读取、编写、启用、停用和删除筛选规则(RFC 9661);更改需确认。服务器公布此功能时注册。

资源 jmap-mcp://status 描述已连接的账户、发现的服务器及其公布的功能。

电子邮件内容被视为不可信数据:它会作为数据返回给模型,绝不会被解释执行;工具说明也会告知模型,邮件中可能包含必须忽略的指令。

对于非机密选项(选择哪个账户、使用哪个发件人身份,以及确认发送或永久删除),如果客户端支持,系统会通过 MCP elicitation 询问。否则,工具会返回列出选项的错误,模型随后使用设置好的参数(account、identity、confirm)再次调用工具。凭据不会通过 elicitation 或工具参数传递。

工作原理

                         HTTP mode                                     mail server
 ┌──────────────┐  OAuth 2.1 (bridge tokens)  ┌──────────────┐  OAuth (mail tokens)  ┌──────────────┐
 │  MCP client  │ ──────────────────────────▶ │   jmap-mcp   │ ────────────────────▶ │ OAuth server │
 │  Claude.ai…  │ ◀── MCP over HTTP ────────▶ │  (bridge)    │ ◀──── JMAP ─────────▶ │  JMAP API    │
 └──────────────┘                             └──────────────┘                       └──────────────┘

在 HTTP 模式(jmap-mcp serve)下,桥接服务同时是:

  1. 受保护的资源(RFC 9728 元数据、通过 401 和 WWW-Authenticate 响应头发起认证挑战、对每个请求检查受众);
  2. 面向 MCP 客户端的精简授权服务器(RFC 8414 元数据、PKCE S256、RFC 8707 资源指示符、 RFC 7591 动态注册、客户端 ID 元数据 文档、轮换刷新令牌);
  3. 邮件服务器的 OAuth 客户端:其登录页面会要求用户输入电子邮件地址、发现服务器、 在每台服务器上注册一次,并将用户重定向到邮件服务器的 PKCE 授权码流程。只有邮件 服务器返回后,桥接服务才会发放自己的授权码和令牌。

单个部署可为使用不同邮件服务器的用户提供服务。每位用户都会获得一个隔离的 MCP 服务 实例,且只能访问自己的账户。

在 本地模式(jmap-mcp,stdio)下没有第三方:进程本身就是邮件服务器的 OAuth 客户端,与邮件应用类似。它会注册为公共客户端,在浏览器中打开本地回环重定向地址; 如果无法打开浏览器,则会回退到设备流程(RFC 8628), 并显示需要输入的代码。

安装

1. 在 Traefik 后运行 Docker

镜像为 ghcr.io/kolapsis/jmap-mcp(linux/amd64 和 linux/arm64,distroless,以非 root 用户运行,数据存储在 /data 卷中)。如果 Traefik 已配置 websecure 入口点和 ACME 解析器,请复制 docker-compose.yml,设置主机名、解析器和网络, 然后启动:

curl -O https://raw.githubusercontent.com/kOlapsis/jmap-mcp/main/docker-compose.yml
# edit mcp.example.com, the certresolver name and the network
docker compose up -d
curl https://mcp.example.com/healthz

Traefik 会设置 X-Forwarded-* 响应头,桥接服务据此推导其公开 URL。只有在代理未发送 这些响应头时,才需要设置 JMAP_MCP_PUBLIC_URL。

镜像标签:发布版本使用 X.Y.Z、X.Y、X 和 latest;主分支的最新构建使用 main 和 sha-<commit>。两种镜像均由 GitHub Actions 构建并推送到 ghcr.io。

不使用 Traefik 时,deploy/caddy 中提供了可自行获取证书的 Caddy 配置:

cd deploy/caddy   # edit mcp.example.com in the Caddyfile
docker compose up -d

MCP 地址为 https://mcp.example.com/mcp。

2. 添加到 Claude.ai

设置 › 连接器 › 添加自定义连接器。为连接器命名,并填写 URL https://mcp.example.com/mcp。在高级设置中,将 客户端 ID 和 客户端密钥 留空: Claude.ai 会自行动态注册(其重定向 URI 为 https://claude.ai/api/mcp/auth_callback)。点击“连接”,在桥接服务页面输入电子邮件地址, 然后在邮件服务器上登录。

免费套餐仅限添加一个自定义连接器。Team 和 Enterprise 套餐的所有者可在“组织设置” › “连接器”下添加连接器。

3. 使用远程桥接服务配置 Claude Code
claude mcp add --transport http mail https://mcp.example.com/mcp

然后在 Claude Code 中运行 /mcp,并选择服务器,在浏览器中完成身份验证。

4. Claude Code 和 Claude Desktop,本地模式(stdio)

从发布页面下载二进制文件,通过 Homebrew(brew install --cask kolapsis/tap/jmap-mcp,适用于 macOS 和 Linux)或通过 Go 安装:

go install github.com/kOlapsis/jmap-mcp@latest

Claude Code:

claude mcp add mail -- jmap-mcp

或者在 .mcp.json 中:

{
  "mcpServers": {
    "mail": { "command": "jmap-mcp", "args": ["stdio"] }
  }
}

Claude Desktop:从发布页面安装 jmap-mcp.mcpb(双击该文件,或前往 Settings › Extensions),或者在 claude_desktop_config.json 中添加二进制文件的完整路径:

{
  "mcpServers": {
    "mail": { "command": "/usr/local/bin/jmap-mcp", "args": ["stdio"] }
  }
}

首次使用时,请让助手连接你的邮箱。它会询问你的电子邮件地址(通过 elicitation 或 connect_account 工具),在浏览器中打开邮件服务器的登录页面,随后即可使用该账户。没有图形会话时(SSH),它会显示一个 URL 和一段代码,你可以在任意设备上输入代码。令牌存储在数据目录中(Linux 上为 ~/.config/jmap-mcp),使用保存在操作系统密钥环中的密钥加密;如果没有可用的密钥环,则使用权限为 0600 的密钥文件加密。可以连接多个账户。

若要在本地模式下发送邮件,请在服务条目中添加 "env": {"JMAP_MCP_ENABLE_SEND": "true"}。

5. 使用 systemd 运行二进制文件
sudo install -m 755 jmap-mcp /usr/local/bin/
sudo cp deploy/systemd/jmap-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now jmap-mcp

该单元使用动态用户,在 127.0.0.1:8080 上侦听,并将状态保存在 /var/lib/jmap-mcp 中。在前面配置 TLS 反向代理(任何会发送 X-Forwarded-Proto 和 X-Forwarded-Host 的代理均可),或设置 JMAP_MCP_PUBLIC_URL。

准备邮件服务器

发现。 按照 RFC 8620 §2.2 的说明,通过电子邮件域名查找 JMAP 服务:查找指向 JMAP 主机的 SRV 记录 _jmap._tcp.example.com;若不存在,则使用 https://example.com/.well-known/jmap。如果你的网站并非由邮件服务器提供服务,请添加 SRV 记录:

_jmap._tcp.example.com. 3600 IN SRV 0 1 443 mail.example.com.

OAuth 服务通过 JMAP 主机查找:依次使用 RFC 9728 资源元数据、RFC 8414 和 OpenID Connect 发现机制。它必须与 JMAP 主机位于同一可注册域名下(例如 jmap.example.com 和 auth.example.com);否则,桥接程序会拒绝该服务。

使用 Stalwart 注册客户端。 使用默认设置时无需进行任何操作:桥接程序会通过 PKCE 将自身注册为公共客户端,Stalwart 支持匿名注册(anonymousClientRegistration,默认在 Stalwart 0.16 中启用)。Stalwart 只会向经过身份验证的调用方签发机密客户端,因此桥接程序无法通过此方式获取客户端密钥;授权码改由 PKCE 保护。

如果运营者关闭了匿名注册,请静态声明客户端:

  1. 在 Stalwart 中,前往 Management › Directory › OAuth Clients,创建一个客户端,并设置重定向 URI 为 https://mcp.example.com/callback(如果需要机密客户端,也可设置密钥)。
  2. 获取桥接程序的管理员令牌:docker compose exec jmap-mcp /jmap-mcp admin-token(或 jmap-mcp admin-token --data-dir /var/lib/jmap-mcp)。
  3. 打开 https://mcp.example.com/admin,使用任意用户名和该令牌作为密码登录,然后输入邮件服务器(电子邮件地址或其 URL)、客户端 ID、密钥和身份验证方法。它们会加密后存储在桥接程序数据库中。

本地模式需要动态注册公共客户端,这是 Stalwart 的默认设置。

配置

所有选项都是可选的,且仅与部署有关。每个标志也可以通过环境变量 JMAP_MCP_<FLAG> 设置(例如 JMAP_MCP_ENABLE_SEND=true)。

标志默认值用途
--listen:8080HTTP 监听地址(serve)。
--data-dir$XDG_CONFIG_HOME/jmap-mcp(镜像中为 /data)数据库和主密钥。
--public-url根据 X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-Prefix 确定桥接服务的公共基础 URL。
--log-levelinfodebug、info、warn 或 error。日志中绝不会包含机密、验证码或邮件正文。
--enable-sendfalse注册 send_email。
--allow-private-networksfalse允许邮件服务器使用私有或环回地址(例如位于同一 LAN 上)。这会停用部分 SSRF 防护。

命令:jmap-mcp 或 jmap-mcp stdio(本地模式)、jmap-mcp serve(HTTP 模式)、jmap-mcp admin-token、jmap-mcp healthcheck、jmap-mcp version。

暴露的端点

以下所有端点都必须通过反向代理访问,且使用相同的主机名。

路径用途
/mcpMCP Streamable HTTP 端点(需要 bearer token)。
/.well-known/oauth-protected-resource、/.well-known/oauth-protected-resource/mcp受保护资源元数据(RFC 9728)。
/.well-known/oauth-authorization-server、/.well-known/oauth-authorization-server/mcp授权服务器元数据(RFC 8414)。
/register动态客户端注册(RFC 7591)。
/authorize授权端点及用于输入电子邮件地址的页面。
/callback从邮件服务器登录流程返回。
/token令牌端点(授权码、刷新令牌)。
/revoke令牌撤销(RFC 7009)。
/attachments/{token}有签名且短时有效的附件下载。
/admin静态客户端声明(需要管理员令牌)。
/healthz健康检查。
/简短说明页面。

安全性

  • 只接受由桥接服务签发的令牌,且令牌只能用于其自身的资源 URL;邮件服务器令牌绝不会离开桥接服务。签发的令牌是不透明的随机值,以带密钥的哈希形式存储。访问令牌有效期为一小时;刷新令牌每次使用后都会轮换,且仅适用于对应客户端,重用旧令牌会撤销整个令牌链。重放授权码会撤销由该授权码签发的令牌。
  • 必须使用 PKCE S256。重定向 URI 必须为 HTTPS、环回 HTTP 或私有用途方案,并且必须与注册信息完全匹配(环回地址的端口可以不同)。state 会原样返回,并会发送和检查 iss 参数(RFC 9207)。在邮件服务器这一侧,会检查 state、iss 和 ID 令牌的 nonce,并通过 Cookie 将流程绑定到浏览器。
  • JMAP 主机只能将用户引导至其自身可注册域名下的授权服务器,因此恶意域名无法收集由其他邮件服务器签发的令牌。用户身份由签发方和 ID 令牌的 sub 确定(会检查 nonce、签发方和受众),而非由 JMAP 服务器报告的信息确定。邮件令牌只会发送到请求它们的主机,绝不会在重定向到其他主机后发送。
  • 每个出站请求(发现、OAuth、JMAP、客户端元数据文档)都会经过防护机制:仅接受 HTTPS,在连接时解析域名并拒绝私有、环回和链路本地地址,同时限制重定向次数。
  • 首次启动时会生成密钥:在数据目录中生成主密钥(或在本地模式下存入操作系统密钥环),并据此派生数据库加密密钥(AES-GCM)、令牌哈希密钥和附件 URL 密钥。邮件服务器令牌和客户端密钥会以加密形式静态存储。
  • OAuth 端点会按客户端 IP 进行速率限制;只有请求来自私有地址(即你的反向代理)时,才会信任 X-Forwarded-For。HTML 页面不使用 JavaScript,并设置严格的 Content Security Policy、X-Frame-Options: DENY 和 Referrer-Policy: no-referrer。附件始终以下载形式提供(application/octet-stream,sandbox CSP)。
  • 默认禁用发送邮件;启用后,每封邮件(完整正文和附件名称)、永久删除、Sieve 更改和外出通知更改都必须经用户确认,且批准仅适用于所显示的确切内容。在本地模式下,如果账户地址来自模型,连接该账户也必须经过确认。对于无法征求确认的客户端,模型必须先询问用户,再按规范传入 confirm=true;这类客户端应保持启用工具审批,因为被提示词注入的模型可能会设置该参数。

请按照 SECURITY.md 中的说明报告漏洞。

数据

数据目录包含 master.key(除非使用操作系统密钥环)和 jmap-mcp.db(SQLite)。请一并备份两者:没有密钥就无法解密数据库。删除它们会断开所有账户;用户只需重新登录。

开发

go test ./...                                  # unit tests, including replayed Stalwart exchanges
go test -tags integration ./...                # starts Stalwart in Docker
golangci-lint run ./...

集成测试会启动 stalwartlabs/stalwart,通过其 API 完成设置、创建账户、导入示例邮件,并运行真实的 OAuth 流程(浏览器、设备、使用 MCP SDK 客户端的 HTTP 桥接)。单元测试会重放这些运行过程中记录的 JMAP 交互;使用 JMAP_MCP_RECORD=$PWD/internal/tools/testdata/read go test -tags integration -run TestStalwartReadTools ./internal/tools 刷新记录(以及 write / TestStalwartWriteTools)。

目录结构:internal/jmapc(JMAP 客户端和发现)、internal/mailauth(邮件服务器的 OAuth 客户端)、internal/mailview(精简邮件视图)、internal/tools(MCP 工具)、internal/stdio 和 internal/httpd(两种模式)、internal/store(加密的 SQLite)、internal/netguard(SSRF 防护)。

另请参阅 CONTRIBUTING.md。

JMAP 库的选择

库评估
git.sr.ht/~rockorager/go-jmapaerc 使用的库,涵盖核心功能、邮件和推送。最近一次发布为 2025 年 2 月的 v0.5.3,不支持 Sieve。
github.com/mikluko/jmap上述库的维护分支(v0.26.0,2026 年 2 月):覆盖范围相同,包括 EmailSubmission、Identity 和 VacationResponse,并支持 Sieve 脚本(RFC 9661)。已选用。
github.com/rhyselsmore/go-jmap较新且设计良好,但声明为“尚不可用”,且不支持 EmailSubmission 或 Identity。

mikluko/jmap 提供方法和对象类型。传输层在不分叉的情况下于 internal/jmapc 中补全:其上传会发送错误的 Content-Type,下载会将名称和类型写死, 而会话解码遇到其不认识的能力时会失败。

决策

在根据 2026 年 10 月的实际软件进行核对后,发现初始规范不准确或必须作出选择的事项:

  1. Stalwart 客户端注册。 Stalwart 参考文档将 anonymousClientRegistration 的默认值设为 true(另一页面则称为 false),而 Stalwart 0.16.27 接受匿名注册,但仅限公共客户端:机密客户端始终需要具有 oauthClientRegistration 权限的已认证调用方。因此,桥接程序会请求注册机密客户端,失败时回退到使用 PKCE 的公共客户端,并提供 /admin 页面供静态声明的客户端使用。
  2. 查找 Stalwart 的 OAuth 服务端。 Stalwart 会匿名提供 JMAP 会话(HTTP 200),仅在调用 API 时要求进行身份验证;此外,根据电子邮件域名找到的会话主机可能与 OAuth 颁发者不同(example.com 与 mail.example.com)。桥接程序会先读取会话源站上的 RFC 9728 文档,再尝试在那里进行 RFC 8414 和 OpenID 发现。
  3. 使用 MCP 2026-07-28 进行征询。 Go SDK v1.8.0 实现了 2026-07-28 协议,该协议禁止在工具调用期间由服务端发起征询请求:服务端必须在结果中返回问题,由客户端重试(SEP-2322,多轮往返请求)。这些工具使用此机制,并在旧版本客户端上回退到经典的 elicitation/create。
  4. 注册表名称。 注册表会按 GitHub 用户名的确切大小写授予 io.github.<owner>/*,并区分大小写地比较名称,因此服务端发布为 io.github.kOlapsis/jmap-mcp,而不是 io.github.kolapsis/jmap-mcp。
  5. 注册表中的二进制文件。 注册表没有普通二进制包类型。二进制文件以 MCP bundle(.mcpb:macOS 通用版和 Windows x64 版,适用于 Claude Desktop)的形式发布;镜像则以 OCI 软件包的形式发布(本地模式使用持久卷,并通过设备授权流程登录)。
  6. 默认账户。 每次调用都询问要使用哪个账户,会导致多个账户无法使用。当已连接多个账户且未设置默认账户时,只询问一次账户,并将答案设为默认账户(list_accounts 会更改默认账户)。
  7. 本地令牌存储。 本地模式使用与 HTTP 模式相同的加密 SQLite 存储;操作系统密钥环保存主密钥,而不是逐个保存令牌。
  8. 签发的令牌。 不透明令牌以带密钥的哈希形式存储,而非签名 JWT:这样可以撤销令牌,并检测刷新令牌重用。
  9. Sieve 和外出自动回复。 编写或启用筛选规则可能会转发或丢弃邮件,而自动回复会向所有发件人发送文本:两者都需要与发送邮件相同的确认。
  10. 同域授权服务器。 如果允许 JMAP 主机的元数据指向任意授权服务器,恶意域名就能接收由其他服务器签发的令牌(并在 HTTP 模式下冒充其他用户)。JMAP 主机和颁发者必须共享同一个可注册域名,用户身份则取自 ID 令牌。因此,JMAP 主机与 OAuth 服务端位于互不相关域名上的提供方不受支持。

发布

每次推送到 main 都会构建镜像并推送到 ghcr.io/kolapsis/jmap-mcp:main(工作流 image.yml)。维护者通过推送 vX.Y.Z 标签来发布版本。发布工作流会运行 GoReleaser(归档文件、校验和、SBOM、带有 semver 和 latest 标签的 GHCR 多架构镜像、推送到 kOlapsis/homebrew-tap 的 Homebrew cask,部署密钥存储在 HOMEBREW_TAP_DEPLOY_KEY 密钥中),构建并上传 jmap-mcp.mcpb,然后使用 GitHub OIDC 将 server.json 发布到 MCP 注册表。

一次性设置:首次发布后,将组织的 GitHub packages 中的 jmap-mcp 软件包设为公开(注册表只验证公开镜像),然后重新运行 mcp-registry 作业。设置仓库主题,以便 Glama 等目录能够找到它:

gh repo edit kOlapsis/jmap-mcp --description "MCP server giving AI assistants OAuth access to JMAP mailboxes (Stalwart and others)" \
  --homepage https://github.com/kOlapsis/jmap-mcp --add-topic mcp,mcp-server,jmap,stalwart,email

许可证

Apache-2.0

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。