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認証もテストユーザー制限も不要です。

1つのインスタンスで複数のユーザーを利用できます。各ユーザーは自分の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

仕組み

マルチテナントでありながら、小規模です。 1つのSQLiteファイルに2つのテーブルがあります。users(idとAPIトークンのハッシュ)とmail_accounts(各ユーザーのメールボックス。アプリパスワードは暗号化されています)。別途データベースサービスを実行する必要はありません。

分離は事後チェックではなくクエリに組み込まれています。 すべてのMCPセッションは、ベアラートークンによって決定される単一のユーザーに属します。MCPサーバーはリクエストごとにそのユーザーを中心に構築され、すべてのデータベースクエリはWHERE句にuser_idを含みます。他のユーザーのエイリアスは、あなたのセッションには存在しません。

プロバイダーインターフェース。 ツール層は汎用のMailProviderと通信し、IMAPやGmailについて知りません。ImapSmtpProviderが主な実装で、任意でGmailApiProviderを併用できます。3つ目を追加してもツールの変更は不要です。プロバイダーの追加を参照してください。


クイックスタート

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.js(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/mcpで待ち受けます。GET /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

アカウントで2FAが必要

Outlook / Microsoft 365

https://account.microsoft.com/security

2FAが必要。管理者がIMAPをブロックする可能性あり

Fastmail

設定 → プライバシーとセキュリティ → アプリパスワード

「Mail (IMAP/SMTP)」を選択

iCloud

https://account.apple.com → App用パスワード

2FAが必要

独自サーバー

n/a

メールパスワード、または専用アカウント

プロバイダーがアプリパスワードを提供している場合は、通常のパスワードを使わないでください。

ホストとポート

既知のプロバイダーでは、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_secureまたはsmtp_secureを明示的に指定してください。


利用可能なツール

ツール

説明

list_accounts

エイリアスとメールアドレス付きでメールボックスを一覧表示します

add_mail_account

IMAP/SMTPメールボックスをアプリパスワードでリンクします(最初に接続をテストします)

remove_mail_account

メールボックスのリンクを解除し、保存されたアプリパスワードを消去します

search_emails

Gmailスタイルの構文で検索します。メッセージごとにidthreadIdを返します

get_message

1件のメッセージの完全な内容: ヘッダー、本文、添付ファイルのメタデータ

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:unread, is:read, is:starred, is:answered

newer_than:7d, older_than:2w (d/w/m/y)

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

larger:5M, smaller:100k

has:attachment

✅ (後でフィルタリング)

in:inbox, in:sent, in:archive, in:all, in:trash

✅ (SPECIAL-USE経由)

-from:someone (除外)

"exact phrase" と通常の単語

⚠️ 1つのテキスト語句に結合

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のすべての結果にはthreadIdが含まれ、get_threadはそれを使って会話全体を取得します。時系列順で、メッセージごとに送信者、件名、日付、本文が含まれます。

これはサーバーの機能に応じて2つの方法で行われます:

  • Gmail(X-GM-THRID)とRFC 8474サーバー(OBJECTID は安定したスレッドIDを自ら発行します。これを直接使用し、threadIdsrv:1829384756のようになります。

  • その他のIMAPサーバーにはスレッドの概念がありません。そこでは、標準のMessage-IDIn-Reply-ToReferencesヘッダーから会話を再構築します。そのチェーン内の最初のIDがスレッドのルートです。これらのthreadIdref:で始まります。

取得時には、サーバーに「all mail」フォルダーがあればそこを検索し、なければInbox、Sent、Archiveを横断して検索します。そのため、自分が送信した返信も会話に含まれます。


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"

注意すべき点:

  • .envPUBLIC_HOSTを自分のホスト名に設定します。ドメインが現れるのはそこだけなので、composeファイル自体は変更不要です。

  • proxyネットワークが存在し(docker network create proxy)、Traefikがそのネットワーク上にある必要があります。

  • コンテナは独自のポートを公開しません。Traefikだけが到達できます。

  • TRUST_PROXY=trueを設定すると、ExpressがX-Forwarded-*ヘッダーを信頼します。

  • TLSはTraefikで終端します。トークンはベアラー資格情報として送信されるため、HTTPSがないと平文でやり取りされます。

  • postbus-dataボリュームには、暗号化されたすべてのアプリパスワードを含むデータベースが保存されます。MASTER_KEYは別に保管し、データベースと一緒にバックアップしてください。


セキュリティ

MASTER_KEY。 アプリパスワードとリフレッシュトークンは、それぞれ独自のIVを持つAES-256-GCMで保存されます。サーバーはキーがないと起動を拒否します。キーを失うと全員がメールボックスを再リンクする必要があるため、データベースのバックアップとは別に保管してください。

トークン。 SHA-256ハッシュのみが保存されます。信頼できるチャネルで共有し、疑わしい場合はローテーションしてください(npm run rotate-token)。

分離。 mail_accountsに対するすべてのクエリはuser_idでフィルタリングされ、MCPサーバーはリクエストごとに単一のユーザーを中心に構築されるため、人を取り違える可能性のあるセッションストアはありません。

これが提供しないもの。 レート制限も監査ログも細かい権限もありません。これはTLSの背後で、知り合いの数人を対象に構築されています。不特定多数に公開しないでください。


プロバイダーの追加

ツール層はsrc/types.tsMailProviderとのみ通信します:

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.tsProviderIdMailAccountユニオンを拡張します。

  2. インターフェースを実装するクラスを含むsrc/providers/<name>/provider.tsを作成します。

  3. src/providers/registry.tsのマップに1行追加します。

  4. そのタイプのアカウントがデータベースに到達できるようにします。src/db/accounts.tssave<Name>Account()を追加し(シークレットはencryptSecretを経由)、さらにリンクする手段(add_mail_accountの隣に追加のツールを置くか、CLIスクリプト)を用意します。

既存のツール(search_emailsget_messageget_threadsend_email)は変更不要です。CONTRIBUTING.mdも参照してください。


オプション: IMAPの代わりにAPI経由でGmailを使用

このリポジトリには、IMAP/SMTP ではなく Gmail API 経由で Gmail にアクセスする第 2 のプロバイダが含まれています。これを使う必要はほぼありません。アプリパスワードを使った IMAP で同じことを、はるかに少ない手間で実現できるからです。このプロバイダが役立つのは、組織が IMAP をブロックしているが API は許可している場合だけです。

  1. https://console.cloud.google.com でプロジェクトを作成します。

  2. APIs & Services → Library で "Gmail API" を検索し、Enable をクリックします。

  3. APIs & Services → OAuth consent screenExternal を選択し、名前とサポートメールアドレスを入力します。

  4. 連携予定のアドレスを Test users に追加します。

  5. Credentials → Create credentials → OAuth client IDDesktop app を選択します。

  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 同意画面が Testing に設定されている間、リフレッシュトークンは 7 日 で期限切れになり、再連携する必要があります。この問題が解消されるのは、同意画面が In production に切り替わったときだけです。ただし、この切り替えには、これらのスコープでは 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/ 内のテストは 0.5 秒で実行され、プロセスの外部には一切触れません。SQLite はインメモリで動作し、マシンの外への接続は発生しません。テストがカバーするのは、静かに失敗しうるロジック、つまり検索クエリの変換、メッセージ ID とスレッド ID のエンコード、MIME の解析と構築、暗号化ストレージ、ユーザー間の分離、ベアラーミドルウェアです。

テストがカバー しない のは、実際のメールサーバーとの通信です。それを行うには、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、テスト、そしてコンテナを起動して /health が応答することと /mcp がトークンなしで 401 を返すことを検証する docker ビルドです。CI とコンテナはどちらも、現在の LTS である Node 24 で実行されます。

プロジェクト構成

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