AI エージェントは、サービスに登録したり、ジョブを開始したり、サポートチケットを起票したりできます。ところが、そこで流れが止まります。返事が、エージェントのいない場所、つまりメールのインボックスに届くからです。確認コード、領収書、「エクスポートの準備ができました」という通知、パスワードのリセットなどです。メールはインターネットで最も古いコールバックの仕組みですが、エージェントにはアドレスがありません。
この記事では、AnyHook が作れた最小限の解決策を紹介します。登録不要の API 呼び出し 1 回で、実際に使えるメールアドレスが返ってきます。そこに届いたメールは構造化されたイベントになり、エージェントは、Webhook が届くのと同じイベントログから、HTTP でそれを読み返します。
TL;DR
POST https://anyhook.net/api/v1/quickstart(認証不要)は、q-cd3fe0f8.quickstart@anyhook.netのようなinbox_addressに加えて、Webhook 用のinbound_urlと API キーを返します- そのアドレスに送られたメールは、
email.receivedイベントになります。中身はfrom、to、subject、message_id、そして完全な生の MIME メッセージです - エージェントは
GET /api/v1/eventsでイベントを一覧にし、GET /api/v1/events/{id}で 1 件を読みます。MCP ならanyhook_inbox、anyhook_events、anyhook_inspectを使います(レジストリ:net.anyhook/anyhook、リモートエンドポイント:https://anyhook.net/mcp) - できるのは受信だけです。送信も返信もできません。これは意図的な境界線で、ロードマップ上の穴ではありません
- Free のエンドポイントは、アカウントに紐付けない限り 7 日で期限切れになります。Free プランの上限は 1,000 件/日です
呼び出しは 1 回だけ
curl -X POST https://anyhook.net/api/v1/quickstart
{
"inbound_url": "https://in.anyhook.net/q-cd3fe0f8/quickstart",
"inbox_address": "q-cd3fe0f8.quickstart@anyhook.net",
"api_key": "ahk_live_…",
"claim_url": "https://anyhook.net/claim/…",
"expires_at": "2026-08-06T…"
}
アカウントの作成も、CAPTCHA も、OAuth の同意画面のクリックも要りません。ここでの呼び出し元は人間でないことが多いので、これは重要です。呼び出し元はタスクの途中にいるエージェントで、流れの中にある登録フォームは、どれもタスクが死ぬ場所になります。エンドポイントは、人間が claim_url からアカウントに紐付けるまでは一時的なもの(7 日)です。これは不正利用の上限でもあります。匿名のものは、どれも TTL を超えて生き残りません。
これで、同じ App(Webhook の送信元ごとに作る受信設定)が、2 つの経路で受け付けるようになります。
| 経路 | アドレス |
|---|---|
| HTTP の Webhook | https://in.anyhook.net/q-cd3fe0f8/quickstart |
| メール | q-cd3fe0f8.quickstart@anyhook.net |
どちらも 1 つのイベントログに入るので、エージェントから見れば、「Stripe の Webhook を待つ」ことも「確認メールを待つ」ことも同じ操作です。イベントの API をポーリングし、ペイロードを調べるだけです。
メールは何になるか
そのアドレスに、何でもよいのでメールを送ってみてください。数秒以内に、イベントとして現れます。
{
"type": "email.received",
"from": "noreply@github.com",
"to": "q-cd3fe0f8.quickstart@anyhook.net",
"subject": "Your verification code is 481920",
"message_id": "<abc123@mail.example.com>",
"date": "Thu, 30 Jul 2026 11:42:31 +0700",
"size": 7026,
"raw": "Received: from …"
}
raw は、完全で手を加えていない MIME メッセージです。すべてのヘッダー、すべてのパート、すべての添付ファイルが、届いたとおりに入っています。メタデータのフィールドは便宜のためのもので、信頼できる情報源は生のメッセージです。エージェントで最も多い用途、つまり確認メールからコードを取り出す場合は、たいてい件名だけで足ります。それ以上のことをするなら、使っている言語の標準ライブラリで MIME をパースしてください。標準ライブラリは、まさにそのためにあります。
読み返すには、次のようにします。
curl https://anyhook.net/api/v1/events \
-H "Authorization: Bearer ahk_live_…"
# the list carries no payloads; this returns one event with its body
curl https://anyhook.net/api/v1/events/<id> \
-H "Authorization: Bearer ahk_live_…"
MCP で使う
エージェントが MCP を使えるなら、curl に触れる必要はまったくありません。サーバーは 公式の MCP レジストリに net.anyhook/anyhook として登録されていて、npm パッケージの anyhook-mcp と、https://anyhook.net/mcp のリモートの streamable HTTP エンドポイントとして提供されています。
anyhook_quickstartがinbox_addressを直接返します(npm パッケージならキーなしで実行できます。リモートエンドポイントでは、先に API キーかログインが必要です)anyhook_inboxは、既存の App のアドレスと、その Webhook の URL を返しますanyhook_eventsとanyhook_inspectで、届いたものを読みます
オンボーディングは、クイックスタートのツールだけで完結します。レジストリでサーバーを見つけたエージェントは、人間を介さずに自分でインボックスを作り、受信を始められます。人間が登場するのは後になってから、それも必要な場合だけで、アカウントに紐付けるためです。
仕組み(と、アドレスがこの形をしている理由)
内部には、意図的に別のパイプラインを用意していません。
- Cloudflare Email Routing のキャッチオールが、そのドメイン宛てのすべてのメッセージを、Webhook を受信するのと同じエッジの Worker に渡します
- Worker は、
{user-slug}.{app-slug}@anyhook.netというアドレスのローカル部を、最後のドットで分割します。スラッグは作成時に[a-z0-9-]に制限されるのでドットを含むことはなく、構造上、分割があいまいになることはありません - メッセージは、もし Webhook だったらそうなっていたはずの HTTP リクエストに詰め直されます。その下流のすべて(クォータ、ペイロードの上限、キューイング、リトライ、転送先への配信、イベントログ)は、Webhook が通るのとまったく同じコードパスです
実在する App に解決できないメールは、黙って飲み込むのではなく、SMTP の段階で拒否します。エラーを受け取らなかった送信者は、届いたものと考えるからです。サイズの大きすぎるメッセージも、同じように差し戻します。
Webhook の側から、2 つの性質がそのまま引き継がれます。メッセージのボディは、データベースに触れる前に AES-256-GCM で暗号化されます。そして、各イベントのハッシュは App ごとのチェーンに畳み込まれ、毎日封印されます。各日のルートは、AnyHook が認証情報を持たない 公開の Git リポジトリにコミットされます。保存したメールを、その日が封印された後に AnyHook が編集すれば、公開されているアンカーで検証が通らなくなります。
これは何ではないか
送信はしません。返信も、外部へのメールも、SMTP の認証情報もありません。送信には、到達率、SPF/DKIM のアライメント、IP レピュテーション、スパムの責任がついて回ります。それは、失敗の仕方も異なる別の分野です。エージェントに、製品として完全な双方向の会話型メールが必要なら、そのカテゴリーは存在します(AgentMail は、まさにその主張で資金を調達しました)。Webhook 中継サービスに後付けした受信専用のインボックスは、もっと狭いものです。入ってくるものすべてを、1 つのイベントログにまとめるだけです。
使い捨てメールのサービスでもありません。想定しているのは、自分のシステムが生成するメールです。エージェントが正当に運用しているアカウントの確認メール、連携しているサービスからの通知、自分のフローから出る領収書などです。Free のエンドポイントにはレート制限と上限があり、期限切れにもなります。不正利用のパターンはブロックされます。サービスの規約が自動登録を禁止しているなら、インボックスがあってもそれは変わりません。
プッシュではなく、ポーリングです。エージェントが「何が届いた?」と尋ねるだけで、何かがエージェントを起こすことはありません。遅延を小さくしたいなら、destination_url を設定してください。イベントは届いた時点で、自分のサーバーに転送されます。メールが Webhook になるのです。
試してみる
# 1. mint an inbox (no signup)
curl -X POST https://anyhook.net/api/v1/quickstart
# 2. send any email to the inbox_address you got back
# 3. find it, then read it
curl https://anyhook.net/api/v1/events -H "Authorization: Bearer <api_key>"
curl https://anyhook.net/api/v1/events/<id> -H "Authorization: Bearer <api_key>"
セットアップにかかる時間は、手順 2 のメールが届くまでの時間だけです。