Skip to main content
Glama
HalloSouf

postbus-mcp

by HalloSouf

postbus-mcp

Code quality Docker License: MIT

一个自托管的 MCP 服务器,让你和你身边的几个人可以通过 Claude 或其他任何 MCP 客户端处理你的邮箱:搜索、阅读完整会话,以及发送邮件。

适用于任何 IMAP/SMTP 提供商——Gmail、Outlook、Fastmail,甚至你自己的邮件服务器——只需一个普通的应用密码。无需 Google Cloud 项目,无需 OAuth 验证,也没有测试用户限制。

一个实例可服务多个用户。每个人都有自己的 API 令牌,并且只能看到自己的邮箱。由你托管,由你分发令版;没有开放注册。

Claude / MCP client
        │  Authorization: Bearer <token>
        ▼
   POST /mcp  ──►  postbus-mcp  ──►  SQLite (users + encrypted app passwords)
                        │
                        ├──►  IMAP  (imapflow)      search, read, threads
                        └──►  SMTP  (nodemailer)    sending

目录


Related MCP server: simple-email-mcp

工作原理

多租户,但体积小。 一个 SQLite 文件包含两张表:users(id 以及 API 令牌的哈希)和 mail_accounts(每个用户的邮箱,应用密码已加密)。无需单独运行数据库服务。

隔离体现在查询中,而不是事后的检查中。 每个 MCP 会话恰好属于一个用户,由 Bearer 令牌决定。MCP 服务器针对每个请求围绕该用户构建,并且每个数据库查询都在其 WHERE 中携带 user_id。别人的别名在你的会话中根本不存在。

提供商接口。 工具层与通用的 MailProvider 交互,不关心 IMAP 或 Gmail。ImapSmtpProvider 是主要实现,可选配 GmailApiProvider。添加第三个提供商无需改动工具层——参见 添加提供商


快速开始

使用 Docker(推荐)

git clone https://github.com/HalloSouf/postbus-mcp.git
cd postbus-mcp

cp .env.example .env
openssl rand -hex 32          # put the result in .env as MASTER_KEY

docker compose up -d --build
docker compose exec postbus node dist/cli/add-user.js "Soufiane"

最后一条命令会恰好打印一次 API 令牌。请立即保存。

在本地使用 Node(22 或更高版本)

npm install
cp .env.example .env
openssl rand -hex 32          # put the result in .env as MASTER_KEY

npm run build
npm run add-user -- "Soufiane"
npm start

服务器监听 http://localhost:3000/mcpGET /health 返回 {"status":"ok"},方便做存活检查。


用户和令牌

令牌由你自己分发;没有自助注册。

命令

作用

npm run add-user -- "Name"

创建用户并打印令版(仅一次)

npm run list-users

显示用户、邮箱数量和状态

npm run rotate-token -- <id>

生成新令版;旧令版立即失效

npm run remove-user -- <id>

删除该用户及其所有邮箱

在 Docker 中,以 node dist/cli/<script>.js 方式运行相同的脚本:

docker compose exec postbus node dist/cli/list-users.js
docker compose exec postbus node dist/cli/rotate-token.js WvDnhafdM5yQ

每个令版仅存储 SHA-256 哈希,因此丢失的令版无法找回——请改为轮换令版。


连接你的客户端

Claude Desktop

Claude Desktop 使用 stdio,因此需要在中间加上 mcp-remote。在 claude_desktop_config.json 中:

{
  "mcpServers": {
    "postbus": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.example.com/mcp",
        "--header",
        "Authorization: Bearer pb_YOUR_TOKEN_HERE"
      ]
    }
  }
}

该文件在 macOS 上位于 ~/Library/Application Support/Claude/claude_desktop_config.json,在 Windows 上位于 %APPDATA%\Claude\claude_desktop_config.json。编辑后请重启 Claude Desktop。

Claude Code

claude mcp add --transport http postbus https://mcp.example.com/mcp \
  --header "Authorization: Bearer pb_YOUR_TOKEN_HERE"

其他客户端

任何支持 Streamable HTTP 的客户端都可以工作:端点 POST /mcp,令版作为 Authorization: Bearer <token>。服务器是无状态的——没有会话 ID,也没有服务器端流——因此 GET /mcp 会刻意返回 405


关联邮箱

你在对话中用自己的令版完成此操作,无需终端:

把我的 Gmail 关联为“个人”,地址 souf@gmail.com,应用密码 abcd efgh ijkl mnop

Claude 随后会调用 add_mail_account。首先会测试连接(IMAP 和 SMTP 都测试);只有两者都成功才会存储任何信息。

创建应用密码

提供商

位置

说明

Gmail / Workspace

https://myaccount.google.com/apppasswords

需要账号开启两步验证

Outook / Microsoft 365

https://account.microsoft.com/security

需要两步验证;管理员可能阻止 IMAP

Fastmail

设置 → 隐私与安全 → 应用密码

选择“邮件(IMAP/SMTP)”

iCloud

https://account.apple.com → 应用专用密码

需要两步验证

自有服务器

不适用

你的邮件密码,或一个专用账号

当提供商提供应用密码时,切勿使用你的常规密码。

主机和端口

对于已知提供商,postbus-mcp 会自动填写这些信息——你只需提供别名、邮箱和应用密码:

Gmail、Google Workspace、Outlook、Hotmail、Microsoft 365、Fastmail、iCloud、Yahoo、Zoho、Proton(通过 Bridge)。

对于其他提供商,请自己传入这些信息:

imap_host: imap.yourdomain.com    imap_port: 993   (TLS)
smtp_host: smtp.yourdomain.com    smtp_port: 465   (TLS) or 587 (STARTTLS)

端口 993 和 465 从一开始就使用 TLS;在其他端口上,如果服务器支持,则使用 STARTTLS。如果该假设不适用于你的服务器,请显式传入 imap_securesmtp_secure


可用工具

工具

作用

list_accounts

列出你的邮箱,包含别名和邮件地址

add_mail_account

关联一个 IMAP/SMTP 邮箱和应用密码(先测试连接)

remove_mail_account

解除邮箱关联并清除已存储的应用密码

search_emails

使用 Gmail 风格语法搜索;每条消息返回一个 idthreadId

get_message

获取单条消息的完整内容:头部、正文、附件元数据

get_thread

获取会话中的所有消息,按时间从旧到新

send_email

立即发送新消息(支持 cc、bcc、reply-to、html)

每个工具都只会访问令牌所属用户的邮箱。


搜索语法

search_emails 使用 Gmail 风格的语法。对于 Gmail 邮箱,你的查询会原样发送给 Gmail(通过 X-GM-RAW),因此 Gmail 搜索栏中可用的任何语法在这里都可用。对于其他 IMAP 服务器,查询会被转换:

术语

Gmail

其他 IMAP

from:to:cc:bcc:subject:

is:unreadis:readis:starredis:answered

newer_than:7dolder_than:2wd/w/m/y

after:2026-01-01before:2026/03/01

larger:5Msmaller:100k

has:attachment

✅(事后过滤)

in:inboxin:sentin:archivein:allin:trash

✅(通过 SPECIAL-USE)

-from:someone(排除)

"exact phrase" 和松散词语

⚠️ 合并为一个文本条件

label:filename:category:

❌ 忽略

示例:

from:boss@company.com is:unread newer_than:7d
subject:"march invoice" has:attachment
in:sent to:client@example.com older_than:1m

空查询会返回收件箱中最新的消息。


会话线程

每个 search_emails 结果都带有 threadIdget_thread 使用它来拉取整个会话——按时间顺序排列,包含每条消息的发件人、主题、日期和正文。

根据服务器可用的能力,有两种方式:

  • Gmail(X-GM-THRID)和 RFC 8474 服务器(OBJECTID 会自行提供稳定的线程 ID。我们直接使用它,threadId 看起来像 srv:1829384756

  • 其他所有 IMAP 服务器 没有线程概念。在这种情况下,我们根据标准的 Message-IDIn-Reply-ToReferences 头重建会话:该链中的第一个 id 是线程的根。这些 threadId 值以 ref: 开头。

获取时,如果服务器有“所有邮件”文件夹,我们会从那里查找;否则会在收件箱、已发送和归档中查找——这样你自己的回复也会出现在会话中。


在 Traefik 后面部署

此仓库中的 docker-compose.yml 是一个可运行的示例。其核心内容:

services:
  postbus:
    build: .
    restart: unless-stopped
    environment:
      MASTER_KEY: ${MASTER_KEY:?set MASTER_KEY in .env}
      DATABASE_PATH: /data/postbus.db
      TRUST_PROXY: "true"
    volumes:
      - postbus-data:/data
    networks: [proxy]
    labels:
      traefik.enable: "true"
      traefik.docker.network: proxy
      traefik.http.routers.postbus.rule: Host(`${PUBLIC_HOST:-mcp.example.com}`)
      traefik.http.routers.postbus.entrypoints: websecure
      traefik.http.routers.postbus.tls.certresolver: letsencrypt
      traefik.http.services.postbus.loadbalancer.server.port: "3000"

需要注意的事项:

  • .env 中将 PUBLIC_HOST 设置为你自己的主机名;这是域名唯一出现的位置,因此 compose 文件本身无需改动。

  • proxy 网络必须存在(docker network create proxy),并且 Traefik 必须连接到此网络。

  • 容器本身不发布任何端口:只有 Traefik 可以访问它。

  • TRUST_PROXY=true 让 Express 信任 X-Forwarded-* 请求头。

  • 在 Traefik 处终止 TLS。令牌以 Bearer 凭证形式传输;没有 HTTPS 就会明文传输。

  • postbus-data 卷保存着包含所有加密应用密码的数据库。请将其与 MASTER_KEY 一同备份——但分开存放。


安全性

MASTER_KEY。 应用密码和刷新令牌使用 AES-256-GCM 存储,每条都有独立的 IV。没有该密钥,服务器拒绝启动。如果丢失,所有人都需要重新关联邮箱,因此请将其与数据库备份分开保存。

令牌。 仅存储 SHA-256 哈希。通过你信任的渠道分享它们,有疑虑时进行轮换(npm run rotate-token)。

隔离。mail_accounts 的每个查询都按 user_id 过滤,并且 MCP 服务器为每个请求围绕单个用户构建,因此不存在可能混淆用户的会话存储。

这不包括什么。 没有速率限制、没有审计日志、没有细粒度权限。这是为你认识的几个人在 TLS 后面使用的。不要将其开放给未知受众。


添加提供商

工具层只与 src/types.ts 中的 MailProvider 交互:

interface MailProvider<A extends MailAccount = MailAccount> {
  readonly id: ProviderId;
  verify(account: A): Promise<void>;
  search(account: A, query: string, maxResults: number): Promise<MessageSummary[]>;
  getMessage(account: A, messageId: string): Promise<MessageDetail>;
  getThread(account: A, threadId: string): Promise<MessageDetail[]>;
  send(
    account: A,
    to: string,
    subject: string,
    body: string,
    options?: SendOptions,
  ): Promise<string>;
}

提供商收到的是完全解析后的账户,凭据已解密。别名查找发生在工具层,因此提供商无法访问会话用户以外的数据。

要添加一个提供商:

  1. 扩展 src/types.ts 中的 ProviderIdMailAccount 联合类型。

  2. 编写 src/providers/<name>/provider.ts,其中包含一个实现该接口的类。

  3. src/providers/registry.ts 的映射表中添加一行。

  4. 确保该类型的账户可以访问数据库:在 src/db/accounts.ts 中添加 save<Name>Account()(机密通过 encryptSecret 处理),并提供关联方式——在 add_mail_account 旁边添加一个额外工具,或提供一个 CLI 脚本。

现有工具(search_emailsget_messageget_threadsend_email)无需改动。另请参阅 CONTRIBUTING.md


可选:通过 API 而非 IMAP 使用 Gmail

  1. https://console.cloud.google.com 创建项目。

  2. API 和服务 → 库 → 搜索 "Gmail API" → 启用

  3. API 和服务 → OAuth 同意屏幕 → 类型选为 外部 → 填写名称和支持邮箱。

  4. 测试用户 下添加要关联的地址。

  5. 凭据 → 创建凭据 → OAuth 客户端 ID → 类型选为 桌面应用

  6. 将客户端 ID 和客户端密钥放入 .env

    GOOGLE_CLIENT_ID=xxxxxxxxxxxx.apps.googleusercontent.com
    GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxx
    OAUTH_CALLBACK_PORT=53682
  7. 关联一个邮箱。此操作在管理员的机器上运行,因为 Google 会将回调发送到 localhost

    npm run list-users                       # look up the user id
    npm run link-gmail -- <user-id> work

使用的范围:gmail.readonlygmail.sendgmail.composegmail.labels

注意: 当 OAuth 同意屏幕设置为 测试 时,刷新令牌会在 7 天后过期,你必须重新关联。这种情况只有在同意屏幕变为 已发布 后才会停止,而对这些范围而言,发布需要 Google 验证。这正是 IMAP 搭配应用专用密码成为主要路径的原因。


开发

npm install
npm run dev          # server with hot reload (tsx watch)
npm test             # unit tests (vitest)
npm run typecheck    # src + tests
npm run format       # prettier across the repo
npm run build        # into dist/

tests/ 中的测试在半秒内运行完毕,并且不会触及进程之外的任何内容:SQLite 在内存中运行,没有任何连接离开机器。它们覆盖了那些可能悄然出错的逻辑——搜索查询转换、消息和线程 ID 的编码、MIME 的解析与组装、加密存储、用户之间的隔离,以及 bearer 中间件。

它们覆盖的是与真实邮件服务器的通信。为此,请在本地运行 GreenMail

docker run -d --rm --name greenmail -p 3143:3143 -p 3025:3025 \
  -e GREENMAIL_OPTS='-Dgreenmail.setup.test.imap -Dgreenmail.setup.test.smtp -Dgreenmail.users=souf:secret@postbus.test -Dgreenmail.hostname=0.0.0.0' \
  greenmail/standalone:2.1.0

然后用 imap_host: 127.0.0.1imap_port: 3143smtp_host: 127.0.0.1smtp_port: 3025username: soufapp_password: secret 关联一个邮箱。

GreenMail 不支持 Gmail 扩展。使用 X-GM-RAWX-GM-THRID 的代码分支只能针对真实的 Gmail 邮箱进行测试。

GitHub Actions 会在每次 push 和 pull request 上运行同样的检查:格式化、类型、对生产依赖执行 npm audit、测试,以及一个 docker 构建——它会启动容器,并验证 /health 有响应,且在没有令牌的情况下 /mcp 返回 401。CI 和容器都运行 Node 24,即当前的 LTS。

项目结构

src/
├── index.ts              startup: check MASTER_KEY, open the db, listen
├── config.ts             environment configuration
├── crypto.ts             AES-256-GCM for secrets, hashing for tokens
├── types.ts              MailProvider plus every shared type
├── db/                   SQLite: migrations, users, mail_accounts
├── http/                 Express app, bearer auth, MCP transport per request
├── providers/
│   ├── registry.ts       account -> provider
│   ├── imap/             IMAP/SMTP: connections, search, threading, sending
│   └── gmail/            optional Gmail API provider (OAuth)
├── tools/                the MCP tools (they know no provider)
└── cli/                  admin scripts: users and tokens

tests/                    unit tests (vitest), mirroring the layout of src/

许可证

MIT — 参见 LICENSE

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables reading and sending emails via IMAP and SMTP through the MCP protocol. Supports multiple email accounts and configuration via UI or environment variables.
    BSD 3-Clause
  • A
    license
    B
    quality
    B
    maintenance
    Enables users to manage email accounts via IMAP/SMTP, including reading, searching, sending emails with attachments and calendar invites, all through natural language interactions with MCP-compatible clients.
    1
    4
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    MCP server that enables email management (send, read, search, delete, etc.) via IMAP/SMTP, compatible with Gmail, Outlook, Yahoo, iCloud, and other standard mail servers.
    11
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes any IMAP mailbox and SMTP relay as MCP tools, enabling email management (read, search, send, delete) through MCP-compatible agents.
    MIT

View all related MCP servers

Related MCP Connectors

  • Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.

  • Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.

  • Fully-managed email as MCP tools - register domains, real mailboxes, send and receive mail.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HalloSouf/postbus-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server