Agentic Inbox(cloudflare/agentic-inbox)は、Cloudflare が公開した「AIエージェント付きのセルフホスト型メールクライアント」だ。Email Routing で受け取ったメールをメールボックスごとの Durable Object に保存し、添付を R2 に置き、Workers AI で動くエージェントが受信メールを読んで返信の下書きを自動で作る。全部が Cloudflare の部品で組まれ、他社のメールサーバーもデータベースも要らない。本記事は 2026-09-16 時点のリポジトリ(★7.6k・Apache-2.0)をクローンしてビルドし、README とソースを突き合わせて「何ができて、どこに権限の落とし穴があるか」を整理する。
demo_app.png)。右のエージェントパネルに、受信をトリガーに下書きが自動生成された履歴が並ぶ。中央の下書きは人が Send を押すまで送られない- ・正体:Cloudflare 製の参照実装。React 19+Hono+Durable Objects(SQLite)+R2+Workers AI+Agents SDK。★7.6k・fork 976・コミット11件・最終コミット 2026-04-17
- ・何ができる:自ドメイン宛メールの受信・閲覧・検索・返信・転送・フォルダ整理・添付。受信のたびにエージェントが返信の下書きを生成し、送信は人の確認が必須
- ・2つの入口:サイドパネルの Email Agent は9ツール(送信なし)。
/mcpの MCP サーバーは13ツールでsend_email・delete_emailを含む - ・認証:本番では Cloudflare Access が必須(未設定だと起動時にエラー)。ただし Access を通れば全メールボックスを操作でき、メールボックス単位の認可は無い(README 明記)
- ・実測:Linux で
npm install(525パッケージ・19秒)とnpm run build(12.4秒)が成功。npm run devとデプロイは未検証
Agentic Inbox は Agents SDK の AIChatAgent をそのまま使った「エージェントに通信手段を持たせる」型の実装で、他の Cloudflare 製エージェント基盤と同じ設計思想の上にある。フレームワーク選定の全体像はAIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証にまとめている。
Agentic Inboxとは——Workers だけで完結するメールクライアント
README の一行目は「A self-hosted email client with an AI agent, running entirely on Cloudflare Workers」。要点は「entirely(すべて)」で、メールの受信から保存・AI処理・送信・認証まで、外部サービスを一つも挟まない。
・何ができるか:自分のドメイン宛メールを Email Routing で Worker に流し込み、リッチテキストの作成画面・返信/転送のスレッド化・フォルダ・検索(from:name・is:unread・has:attachment の演算子)・添付をブラウザから扱う。受信のたびにエージェントが下書き返信を作る
・何を解決するか:「エージェントにメールアドレスを持たせたい」ときに必要な受信・パース・保存・スレッド管理・送信・認証を、一つのリポジトリで揃えている。README が参照する Cloudflare ブログ「Email for Agents」は、このアプリを Email Service と Agents SDK の使い方を示す参照実装として紹介している(ブログ本文は当環境から取得できず、README とドキュメントの記述に基づく)
・何を代替するか:SaaS のメール API を叩く自作エージェントや、IMAP をポーリングするスクリプト。ただし Gmail 等の既存アカウントを読むものではなく、自分のドメイン宛の新しいメールボックスを作る道具だ
wrangler.jsonc から起こした構成。Durable Object は3クラスで、いずれも SQLite バックエンド(編集部作図)wrangler.jsonc を読むと構成が具体的に分かる。
| バインディング | 種別 | 役割 |
|---|---|---|
MAILBOX → MailboxDO |
Durable Object(SQLite) | メールボックス1つにつき1インスタンス。メール本文・スレッド・フォルダを SQLite に保持 |
EMAIL_AGENT → EmailAgent |
Durable Object(SQLite) | Agents SDK の AIChatAgent。チャット履歴・カスタムシステムプロンプトを永続化 |
EMAIL_MCP → EmailMCP |
Durable Object | McpAgent ベースの MCP サーバー。/mcp で公開 |
BUCKET |
R2(バケット名 agentic-inbox) |
添付ファイル |
AI |
Workers AI | エージェントの対話・注入判定・下書き検査 |
EMAIL |
send_email(remote: true) |
Email Service による送信 |
DOMAINS・EMAIL_ADDRESSES |
vars | 受信を受け付けるドメインとアドレス |
compatibility_date は 2025-11-28、nodejs_compat フラグ付き。フロントエンドは React 19+React Router v7+Tailwind+Zustand+TipTap(エディタ)+@cloudflare/kumo(Cloudflare の UI コンポーネント)、API は Hono、ORM は drizzle-orm、メール解析は postal-mime、Access の JWT 検証は jose と、依存も一通り読める。
受信から下書きまでの流れ——「送信は人が押す」設計
workers/index.ts)の実装順。下書き生成は ctx.waitUntil で非同期に走り、送信はUIの Send ボタンだけが行う(編集部作図)workers/index.ts の受信ハンドラを読むと、README の「Auto-draft on new email」がどう実装されているかが分かる。
・Email Routing から渡された生メールを postal-mime で解析し、In-Reply-To/References ヘッダからスレッド ID を決める。ヘッダが無ければ件名と差出人で既存スレッドを探す
・MailboxDO の createEmail で INBOX に保存する。保存される日時はメールの Date ヘッダでなく受信時刻(コード中のコメントに明記)
・保存後、ctx.waitUntil で EmailAgent の /onNewEmail を叩く。エージェントは受信メールを読んで返信の下書きを DRAFT フォルダに作る。失敗しても Auto-draft trigger failed をログに残すだけで受信自体は成功する
・UI に「Draft」バッジ付きで表示され、人が Send/Edit/Discard を選ぶ
workers/lib/ai.ts には、対話用とは別に2つの補助モデルが使われている。受信本文がプロンプトインジェクションかどうかを YES/NO で判定する分類器(@cf/meta/llama-3.1-8b-instruct-fast)と、生成した下書きからエージェントの内部的な文言が漏れていないかを検査して除去する verifier(@cf/meta/llama-4-scout-17b-16e-instruct)だ。対話と下書き生成本体は workers/agent/index.ts の2箇所で @cf/moonshotai/kimi-k2.5 を使っており、README の「Workers AI(@cf/moonshotai/kimi-k2.5)」は対話モデルの話で、実際には3種のモデルを役割分担させている。
(catch-all → Worker)"] B --> C["Hono Worker
postal-mime 解析"] C --> D{"注入判定
llama-3.1-8b"} D --> E["MailboxDO(SQLite)
添付は R2"] E --> F["EmailAgent DO
kimi-k2.5 で下書き"] F --> G{"下書き検査
llama-4-scout"} G --> H["DRAFT フォルダ"] H --> I["人が Send を押す"] I --> J["Email Service
send_email"]
9ツールのエージェントと13ツールの MCP——権限の非対称
このアプリには AI からメールを操作する入口が2つあり、持っているツールが違う。ここが採用判断で一番重要な点だ。
workers/agent/index.ts の createEmailTools と workers/mcp/index.ts の server.tool() 呼び出しを数えたもの(2026-09-16 時点)| 入口 | 実装 | ツール | 送信 | 対象メールボックス |
|---|---|---|---|---|
| サイドパネルの Email Agent | EmailAgent(AIChatAgent)・WebSocket |
list_emails get_email get_thread search_emails draft_email draft_reply mark_email_read move_email discard_draft の9 |
無し(下書きまで。送信はUIの Send) | 開いているメールボックス |
/mcp の EmailMCP |
McpAgent+@modelcontextprotocol/sdk |
上記に加え list_mailboxes create_draft update_draft delete_email send_reply send_email の13 |
あり | mailboxId 引数で任意 |
README の「Prerequisites」末尾はこの非対称を隠していない。「共有の Cloudflare Access ポリシーを通過したユーザーは、設計上このアプリの全メールボックスにアクセスできる。これは /mcp の MCP サーバーも含み、MCP 経由で接続した外部 AI ツール(Claude Code・Cursor 等)は mailboxId パラメータを渡すことでどのメールボックスでも操作できる。メールボックス単位の認可は無い」という趣旨の注記がある。
つまり「エージェントは送信しない」という安心感はサイドパネルの Email Agent に限った話で、MCP を Claude Code や Cursor につないだ瞬間に、その AI クライアントは送信も削除もできる。Access のポリシーを「このアプリを使ってよい人」だけに絞ること、MCP を接続する AI クライアント側で send_email・delete_email の実行前確認を有効にすることが、READMEの設計を前提にした最低限の対策になる。
セットアップと認証——Access が無いと起動しない
README の手順は「Deploy to Cloudflare ボタンを押して終わり」ではなく、デプロイ後の設定が本体だと強調している(Issue #4 のコメントにスクリーンショット付きの手順がある)。
・Deploy to Cloudflare:R2・Durable Objects・Workers AI が自動でプロビジョニングされ、受信ドメイン DOMAINS を聞かれる
・Cloudflare Access の有効化:Worker の Settings → Domains & Routes からワンクリックで Access を付け、表示される POLICY_AUD と TEAM_DOMAIN を Worker のシークレットに設定する
・Email Routing:ドメインの Email Routing で catch-all ルールを作り、この Worker へ転送する
・Email Service:送信用の send_email バインディングを有効にする
・メールボックス作成:デプロイしたアプリで [email protected] のようなアドレスのメールボックスを作る
認証はソースで強制されている。workers/app.ts は POLICY_AUD と TEAM_DOMAIN が未設定なら「Cloudflare Access must be configured in production. Set POLICY_AUD and TEAM_DOMAIN.」を返して止まり、設定済みなら jose の jwtVerify で Access の JWT を JWKS(/cdn-cgi/access/certs)に対して検証する。「Invalid or expired Access token」が出る場合は、Access を一度オフにして再度オンにし、新しい値をシークレットに入れ直すのが README の対処法だ。
実測:Linux でクローンしてビルドする
当サイトでは Cloudflare アカウントを使わず、ローカルでどこまで動くかを確かめた。
# 取得と依存の導入(Node.js 22.22.2)
git clone --depth 1 https://github.com/cloudflare/agentic-inbox
cd agentic-inbox && npm install
# 本番ビルド(React Router v7 のビルド。Worker エントリまで生成される)
npm run build
| 工程 | 結果 | 補足 |
|---|---|---|
npm install |
成功・525パッケージ・19秒 | wrangler 4.74.0・agents 0.7 系・ai 6.0 系が入る |
npm run build |
成功・12.4秒 | build/server/assets/worker-entry-*.js 2.3MB、AgentPanel-*.js 435KB。警告なし |
npm run dev |
未検証 | send_email が remote: true のため Cloudflare へのログインが要る。Email Routing の受信もローカルでは再現できない |
npm run deploy |
未検証 | Cloudflare アカウント・ドメイン・Email Service の有効化が必要 |
デプロイ前に README が求める設定は2つだけで、どちらも1行だ。
# Access のシークレット雛形をローカル用にコピー(本番は wrangler secret put で投入)
cp .dev.vars.example .dev.vars
# 添付ファイル用の R2 バケット(wrangler.jsonc の bucket_name と一致させる)
npx wrangler r2 bucket create agentic-inbox
ローカル開発では .dev.vars に POLICY_AUD/TEAM_DOMAIN を置くが、コメントにあるとおり本番以外では Access 検証を通さない分岐がある。README の「Configuration」は wrangler.jsonc のドメイン設定と wrangler r2 bucket create agentic-inbox の2手順だけで、それ以外の設定は Deploy ボタンが引き受ける。
検証環境:Linux 6.18(x86_64)/Node.js 22.22.2/npm 10.9.7/2026-09-16。クローン・依存導入・本番ビルドまで実測。開発サーバー起動・デプロイ・実メールの送受信・エージェントの応答品質は未検証。
類似アプローチとの比較と、採用の判断材料
「エージェントにメールを持たせる」には他の道もある。Cloudflare の Agents SDK 自体が Email を通信チャネルとして扱う機能を持ち、Agentic Inbox はその上に UI とメールボックス管理を載せたものだ。
| 観点 | Agentic Inbox | Agents SDK の Email チャネルを直接使う | メール API SaaS+自作エージェント |
|---|---|---|---|
| 受信 | Email Routing → Worker(同梱) | 同じ仕組みを自分で配線 | SaaS の Webhook |
| 保存・スレッド | MailboxDO(SQLite)+R2(同梱) | 自作 | SaaS 側 |
| UI | React のメールクライアント(同梱) | 無し | SaaS のダッシュボード |
| 送信の安全弁 | UI は人の Send 必須。MCP は送信可 | 実装次第 | 実装次第 |
| 認証 | Cloudflare Access 必須 | 実装次第 | API キー |
| メンテナンス | コミット11件・最終 2026-04-17・タグ無し | SDK 本体は継続更新 | ベンダー依存 |
Agents SDK 側の設計(Durable Object にエージェントの状態を置く三層構成)はCloudflare Agents SDKとFlue解説|Workers上にAIエージェントを置く三層設計で扱っており、Agentic Inbox の EmailAgent はその実例になる。同じく Durable Object 上に状態を持たせる発想を仮想ファイルシステムに広げたのがCloudflare Computerとは:AIエージェントにDurable Object上の仮想FSと実行環境を与えるOSSで、Cloudflare が「エージェントの持ち物」を DO 単位で分離する設計を繰り返していることが分かる。
採用判断は次の3点に絞れる。
・自ドメインのメールボックスを新設してよいか:既存の Gmail や Microsoft 365 を読むものではない。サポート窓口や通知用アドレスの新設なら合う
・共有 Access で足りるか:メールボックス単位の認可が無いため、利用者全員が全メールボックスを見られてよい範囲で使う
・参照実装として読むか、そのまま運用するか:最終コミットが5か月前でタグも無い。運用するなら依存の更新と Access・MCP まわりの見直しを自分で持つ前提になる
まとめ
Agentic Inbox は、Cloudflare の部品だけでメールの受信・保存・AI 下書き・送信・認証を一式そろえた参照実装として完成度が高く、workers/ を読めば Agents SDK と Email Service の組み合わせ方がそのまま分かる。一方で、サイドパネルのエージェントには送信ツールが無いのに MCP 経由なら送信も削除もできるという非対称と、メールボックス単位の認可が無い点は、README 自身が明記している設計上の割り切りだ。
workers/index.ts・workers/agent/index.ts・workers/mcp/index.ts の3ファイルを読むのが最短。そのまま運用するなら、Access ポリシーの範囲と MCP を接続する AI クライアントの実行前確認を先に決め、5か月止まっている依存の更新を自分で引き受ける覚悟が要る。
参照ソース
・cloudflare/agentic-inbox(公式リポジトリ) — README・wrangler.jsonc・workers/index.ts・workers/agent/index.ts・workers/mcp/index.ts・workers/lib/ai.ts・workers/app.ts(2026-09-16 時点、コミット 48039bb)
・Email · Cloudflare Agents docs — Agents SDK のメールチャネル
・Send emails from Workers · Cloudflare Email Routing docs — send_email バインディング
・Email for Agents(Cloudflare Blog) — README が参照する解説記事(当環境からは取得不可のため本文は未参照)