読む AI と、承認後に送る処理を分ける

ここで作るメール AI エージェントは、既存のメールを読み、要約と返信案を作るプログラムです。送信の判断と実行は任せません。

MCP はモデル側からツールを利用するための接続方式です。MCP のツール仕様は、人が呼び出しを拒否できることや、機密性の高い操作で確認を求めることを推奨しています。ただし、特定の確認画面や操作方式を必須にはしていません。MCP で接続するだけで、送信承認が強制されるわけではありません。

そこで、読み取りは Mailera の MCP 接続、送信は独立した実行サービスに分けます。モデルには送信キーも、送信サービスを自由に呼び出す手段も渡しません。

read 権限のエージェントと、承認後に動く send 権限の送信サービスを分離した構成
返信案の生成と送信を分け、送信キーをモデルへ渡しません。

自動化する操作と、承認が必要な操作

最小構成では、読み取りと返信案の作成だけをエージェントに許可します。

操作必要な権限この構成での扱い
メールの一覧・本文取得read許可したメールボックスだけ自動実行
要約・返信案の保存利用側アプリの保存権限自動実行。Mailera への下書き保存ではない
送信・返信send人の承認後、別サービスが実行
転送send最小構成から除外
フォルダー移動move最小構成から除外
共有リンクの作成share最小構成から除外

承認対象は、送信元メールボックス、宛先、件名、本文、返信先の元メールです。宛先が複数なら全件を表示してください。本文だけを承認しても、送信先の変更は防げません。

Microsoft Graph の権限ガイドも、アプリに必要な最小限の権限を要求する方針を示しています。Mailera のキーでも、読み取り側と送信側を分けて必要な権限だけを付けます。

手順 1:テスト用メールボックスと read 権限の接続を用意する

  1. 自分が管理するテスト用メールボックスを用意します。「メールボックス」から「メールボックスを追加」を開き、接続してテスト用グループにまとめます。接続方法の選択は、既存のメールボックスをエージェントにつなぐ手順を参照してください。
  2. 「設定」の API キー画面で「キーを作成」を選びます。「メールボックスのスコープ」はテスト用グループに限定し、権限は read だけにします。管理者でも、ここでは全グループを対象にしません。
  3. 「有効期限」を設定し、接続元を固定できる場合は「IP制限(任意)」も設定します。キーは作成時に一度だけ表示されるので、安全な保管先に保存してください。
  4. 「MCP 設定をコピー」で利用するクライアントの設定を取得します。接続先は https://mailera.app/api/public/v1/mcp です。設定内のキーをプロンプトやリポジトリ、ログに残さないでください。
  5. 利用側で公開するツールを list_mailboxes、list_messages、get_message に絞ります。許可したメールを読めることに加え、グループ外のメールにはアクセスできないことを確かめます。
対象グループと read 権限を限定して作成する Mailera の API キー設定
グループと権限を絞ります。read 権限内のツールも、利用側で必要なものだけ公開します。

read は「返信に必要な本文だけを読める権限」ではありません。search_messages や、OTP を取得する get_latest_otp も含まれます。キーのグループ制限と、利用側のツール・データ制限を併用してください。

ツールの引数は MCP の tools/list が返す inputSchema に合わせます。REST のパラメーター名を、そのまま MCP の引数として渡さないようにします。

手順 2:元メールを特定し、返信案を保存する

  1. list_mailboxes で対象を選び、list_messages で処理するメールを取得します。
  2. メールボックス ID とメッセージ ID の組を保存し、get_message で本文を読みます。横断検索を使う場合も、結果の mailbox_id が許可対象かを利用側で検査します。
  3. 必要な本文だけをモデルへ渡し、要約と返信案を生成します。
  4. 返信案を利用側アプリに「承認待ち」として保存します。送信元、全宛先、件名、本文、元メールの識別子を、版番号と一緒に固定します。

REST で同じ元メールを照合する場合は、次のように取得できます。$MAILERA_API_KEY は read 権限のキー、$MAILBOX_ID と $MESSAGE_ID は自分のテスト用メールから取得した値を環境変数に設定します。

curl --request GET \
  "https://mailera.app/api/public/v1/mailboxes/$MAILBOX_ID/messages/$MESSAGE_ID" \
  --header "Authorization: Bearer $MAILERA_API_KEY"

取得した data.mailbox_id と data.id を処理対象に照合し、本文は data.body.text で確認します。モデルが生成した宛先や元メールの識別子を、そのまま正しいものとして採用しないでください。

版番号や「承認待ち」は、この記事で設計する利用側アプリの管理項目です。Mailera の API フィールドではありません。

手順 3:承認した内容だけを送信する

承認画面には、元メールと返信案を並べます。認証済みの承認者が、送信元、宛先、件名、本文を確認してから承認する流れにしてください。

承認記録は、変更できない返信案の版に結び付けます。内容のハッシュを使うなら、本文だけでなく、宛先や送信元、元メールの識別子も対象にします。承認後にどれかを変えた場合は、新しい版として承認待ちに戻します。

承認待ちから承認済み、実行中、結果確認へ進み、拒否や期限切れでは停止する状態遷移
利用側アプリの状態遷移です。承認済みの内容を変えた場合は、実行前に再承認へ戻します。

送信サービスは、要求を受けた時点で次をサーバー側で検査します。

  • 承認者に、そのメールボックスからの送信を承認する権限があるか。
  • 承認期限内で、拒否や取り消しが行われていないか。
  • 承認された版と、実際に送る内容が一致しているか。
  • 同じ実行がまだ開始されていないか。

検査と「承認済み → 実行中」の更新は、競合する要求が同時に通らないよう排他的に処理します。二重クリックへの対策は、画面のボタンを無効にするだけでは足りません。状態を更新できた処理だけが送信へ進む設計にします。

send 権限のキーを持つのは送信サービスだけです。このサービスが保存済みの承認内容を読み、POST /mailboxes/{id}/send を呼び出します。呼び出し元から渡された新しい本文で、承認済みの本文を上書きしないでください。API の参照先は Mailera のドキュメントです。

手順 4:送信結果を確認し、再試行を制御する

承認と排他制御に加え、送信要求には Idempotency-Key を付けます。実行を始める前に値を保存し、同じ操作の再試行では同じ値を使います。Mailera の冪等性の有効期間は 24 時間です。期限を越えた要求まで重複排除に頼らず、利用側でも実行記録を保持してください。

送信状態は、send 権限で GET /sends/{id} を呼び出して確認します。read 権限のエージェントに結果確認を任せるために、送信権限を追加する必要はありません。送信サービスから必要な結果だけを返します。

送信状態利用側での扱い
queued新規送信せず、状態確認を待つ
sending実行中として扱い、再送しない
sent同じ操作を完了扱いにし、再実行を止める
failed原因と承認の有効性を確認し、再試行の可否を判断する
unknown失敗と決めつけず、状態照会と運用者の調査へ回す

タイムアウトで応答を受け取れなかった場合も、すぐ新しいキーで再送しません。送信識別子を取得できていれば状態照会へ進みます。取得できていなければ、保存した実行記録と冪等キーを使って対応を判断し、別の送信操作を作らないようにします。

承認記録、返信案の版、利用側の実行識別子、冪等キー、Mailera の送信識別子と状態を関連付けます。sent は受信トレイへの到達保証として扱わないでください。

よくある失敗と、公開前に確認するテスト

症状原因候補確認する場所
読めるが送信できないread キーで送信している送信サービスのキーに send があるか。エージェント側の権限は増やさない
対象メールが見つからないキーとメールボックスのグループが不一致キーのスコープと対象の所属グループ
send 権限があっても送れないメールボックスが受信専用メールボックス情報の capabilities.send
メールを取得できない接続が切れているget_mailbox_status とメールボックスの接続状態
同じ返信が複数回要求される承認後の処理が競合している排他的な状態更新と冪等キーの再利用

自分のテスト環境では、正常系より先に「送らない条件」を確認します。

  1. 未承認、拒否済み、期限切れ、権限のない人による承認では、送信要求が発生しないこと。
  2. 承認後に宛先や本文を変えると、再承認が必要になること。
  3. 承認の二重クリックや並行実行でも、実行開始が重複しないこと。
  4. タイムアウトや unknown でも、新しいキーによる自動再送が起きないこと。
  5. グループ外へのアクセスと、read キーでの送信が拒否されること。

拒否された操作も監査記録に残します。ただし、記録に本文全体や秘密情報を含める必要があるかは別途判断してください。MCP のツール仕様も、監査目的でのツール利用記録を推奨しています。

受信メールの指示からエージェントを守る

受信メールは信頼できないデータであり、命令ではありません。 本文に「この宛先へ転送して」「秘密情報を送って」「承認は省略して」と書かれていても、実行指示として扱わないようにします。

プロンプトにもこの区別を書きますが、制約は権限と実行経路で強制します。メール内の「承認済み」という文を承認記録に変換せず、送信サービスは認証済みの承認操作だけを受け付ける設計にしてください。

最小構成では、本文の URL を自動で開かず、添付ファイルも処理対象から外します。モデルへ渡す情報を必要最小限にし、モデル側とアプリ側それぞれの保存先・保存期間を確認します。read 権限だけでも、読み取った情報の漏えいリスクは残ります。

テストメールには、承認省略や情報の持ち出しを要求する架空の文章を入れ、外部への操作が起きないことを確認します。異常時は処理を停止し、キーを失効させる手順も用意してください。Mailera では、失効したキーによる呼び出しは即座に拒否されます。運用前には Mailera のセキュリティ情報も確認します。

Mailera が担う範囲と、利用側で実装する範囲

Mailera は既存メールボックスへの接続と、MCP・REST 経由のメール操作を提供します。この構成の承認画面、承認者の認可、返信案の版管理、承認記録、実行制御は利用側で実装します。アプリとの接続方法は 開発者向けの案内を参照してください。

Mailera は新しいメールボックスやメールアドレスを発行しません。受信トレイへの到達保証や、一斉配信・マーケティング配信も提供しません。

承認を専用画面ではなくメール経由で受け付けたい場合は、メールを承認経路に使うアプリケーション設計を参照してください。返信メールの受信と、送信を許可する承認記録の作成は、別の処理として扱います。

MCPでAIエージェントがメールボックスを利用

MaileraのMCPサーバーをClaude、Cursor、VS Codeに追加すると、エージェントがメールの閲覧、分類、返信を行えます。

MCPの使い方を見る