エージェント2026年7月30日6 分で読めます

AI エージェントにメールアドレスを API 1 回で持たせる

確認コードも領収書も通知も、今もメールで届きます。キー不要の呼び出し 1 回で、エージェントは Webhook イベントとして読めるインボックスを持てます。

メールアドレスも、ただの受信 URL誰でもメールを送るMXルーティングパース + 検証POSTハンドラーまたはエージェントログほかの Webhook の送信元と同じリトライ、同じイベントログ、同じ再送ボタン
すでに運用しているほかの Webhook の送信元と、まったく同じように振る舞うインボックス。

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 の Webhookhttps://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_…"
新規登録なし、CAPTCHA なし、ブラウザーなしエージェントターミナル/サンドボックスPOST /quickstartエンドポイントURL + API キープロバイダーに設定イベント到着API で読める紐付けエージェントが用意したものを人間が引き継ぐエンドポイントはセッションより長く残るので、12 時間のバッチジョブにも届け先がある
Webhook エンドポイントと同じ、立ち上げてから紐付ける形。インボックスは、入口が違うだけ。

MCP で使う

エージェントが MCP を使えるなら、curl に触れる必要はまったくありません。サーバーは 公式の MCP レジストリに net.anyhook/anyhook として登録されていて、npm パッケージの anyhook-mcp と、https://anyhook.net/mcp のリモートの streamable HTTP エンドポイントとして提供されています。

  1. anyhook_quickstart が inbox_address を直接返します(npm パッケージならキーなしで実行できます。リモートエンドポイントでは、先に API キーかログインが必要です)
  2. anyhook_inbox は、既存の App のアドレスと、その Webhook の URL を返します
  3. anyhook_events と anyhook_inspect で、届いたものを読みます

オンボーディングは、クイックスタートのツールだけで完結します。レジストリでサーバーを見つけたエージェントは、人間を介さずに自分でインボックスを作り、受信を始められます。人間が登場するのは後になってから、それも必要な場合だけで、アカウントに紐付けるためです。

仕組み(と、アドレスがこの形をしている理由)

内部には、意図的に別のパイプラインを用意していません。

  1. Cloudflare Email Routing のキャッチオールが、そのドメイン宛てのすべてのメッセージを、Webhook を受信するのと同じエッジの Worker に渡します
  2. Worker は、{user-slug}.{app-slug}@anyhook.net というアドレスのローカル部を、最後のドットで分割します。スラッグは作成時に [a-z0-9-] に制限されるのでドットを含むことはなく、構造上、分割があいまいになることはありません
  3. メッセージは、もし 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 のメールが届くまでの時間だけです。

すべての記事2026年7月30日 · 6 分

Webhook を、もう取りこぼさない。

URL を 1 つ変えるだけで、リトライ、イベントログ、1 クリックでの再送が使えます。先に動きを見ることもできます。新規登録して 30 秒の障害訓練を実行すると、サーバーがダウンしていてもイベントが失われない様子を確認できます。サーバーを用意する必要はありません。