A2H: ask a human について
A2H: ask a human は、エージェントやスクリプトが人に承認や情報を求め、署名付きの応答を受け取るセルフホスト可能なゲートウェイです。メール、Telegram、プッシュに対応し、高い保証レベルの承認ではパスキー検証を要求できます。
主な機能
- 01承認、情報、通知の依頼
- 02メール、Telegram、プッシュで依頼を送信
- 03応答への署名と決定の検証
- 04高保証レベルの承認でパスキーを必須化
- 05リプレイ攻撃から依頼を保護
活用シーン
- 01デプロイ前に人の承認を求める
- 02フォームで人から情報を収集
- 03重要な操作の承認者を検証
- 04エージェントの進捗や結果を人に通知
MCP 対応
`a2h mcp` MCP サーバーは、承認依頼、質問、通知、保留中の依頼の確認とキャンセルを行うツールを提供します。決定を返す前にゲートウェイの署名を検証します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e A2H_GATEWAY -e A2H_API_KEY -e A2H_TO -e A2H_PRINCIPAL ghcr.io/andreaacanfora/a2h-gateway:0.3.0A2H_GATEWAYURL of your A2H gateway, e.g. https://a2h.example.comA2H_API_KEYシークレットAPI key of the gatewayA2H_TOWhere to reach you: mailto:[email protected], tg:<chat_id> or an ntfy topic URLA2H_PRINCIPALYour principal ID on the gateway (optional)ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/andreaacanfora/a2h-gateway:0.3.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
a2h-gateway
A2H(エージェントから人間へのプロトコル)を実装するセルフホスト可能なゲートウェイです。AI エージェントやスクリプトが人に承認や情報を求めると、人はメール、Telegram、プッシュ通知から回答し、エージェントは誰が判断したかを証明する、署名付きの回答を受け取ります。SQLite を使用する単一の Go バイナリです。
$ a2h ask -to mailto:[email protected] -why "Rolls back if health checks fail." "Deploy v2.3 to production?"
Waiting for an answer from mailto:[email protected] (interaction 01a1bbcf-…)…
Approved (email_link.v1) at 2026-11-08T15:37:50Z.
$ echo $?
0
A2H は Twilio Labs によって 2026 年 2 月に、仕様、OpenAPI スキーマ、概念実証デモとともに公開されました。ロードマップには、次のステップとしてリファレンスゲートウェイと正式な JSON Schema が記載されています。このプロジェクトは、その両方を実装した独立した実装であり、Twilio とは提携していません。
できること
- A2H 1.0 のエージェント向け API 全体:ディスカバリー(
/.well-known/a2h)、POST /v1/intent、ステータス、キャンセル、ノンス、JWKS。 - すべてのインテント:AUTHORIZE(承認または拒否)、COLLECT(テキスト、選択肢、数値、日付を含むフォーム。検証機能付き)、INFORM、RESULT、ESCALATE。
- チャネル:メール(SMTP)、Telegram ボット、ntfy 経由のプッシュ通知(セルフホストまたは ntfy.sh)、開発用のコンソールチャネル。仕様に記載されたバックオフで再試行し、フォールバックチャネルを使用します。
- 判断の証明:
- すべての RESPONSE に署名します(JCS に対する ES256 デタッチド JWS。鍵は JWKS に格納)。
assurance.level: HIGHを含むリクエストは、パスキー(WebAuthn)で承認する必要があります。セクション 1.11.4 の要件に従い、チャレンジはインタラクションに紐付けられます。
- リプレイ保護:
message_idによる冪等性。- タイムスタンプウィンドウと使い捨てノンス。
- 有効期限がインタラクションと連動する、使い捨ての推測困難なリンク。
- Webhook:HMAC で署名(
X-A2H-Signature)し、10 秒/60 秒/5 分後に再試行します。フォールバックとしてポーリングも利用できます。 - すべての A2H メッセージに対応する JSON Schema は
schemas/にあります。 - MCP サーバー(
a2h mcp):Claude、Cursor などの MCP クライアントのエージェントが、ツールを使ってあなたに承認を求めます。 - あらゆる A2H ゲートウェイをテストする適合性テストスイート:
a2h conform。
クイックスタート
リリースから Linux、macOS、Windows、FreeBSD 用のバイナリをダウンロードするか、Docker イメージ ghcr.io/andreaacanfora/a2h-gateway を使うか、Go でインストールします。
go install github.com/AndreaAcanfora/a2h-gateway/cmd/a2h@latest
# Development: no authentication, links printed in the log.
A2H_BASE_URL=http://localhost:8080 A2H_DEV=1 a2h serve
別のターミナルで、次を実行します。
A2H_GATEWAY=http://localhost:8080 a2h ask -to console:me "Delete 3 unused files?"
ゲートウェイはリンク(url=http://localhost:8080/i/…)をログに出力します。そのリンクを開いて承認すると、a2h ask は 0 を返して終了します。
本番環境での利用
docker run -d -p 8080:8080 -v a2h-data:/data \
-e A2H_BASE_URL=https://a2h.example.com \
-e A2H_API_KEYS="deploy-bot:$(openssl rand -hex 24)" \
-e SMTP_HOST=smtp.example.com -e [email protected] -e SMTP_PASSWORD=… \
-e TELEGRAM_BOT_TOKEN=123456:ABC… \
-e A2H_PUSH=1 \
ghcr.io/andreaacanfora/a2h-gateway
HTTPS の背後に配置してください。ユーザーはそのリンクを開き、パスキーはセキュアなオリジンでのみ機能します。
Telegram:@BotFather でボットを作成し、ボットからメッセージを送信できるように、作成したボットに何かメッセージを送信してください。チャット ID は https://api.telegram.org/bot<token>/getUpdates の message.chat.id にあります。A2H_BASE_URL が公開ホスト名の場合、メッセージにアクションボタンが表示されます。Telegram は localhost のボタンを拒否するため、localhost の場合は本文にリンクが表示されます。
| 変数 | 意味 |
|---|---|
A2H_BASE_URL | ユーザーが開く公開 URL(必須) |
A2H_LISTEN | リッスンアドレス。デフォルトは :8080 |
A2H_DATA_DIR | データベース、署名鍵、リンクシークレット。デフォルトは ./a2h-data |
A2H_API_KEYS | name:key のペアをカンマ区切りで指定。エージェントは X-A2H-API-Key を送信 |
SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM | メールチャネル(STARTTLS または TLS) |
TELEGRAM_BOT_TOKEN | Telegram チャネル。アドレスは tg:<chat_id>(下記参照) |
A2H_PUSH, NTFY_TOKEN | プッシュチャネル(ntfy)。アドレスはトピック URL |
A2H_CONSOLE | コンソールチャネル(リンクをログに出力) |
A2H_DEV | 開発モード:認証なし、http:// Webhook、コンソール。絶対に外部へ公開しないでください。 |
エージェントからのリクエスト
任意の HTTP クライアントを使用できます。
curl -s https://a2h.example.com/v1/intent -H "X-A2H-API-Key: $KEY" -H 'content-type: application/json' -d '{
"type": "AUTHORIZE",
"message_id": "'$(uuidgen)'",
"agent_id": "did:web:booking-agent.example.com",
"principal_id": "usr_alice",
"channel": { "type": "email", "address": "mailto:[email protected]",
"fallback": [{ "type": "push", "address": "https://ntfy.sh/alice-a2h-7f3k" }] },
"render": { "title": "Book flight?", "body": "Book the non-refundable flight to Lisbon for 412 EUR?" },
"explanation_bundle": { "why": "The fare expires in 30 minutes." },
"ttl_sec": 1800,
"callback": { "url": "https://agent.example.com/a2h/webhook", "secret": "whsec_…" }
}'
その後、Webhook を待つか、状態が ANSWERED、EXPIRED、CANCELLED、FAILED のいずれかになるまで GET /v1/status/{interaction_id} をポーリングします。
Go では、a2h パッケージがこれらの処理をすべて行い、回答を検証します。
c := a2h.NewClient("https://a2h.example.com", key)
sent, _ := c.Send(ctx, msg)
status, _ := c.Wait(ctx, sent.InteractionID, 2*time.Second)
resp, err := c.VerifyResponse(ctx, status.Response, msg.MessageID) // checks responds_to and the JWS
if err == nil && resp.Decision == a2h.Approve { /* go ahead */ }
AI エージェントから利用する(MCP)
a2h mcp は Model Context Protocol
サーバーです。Claude Code、Claude Desktop、Cursor などの MCP クライアントは、操作を実行する前にあなたに確認するためのツールを利用できます。
| ツール | 機能 |
|---|---|
request_approval | 操作を承認するか却下するかをあなたに尋ね、確認済みの判断を返します |
ask_human | 短いフォーム(テキスト、数値、日付、選択肢、はい/いいえ)の入力をあなたに依頼します |
notify_human | あなたにメッセージ(進捗、結果、アラート)を送信します |
check_request | まだ応答待ちのリクエストを確認します |
cancel_request | 回答されていないリクエストを取り消します |
公式の MCP Registry には
io.github.AndreaAcanfora/a2h-gateway として登録されているため、レジストリを参照する MCP クライアントからインストールできます。または、手動で設定することもできます。
Claude Code:
claude mcp add a2h \
-e A2H_GATEWAY=https://a2h.example.com -e A2H_API_KEY=… -e A2H_TO=tg:123456789 \
-- a2h mcp
Claude Desktop(claude_desktop_config.json)、Cursor など:
{
"mcpServers": {
"a2h": {
"command": "a2h",
"args": ["mcp"],
"env": { "A2H_GATEWAY": "https://a2h.example.com", "A2H_API_KEY": "…", "A2H_TO": "mailto:[email protected]" }
}
}
}
次に、エージェントにいつ確認するかを伝えます。例:「何かを削除したり、お金を使ったりする前に、request_approval で私に確認してください」。
- 受信者は設定で指定します。 モデルは質問を作成できますが、送信先は選べないため、エージェントが他の人にメッセージを送ることはできません。
- 回答は検証されます。 ツールが判断を報告する前に、ゲートウェイの署名と照合します。検証に失敗した回答は、承認ではなく失敗として報告されます。
- 待ち時間が長い場合: ツールの呼び出しは最大 10 分(
-max-wait)待機し、その間、進捗通知を送信します。それまでに相手から回答がなければ、ツールはその旨を伝え、エージェントはcheck_requestを使って処理を続けます。 - 重大な操作の場合:
require_passkey: trueにすると、承認にパスキーが必要になります。
重大な承認にパスキーを使用する
"assurance": {"level": "HIGH"} を含むリクエスト(または passkey.webauthn.v1 を含む required_factors のリクエスト)は、クリックだけでは承認できません。本人がパスキー(Face ID、Touch ID、Windows Hello、セキュリティキー)で確認する必要があります。パスキーを登録できるのはサーバーから操作するオペレーターだけです。
a2h enroll -principal usr_alice
# Send this link to usr_alice. It works once and expires in 24h0m0s:
# https://a2h.example.com/enroll/…
その後、RESPONSE には WebAuthn アサーション、チャレンジ nonce、公開鍵が含まれるため、エージェントは本人の署名を自ら検証できます。
準拠性
a2h conform -gateway https://gateway.example.com -key $KEY -to mailto:[email protected]
PASS MUST §1.4 discovery document
PASS MUST §1.3 RESPONSE type from an agent is rejected
PASS MUST §1.5 unsupported profile is rejected
PASS MUST §1.10.2 duplicate message_id returns the original interaction
PASS MUST §1.7 cancel a waiting interaction
…
conforming to the agent-facing API of A2H 1.0
このテストスイートは、指定したアドレスに実際のインテントを送信してから、それらを取り消します。
仕様の曖昧な点
A2H 1.0 では、一部の詳細が未定義のままになっているか、2 通りの説明がされています。ここで採用した方針は、次のバージョンの仕様へのフィードバックとして、docs/implementation-notes.md に記載しています。
開発
go test -race ./... # unit and integration tests
go build -o e2e/a2h ./cmd/a2h && (cd e2e && npm install && npm test) # passkeys in Chromium
ライセンス
MIT。A2H は Twilio Labs の著作物であり、MIT ライセンスのもとで提供されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。