che-apple-mail-mcp について
che-apple-mail-mcpは、Apple Mailの検索、メッセージ操作、下書き、メールボックス管理を行うSwift製MCPサーバーです。SQLite検索パスとバッチ操作により、大量のメールを扱えます。
主な機能
- 01SQLiteを利用したメール検索
- 02件名、送信者、宛先、日付で検索
- 031回につき最大50通の一括操作
- 04メールボックス、ルール、VIP送信者の管理
- 05メールの作成、返信、転送、下書き保存
- 06ヘッダー、ソース、添付ファイルへのアクセス
活用シーン
- 01大量のApple Mailアーカイブを検索
- 02複数のメールをまとめて移動またはフラグ付け
- 03確認用の返信や下書きを作成
- 04メールヘッダーの確認や添付ファイルの保存
MCP 対応
MCPクライアントにApple Mailのアカウント、メールボックス、メッセージ、作成、添付ファイル、ルール操作を提供します。READMEには54のMCPツールが記載されています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
che-apple-mail-mcp
最も包括的な Apple Mail MCP サーバー - 54 個のツールを搭載し、SQLite を活用して 25 万件以上のメールをミリ秒単位で検索できます。
che-apple-mail-mcp を選ぶ理由
| 機能 | その他の MCP | che-apple-mail-mcp |
|---|---|---|
| ツール総数 | ~20 | 54 |
| 言語 | Python | Swift(ネイティブ) |
| 検索速度 | 数秒(AppleScript) | ミリ秒(SQLite) |
| 検索フィールド | 件名/送信者 | 件名/送信者/受信者/日付 |
| 一括操作 | なし | 1 回の呼び出しで最大 50 件のメール |
| メールボックス管理 | 基本機能 | 完全な CRUD |
| メールの色 | なし | 7 種類のフラグ色+背景色 |
| VIP 管理 | なし | あり |
| ルール管理 | 一部 | 完全な CRUD |
| 署名 | なし | あり |
| 生ヘッダー/ソース | なし | あり |
クイックスタート
プラグインをインストールします。署名済みバイナリ、/archive-mail コマンド
ファミリー、安全ルール、古さを検知するフックが一体となって提供されます。
claude plugin marketplace add PsychQuant/che-apple-mail-mcp
claude plugin install che-apple-mail-mcp@che-apple-mail-mcp
次にアクセス権を付与します。セットアップウィンドウで状態をリアルタイムに確認でき、適切な「システム設定」画面へのリンクも表示されます。
~/bin/CheAppleMailMCP --setup
💡 フルディスクアクセスを付与すると、高速な SQLite 読み取りパスと
batch_export_emails_markdownが利用できます。これがなくてもツールは動作しますが、読み取れるデータはほとんど、あるいはまったくありません。そのため、権限の問題ではなくバグだと誤解されがちです。macOS ではアプリからプログラムで FDA を要求できず、手動でチェックを付ける必要があります。セットアップウィンドウは、この操作を素早く行えるように用意されています。
プラグインと MCP のみの場合
MCP サーバー単独で登録する方法も、上級者向けのサポート対象ですが、インストールされる内容は明らかに少なくなります。次の機能がないことを承知のうえで選択してください。実行時に不足を知らせるものはありません(#353)。
| プラグインに含まれるもの | MCP のみの場合 |
|---|---|
| MCP ツール 54 個すべて | ✅ あり |
/archive-mail + -migrate/-rebuild-threads/-repair-synthetic-ids/-view | ❌ アーカイブ手順書がありません |
rules/compose-wrapper-free.md — cite-block とは何だったのか、compose 呼び出しが拒否された場合に何を意味するのか | ⚠️ 背景:#304 以降、ラッパーは構造上使用できなくなったため、このルールは無言のフォールバックを防ぐのではなく、6 つの拒否理由とその対処方法を説明しています |
rules/confirmation-triggers.md、rules/false-positive-detection.md | ❌ 破壊的な操作に対する確認の指針がありません |
hooks/session-start.sh — 古いバイナリの実行を停止 | ❌ アップグレード後も、セッションで古いバイナリが使われ続けることがあります |
| Developer ID による署名済み+公証済みバイナリ | ❌ 自分でビルドしたバイナリはアドホック署名です。macOS 26 では TCC がフルディスクアクセス/オートメーションの権限を確実に保持できず、権限を付与したように見えても動作しなくなります(#211) |
バージョンサイドカー → --self-update + #303 の古さを確認する自己診断 | ❌ 手動ビルドしたバイナリの隣にはサイドカーがないため、このチェックは常に無反応です |
上級者向け:MCP サーバーのみを登録(開発用、またはプラグインを使わない場合)
git clone https://github.com/PsychQuant/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release
# --scope user : available across all projects (stored in ~/.claude.json)
# --transport stdio: local binary execution via stdin/stdout
# -- : separator between claude options and the command
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP
バイナリは ~/bin/ のようなローカルディレクトリにインストールしてください。クラウド同期フォルダー(Dropbox、iCloud、OneDrive)は避けてください。同期処理によって MCP 接続がタイムアウトすることがあります。
自分でビルドしたバイナリで TCC の権限を再ビルド後も保持するには、Developer ID で署名してください。詳しくは署名と公証を参照してください。そうしない場合、ビルドのたびに権限を再付与する必要があります。
最近のリリース
詳細については、CHANGELOG.mdを参照してください。
v2.7.2 (2026-05-10) — attachmentFragment の一連の修正+フォールバックの同等性
- 3 つすべての呼び出し元で
attachmentFragmentのインデントを堅牢化し、v2.7.0 の競合状態緩和用の遅延を迂回していた未使用のMailController.attachmentScriptヘルパーを削除しました(#61、#62) - 添付ファイル数の上限(50)を設定し、
CHE_MAIL_ATTACHMENT_DELAY_BETWEEN/_TRAILINGで遅延を環境変数から設定できるようにしました(#63、#64) get_email_metadataの SQLite パスでエラー時に AppleScript にフォールバックするようになりました。これにより最後に残っていた読み取りツールの不足が解消され、SQLite を優先する 8 つすべての読み取りツールに同等のフォールバックが備わりました(#71)
v2.7.1 (2026-05-09) — base64 の修正+.partial.emlx+可観測性
- 重大:RFC822 ヘッダーと本文の分割で、絶対
Dataインデックスではなく相対配列インデックスを返していたため、一部の Android Gmail メッセージでhtml_bodyが"sion: 1.0\n\n<base64>"から始まっていました。生の base64 が LLM のコンテキストに漏れ、後続処理で AUP の誤検知を引き起こしていました(#72) .partial.emlxの本文が空の場合、save_attachmentはAttachments/<rowId>/<part_id>/<filename>キャッシュから読み込むようになりました。バイナリが削除された IMAP メッセージで、無言のまま 0 バイトのファイルが書き込まれることはなくなりました(#66)- SQLite の高速パスの失敗を stderr に記録するようになりました(
SQLite ... fast path failed for rowId=...; falling through to AppleScript)(#69)
v2.7.0 (2026-05-04) — Mail.app の競合状態を緩和
- 高速な IPC によって Mail.app が添付ファイルを黙って破棄する問題を緩和するため、複数の添付ファイルを処理する AppleScript に、各処理の間に 0.3 秒、最後に 0.5 秒の遅延を設けました(#60)
v2.6.0 (2026-05-03) — セキュリティと検証の強化(8 件の PR、16 件の issue)
forward_emailのプレーンモードで、RFC 3676 に準拠した>付きの元のメッセージを埋め込むようになりました(reply_emailの #43 の修正と同等)(#44)- ツールのパラメーター型が一致しない場合は、必ずエラーにするようになりました。
bool/[String]が暗黙に型変換されることはありません(#35) - 宛先メールアドレスの検証で、ヘッダーインジェクション(制御文字、
@の欠落または複数指定)を拒否するようになりました(#41) cc_additionalの重複を大文字小文字を区別せずに除去します(#34)- 添付ファイルのパスを拒否リスト(
~/.ssh、Keychains、TCC データベース、ブラウザーの Cookie)で制限し、シンボリックリンクの解決に対応しました。また、新たにMAIL_MCP_ATTACHMENT_ROOTS環境変数による許可リストを追加しました(#38) - ID を受け取る 17 個すべてのツールで、ハンドラーの境界で
idが Int であることを厳密に検証し、AppleScript の述語インジェクションを防ぎます(#50) reply_emailの実行時に対する、条件付きの統合テストを追加しました(#37、#45)。スモークテスト用のマトリックステンプレートも追加しました(#46、#47)
v2.5.0 (2026-04-17) — メール作成の format パラメーター
- メール作成ツール 4 種(
compose_email/create_draft/reply_email/forward_email)に、format: "plain" | "markdown" | "html"パラメーターを追加しました(#14、#15 を解決) - 新しい
message-composition機能仕様を追加しました
全54件のツール
アカウント(2)
| ツール | 説明 |
|---|---|
list_accounts | すべてのメールアカウントを一覧表示 |
get_account_info | アカウントの詳細を取得 |
メールボックス(4)
| ツール | 説明 |
|---|---|
list_mailboxes | すべてのメールボックス(フォルダー)を一覧表示 |
create_mailbox | 新しいメールボックスを作成 |
delete_mailbox | メールボックスを削除 |
get_special_mailboxes | 特殊なメールボックス名(受信、下書き、送信済み、ゴミ箱、迷惑メール、送信トレイ)を取得 |
メール(7)
| ツール | 説明 |
|---|---|
list_emails | メールボックス内のメールを一覧表示 |
get_email | メールの全文を取得 |
search_emails | 件名/本文で検索 |
get_unread_count | 未読件数を取得 |
get_email_headers | すべてのメールヘッダーを取得 |
get_email_source | メールの生データを取得 |
get_email_metadata | メタデータ(転送、返信、サイズ)を取得 |
操作(8)
| ツール | 説明 |
|---|---|
mark_read | 既読/未読にする |
flag_email | メールにフラグを付ける/外す |
set_flag_color | フラグの色を設定(7色) |
set_background_color | メールの背景色を設定 |
mark_as_junk | 迷惑メール/迷惑メールでないものとしてマーク |
move_email | 別のメールボックスに移動 |
copy_email | 別のメールボックスにコピー |
delete_email | メールを削除(ゴミ箱へ) |
作成(5)
| ツール | 説明 |
|---|---|
compose_email | 新しいメールを送信(cc/bcc/添付ファイルに対応 — アドレスのみ指定可能:いずれかの宛先リストに表示名付きの宛先がある場合、送信は拒否されます。create_draft を使用してください(#404);format は #304 以降、plain のみ;複数アカウントの送信元選択には任意の from_address を指定できます — #131 を参照。検証済みの差出人ポップアップを使うクリーンな方法に対応しています(#219)。本文は常に Mail 独自のエディターから入力されます — #175/check_accessibility を参照;正常に実行できない呼び出しは理由を明示して失敗し、何も作成されません(#304) |
reply_email | メールに返信。任意項目:cc_additional、attachments、save_as_draft、format(v2.4.0 以降)。プレーンモードでは、RFC 3676 の > で元のメールを引用します(v2.5.0/#43 以降)。新しい本文は Mail の標準返信機能に貼り付けられます(#218);plain 以外の format が指定された場合、またはアクセシビリティの許可がない場合は、フォールバックせずに失敗します(#304) |
forward_email | メールを転送。任意項目:body と format。プレーンモードでは、RFC 3676 の > で元のメールを引用します(v2.5.0 以降/#44)。本文のない転送では何も割り当てず、アクセシビリティの許可も不要です。本文がある場合は reply_email と同じルールが適用されます(#218/#304) |
redirect_email | メールをリダイレクト(元の送信者を保持) |
open_mailto | mailto URL を開く |
下書きとして返信する例(v2.4.0 以降)
スレッドに返信し、CC を追加してファイルを添付し、送信前に人が確認できるよう下書きとして保存します:
reply_email(
id="<message id from search_emails>",
mailbox="INBOX",
account_name="iCloud",
body="Reply text",
cc_additional=["[email protected]"],
attachments=["/path/to/file.pdf"],
save_as_draft=true
)
下書き(3)
| ツール | 説明 | |------|-------------| | `list_drafts` | 下書きメールを一覧表示します。各エントリには `subject` と数値の `id` が含まれます([#276](https://github.com/PsychQuant/che-apple-mail-mcp/issues/276)、追加機能。`update_draft.draft_id`/`delete_email.id` に使用します) | | `create_draft` | 下書きを作成します(添付ファイルに対応。複数アカウントから送信者を選択する場合は、任意で `from_address` を指定できます。[#131](https://github.com/PsychQuant/che-apple-mail-mcp/issues/131) を参照してください。検証済みの差出人ポップアップを使ったクリーンなパスに対応しています。[#219](https://github.com/PsychQuant/che-apple-mail-mcp/issues/219))。本文には Mail 独自のエディターを使用します。[#175](https://github.com/PsychQuant/che-apple-mail-mcp/issues/175)/`check_accessibility` を参照してください。ただし、オプトインの直接書き込み(`CHE_MAIL_EXPERIMENTAL_DIRECT_DRAFT=1`、[#472](https://github.com/PsychQuant/che-apple-mail-mcp/issues/472))は例外です。詳細は以下の「アクセシビリティ」を参照してください。クリーンに実行できない場合、理由を明示して失敗し、何も作成しません([#304](https://github.com/PsychQuant/che-apple-mail-mcp/issues/304))。`to`/`cc`/`bcc` に指定した表示名付き宛先(`Name `)は、作成ウィンドウの AX 指定フィールドから入力し、保存前にトークンを読み戻して確認します。非表示の Bcc フィールドは表示して、そのまま表示状態にします(`bcc_field_revealed: true`)。保存後に cc/bcc アドレスを再読み込みし(`recipients_verified: true|false` と `recipients_diff`)、下書きは常に保持されます — [#277](https://github.com/PsychQuant/che-apple-mail-mcp/issues/277)/[#404](https://github.com/PsychQuant/che-apple-mail-mcp/issues/404) | | `update_draft` | 既存の下書きを置き換えます(アップサート、[#276](https://github.com/PsychQuant/che-apple-mail-mcp/issues/276))。`draft_id` または完全一致の `subject_match` で検索 → 置き換え用の下書きを作成(`create_draft` の適格性と開示要件を継承)→ 古い下書きを削除します。意図的に「作成してから削除」する方式を採用し、作成後の受領確認を行います(失敗時は常に下書きの保持を優先します。最悪の場合、両方が存在する可能性はありますが、どちらも存在しない状態にはなりません)。一致が 0 件または 2 件以上の場合は必ず処理を拒否し、候補を一覧表示します。置き換え後の下書きには新しい ID が割り当てられます。`create_draft` と同様に、表示名付きの `to`/`cc`/`bcc` に対応しています([#404](https://github.com/PsychQuant/che-apple-mail-mcp/issues/404)) |添付ファイル(2)
| ツール | 説明 |
|---|---|
list_attachments | メールの添付ファイルを一覧表示します |
save_attachment | 添付ファイルをディスクに保存します |
VIP(1)
| ツール | 説明 |
|---|---|
list_vip_senders | VIP 送信者を一覧表示します |
ルール(5)
| ツール | 説明 |
|---|---|
list_rules | メールルールを一覧表示します |
get_rule_details | ルールの詳細を取得します |
create_rule | 新しいルールを作成します |
delete_rule | ルールを削除します |
enable_rule | ルールを有効化/無効化します |
署名(2)
| ツール | 説明 |
|---|---|
list_signatures | メール署名を一覧表示します |
get_signature | 署名の内容を取得します |
SMTP(1)
| ツール | 説明 |
|---|---|
list_smtp_servers | SMTP サーバーを一覧表示します |
同期(2)
| ツール | 説明 |
|---|---|
check_for_new_mail | 新着メールを確認します |
synchronize_account | IMAP アカウントを同期します |
一括処理(4)
| ツール | 説明 | |------|-------------| | `get_emails_batch` | 1 回の呼び出しで最大 50 件のメールを取得します(項目ごとのエラーに対応) | | `list_attachments_batch` | 最大 50 件のメールの添付ファイルを一覧表示します | | `batch_export_emails_markdown` | サーバー側で一括エクスポートし、元の内容をそのまま保持した Markdown と添付ファイルを出力します(フロントマターのマニフェストは固定。`output_dir` ごとに同時実行を直列化します — [#193](https://github.com/PsychQuant/che-apple-mail-mcp/issues/193) / [#236](https://github.com/PsychQuant/che-apple-mail-mcp/issues/236)) | | `export_emails_markdown` | **非推奨** — `batch_export_emails_markdown` に名称変更されました([#233](https://github.com/PsychQuant/che-apple-mail-mcp/issues/233))。エイリアスは v3.0 以降に削除予定です |ユーティリティ(4)
| ツール | 説明 |
|---|---|
extract_name_from_address | メールアドレスから名前を抽出します |
extract_address | フルアドレスからメールアドレスを抽出します |
get_mail_app_info | Mail.app の情報を取得します |
import_mailbox | ファイルからメールボックスをインポートします |
診断(4)
| ツール | 説明 |
|---|---|
check_fda | フルディスクアクセスの状態を確認します(SQLite の高速パスが利用可能かどうか) |
check_accessibility | アクセシビリティ権限を確認します(作成/返信の GUI 経路で必要です。権限がない場合、これらのツールは処理を拒否します。ただし、オプトインの直接書き込み create_draft 経路では代わりにフルディスクアクセスが必要です) |
check_automation | オートメーション権限(Mail への Apple Events)を確認します — プロンプトを表示しないチェックで、修復方法を含む 4 つの状態を返します(#293)。バイナリは独自の権限付与を保持します。osascript が動作しても、バイナリが認証されているとは限りません(#288) |
get_mail_log_events | Mail 独自の統合ログを読み取り、イベントチェーンがどこで停止したかを確認します(例:下書き保存 → キュー登録 → エンジンへの通知 → IMAP APPENDUID の受領)。読み取り専用です(#465)。detail=brief(デフォルト)では静的なイベントテンプレート、整数引数、[account - mailbox] 行のアカウントを示す文字のみを返します。テンプレートがコンパイル時の文字列(Mail 独自のテンプレートなど)である限り、アカウント名、件名、Message-ID は含まれません。detail=detailed では生のメッセージも追加されますが、アカウント識別子と受信メールの内容が含まれます。公開の課題に貼り付けないでください。検索期間は最大 60 分で、時刻には UTC オフセットが必要です。since=next_start、offset=next_offset と同じ until を指定してページングします。イベント名によるフィルターにはまだ対応していません(#466)。結果が空でも、アクションが実行されなかったことを意味するわけではありません。macOS 27.2/Mail 16.0 でのみ検証済みです。管理者グループのユーザーが必要です |
両方のツールはエンベロープオブジェクト{ results, returned, limit, truncated }を返します。配列そのものではありません(v2.14.0、#204で変更)。一致した項目は.resultsから読み取ってください。
| フィールド | 意味 |
|---|---|
results | 結果オブジェクトの配列(各オブジェクトのフィールドはエンベロープ形式導入前から変更されていません)。search_emailsのオブジェクトには、id、subject、sender、date_received、account_name、mailbox、toが含まれ、アカウントUUIDを解決できる場合はaccount_idも含まれます。list_emailsのオブジェクトには、id、subject、senderが含まれます。 |
returned | results内のオブジェクト数 |
limit | クエリに適用された実効limit |
truncated | 返された件数よりも多くの結果がある場合はtrueになります。残りを取得するには、limitを増やすか、クエリの範囲を絞ってください(SQLite高速パスでは確定的な値です。AppleScriptフォールバックでは後述のとおり、ベストエフォートの推定値です)。 |
truncatedはSQLite高速パスでは確定的な値です(内部でlimit + 1件を取得します)。AppleScriptフォールバックでは、returned == limitに基づくベストエフォートの推定値です。「列挙→バッチ処理」を行うコンシューマーは、全件を取得できたと判断する前にtruncatedを確認してください。
インストール
クイックスタートから始めてください — プラグインのインストールがサポート対象の方法です。コマンド、安全ルール、古さを検出するフック、署名済みバイナリを利用できます。以下はすべて上級者向け/開発者向けの手順です。MCP サーバーのみを登録する、機能が大幅に少ないインストール方法です(実行時に不足している機能を知らせるものはありません。欠けている内容についてはプラグインとMCPのみの比較を参照してください)。
Claude Desktopバンドルのバージョンメタデータ
scripts/package-mcpb.shで新しくビルドされる.mcpbバンドルには、実行ファイルと同じ場所にserver/.CheAppleMailMCP.versionが含まれます(#312)。パッケージャーはコピーしたバイナリの--versionを照会し、マニフェストのバージョンと一致することを確認してから、ZIP化の前にサイドカーファイルを書き込みます。照会に失敗した場合、応答が不正な場合、またはタイムアウトした場合は、パッケージの作成を中止します。実行中のサーバーが初回使用時にこのファイルを作成することはありません。開発用と署名付きリリース用のどちらの手順でも、この共通パッケージャーを使用します。
これにより、新しいバンドルが実行中の実行ファイルの場所にあるファイルを置き換えた一方で、古いイメージが実行中のままの場合に、既存の古さ診断機能が使えるようになります。警告はMCP サーバーのstderrログに出力され、ホストの再起動を促します。GitHubで新しいリリースを確認したり、変更されていない古いインストールを更新したり、別のディレクトリにインストールされた新しいバンドルを検出したりする機能はありません。Desktopの更新/再起動のライフサイクルは、ここでは検証されていません。バージョンが一致していれば、警告は出ません。サイドカーファイルを含まない古いバンドルでこの機能を利用するには、更新が必要です。
配布にはmake release-signed VERSION=vX.Y.Zを使用してください。
scripts/build-mcpb.shは、明示的に署名なしの開発用ビルドとして引き続き使用できます。
必要条件
- macOS 13.0+
- Xcode Command Line Tools(以下の自分でビルドする手順を使う場合)
- 少なくとも1つのアカウントが設定されたApple Mail
手順1:ビルド
git clone https://github.com/PsychQuant/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release
手順2:設定
Claude Desktopの場合
~/Library/Application Support/Claude/claude_desktop_config.jsonを編集してください。
{
"mcpServers": {
"che-apple-mail-mcp": {
"command": "/full/path/to/che-apple-mail-mcp/.build/release/CheAppleMailMCP"
}
}
}
Claude Code(CLI)の場合
# Copy to ~/bin and register (user scope = available in all projects)
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP
手順3:権限を付与
最も簡単なのはセットアップウィンドウを使う方法です。フルディスクアクセス/オートメーション/アクセシビリティの状態がリアルタイムで表示され、権限の付与に応じて再確認されるほか、適切な「システム設定」パネルを開けます。
~/bin/CheAppleMailMCP --setup
手動で設定する場合:
オートメーション(Mail.appを制御する権限):
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
- CheAppleMailMCPを見つけ、Mail.appへの権限を有効にします
- Claude Codeを使用する場合は、TerminalまたはiTermも追加します
フルディスクアクセス(SQLite高速パスとexport_emails_markdownは~/Library/Mailを読み取ります):
open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"
macOS はフルディスクアクセスをバイナリ自体ではなく、責任プロセス、つまりこのサーバーを起動したアプリに付与します。ターミナル内で Claude Code が実行する MCP サーバーの場合、責任プロセスはターミナル(Ghostty/Terminal/iTerm)です。そのため、ここにお使いのターミナルアプリを追加して、有効にしてください。ターミナルに一度許可を付与すれば、そのターミナルが起動するすべての MCP サーバーが対象になります。(バイナリを直接実行する場合、または Claude Desktop バンドルを使う場合は、そのバイナリ(~/bin/CheAppleMailMCP)を追加してください。この場合はバイナリ自体が責任プロセスになります。)FDA による拒否エラーメッセージには候補が表示されますが、macOS にはプロセス内で正確なアプリを特定する信頼できる API がないため、対象となるアプリが自動的に特定されるわけではありません(#214)。フルディスクアクセスがない場合、読み取りツールは警告なく低速な AppleScript 経由の処理に切り替わり、SQLite のみを使用する機能(projection、export_emails_markdown)は失敗します。直接起動する場合、Developer ID 署名済みのビルドを使えば、バージョン更新後も許可が維持されます。署名と公証をご覧ください。
ガイド付きセットアップ(#213) — 上記の手動手順に代わり、バイナリにはセットアップ用のヘルパーが含まれています。
CheAppleMailMCP --setupは小さなウィンドウを開き、フルディスクアクセスの状態をリアルタイムで表示します(タイマーで再確認し、許可を付与した瞬間に「Ready ✅」に切り替わります)。また、必要に応じて実行するオートメーションの確認機能と、「フルディスクアクセスの設定を開く」/「バイナリのパスをコピー」ボタンも備えています。CheAppleMailMCP --check-fdaはステータスをヘッドレスで表示し(アクセスが拒否されている場合は設定パネルを開きます)、ターミナルやスクリプトから使うのに便利です。check_fdaMCP ツールは同じステータスを Claude に報告します(SQLite のみを使用する機能でエラーが発生した際に呼び出してください)。
いずれも、手動で切り替える必要のある唯一の設定は変更できません(Apple はフルディスクアクセスを、アクセシビリティ/画面収録と同様に手動設定のみの項目として扱っています)。ただし、「どうすればよいか」がすぐに分かり、設定を有効にした瞬間にリアルタイムで状況を確認できます。
アクセシビリティ(作成、#175/#304) — Full Disk Access とは別の許可で、GUI による作成経路に必要です。Mail.app は、AppleScript で挿入された送信メッセージの本文をすべて <blockquote type="cite"> で囲みます。これを一部のモバイルクライアントは自分の文章の引用として表示しますが、ラッパーのインラインスタイルに境界線がないため、送信者はローカルでは確認できません。#304 により、これを生成するコードはすでに存在しません。すべての作成ツールは Mail 自身のエディターから本文を取得します。compose_email / create_draft では mailto: に引き渡し、reply_email / forward_email ではネイティブの返信/転送コマンドと貼り付けを使います。保存/送信/添付はキーボードショートカットで実行するため、アクセシビリティ(システム設定 → プライバシーとセキュリティ → アクセシビリティ)が必要です。FDA と同じプロセス(お使いのターミナル/Claude Desktop)に許可を付与してください。check_accessibility MCP ツールと --setup ウィンドウのアクセシビリティ行でステータスを確認できます。許可がない場合、これらのツールはフォールバックせず失敗します(本文なしの forward_email は何も書き込まず、許可も必要ありません)。以前フォールバック先だったレガシー経路は削除されているため、正常に実行できない呼び出しは、名前付きエラーを返し、何も作成しません。エラーは open_mailto を案内します。これは TCC の許可がまったく不要です(添付ファイルは扱えません。ウィンドウはご自身で保存または送信してください)。呼び出しが拒否される条件は、次のちょうど 6 つです。plain 以外の format、空の件名、アクセシビリティの許可がないこと、裸の addr-spec ではない from_address、ASCII 以外の文字を含む添付ファイルのパス(#220)、およびこの経路では入力できない表示名付きの宛先(cc/bcc は常に該当し、送信時の to も該当します。下書きの to の表示名は GUI 経由で入力されます(#277))。デフォルト以外のアカウントから本文をきれいに作成するには、from_address を指定してください。GUI が Mail の差出人ポップアップでアカウントを選択し、選択内容を読み返して、誤った差出人になるリスクがあれば中止します(#219)。レガシー経路とともに削除されたもの:format: "markdown" / "html" — 現在提供されている経路に、削除された本文割り当てなしでリッチテキストを配信できるものはありません。これは現状について述べているのであり、不可能だと証明するものではありません(#310)。貼り付け経路(#218)はラッパーのない別の経路であり、NSPasteboard ではリッチ形式を扱えますが、生成される MIME は未検証です。#306 で決着します。#308 / #309 は代替案であり、require_wrapper_free と sanitize_links パラメーター、および回避用の CHE_MAIL_DISABLE_MAILTO_COMPOSE / CHE_MAIL_DISABLE_PASTE_REPLY もあります。これらに伴う 2 つの機能上の制約も明記しておきます。表示されるウィンドウなしで作成すること(回避策が当初目的としていた機能)はできなくなり、compose_email では Name <addr> 宛てに送信できなくなりました。create_draft を使い、下書きをご自身で送信してください。
例外は 1 つだけで、オプトインの実験的機能です:CHE_MAIL_EXPERIMENTAL_DIRECT_DRAFT=1 を設定すると、直接書き込み経路のすべての条件(message-composition 仕様の 2 つの閉じたリスト、Requirement: Direct-write draft path)を満たす create_draft 呼び出しは、下書きを Mail のストアに直接書き込みます(#472 / #475)。この経路ではウィンドウを開かず、アクセシビリティも必要ありません。Full Disk Access と Automation は必要です。条件を満たさない呼び出しは、上記の GUI 経路を使い、そこで述べたすべての制約が適用されます。
Automation TCC(-1743)とゼロ TCC の回避策
AppleScript を使用するツールが AppleScript error (-1743): Not authorized to send Apple events to Mail で失敗する場合、このバイナリに対する Automation 権限がありません。署名済みの MCP バイナリは、独自の Automation 権限を保持します。その TCC ID は、バイナリの署名 ID(#211 の FDA に関する教訓、Automation の側面)にひも付けられており、ターミナルのものとは別です。実証済みの事実として、シェルから osascript で Mail を操作できても、バイナリに権限があることを意味しません。システム設定 → プライバシーとセキュリティ →
Automation で権限を付与します。バイナリまたはそのホストの項目を探し(Claude Desktop 拡張機能の場合は Claude.app の下)、Mail を有効にしてください。項目がない場合は、以前の拒否が記憶されており、macOS が再度確認を求めない状態です。tccutil reset AppleEvents を実行してから、Mail ツールを再試行し、確認を再表示させてください。権限はインストールごとに設定され、バイナリの更新によって項目が無効になることがあります(#211)。
権限が付与されるまでは、open_mailto は引き続き動作します。LaunchServices(ゼロ TCC、#287)経由で、引用ブロックのない作成ウィンドウをシステムの既定メールクライアントで開きます。mailto には添付ファイルを含められないため(RFC 6068)、手動でファイルをドラッグして追加してください。
ステップ 4:Claude を再起動する
# For Claude Desktop
osascript -e 'quit app "Claude"' && sleep 2 && open -a "Claude"
# For Claude Code - start a new session
claude
使用例
自然言語(Claude Desktop)
"List all my mail accounts"
"Show unread emails in Gmail inbox"
"Search for emails about 'quarterly report'"
"Send an email to [email protected] about the meeting"
"Flag important emails in red"
"Create a rule to move newsletters to a folder"
ツールの直接呼び出し(Claude Code)
"Use list_accounts to show my accounts"
"Use search_emails to find emails containing 'invoice'"
"Use set_flag_color to mark email ID 12345 as blue"
"Use check_for_new_mail to refresh"
フラグと背景の色
フラグの色(set_flag_color)
| インデックス | 色 |
|---|---|
| 0 | 赤 |
| 1 | オレンジ |
| 2 | 黄 |
| 3 | 緑 |
| 4 | 青 |
| 5 | 紫 |
| 6 | グレー |
| -1 | クリア |
背景の色(set_background_color)
blue、gray、green、none、orange、purple、red、yellow
パフォーマンスとストレージ
SQLite + .emlx の高速パス
ほとんどの読み取りツールは、AppleScript IPC よりも Apple Mail のローカル Envelope Index(SQLite)とディスク上の .emlx メッセージファイルを優先し、SQLite パスで要求を満たせない場合は AppleScript に透過的にフォールバックします。
| ツール | SQLite/.emlx パス | AppleScript フォールバック |
|---|---|---|
get_email | ✓ | エラー時に ✓ |
get_emails_batch | ✓(項目ごと) | ✓(項目ごと) |
get_email_headers | ✓ | エラー時に ✓ |
get_email_source | ✓ | エラー時に ✓ |
search_emails | ✓ | リーダーを利用できない場合に ✓ |
list_attachments | ✓ | エラー時に ✓ |
save_attachment | ✓ | エラー時に ✓ |
get_email_metadata | ✓ | エラー時に ✓(#71 以降) |
get_mail_log_events は意図的にこの表の対象外です。Envelope Index(状態)ではなく、/usr/bin/log を使って Mail の統合ログ(イベント:何がいつ起きたか)を読み取ります。フルディスクアクセスは不要ですが、ユーザーが管理者グループに属している必要があります。また、メッセージが存在するかどうかの根拠として使うことはできません。詳しくは .claude/rules/r-must-direct-db.md を参照してください。
save_attachment の読み取りパスでは、高速パスは AppleScript より10~100 倍高速です(#12 の測定値)。その他のツールの速度向上率はリクエストの形によって異なりますが、一般に、大量のデータを一括で読み取る場合に最も大きな効果が得られます。
高速パスには次の条件が必要です。
- ホストプロセスにフルディスクアクセスが付与されていること(システム設定 → プライバシーとセキュリティ → フルディスクアクセス)
- Apple Mail のローカルストアが
~/Library/Mail/V10/...にあること - メッセージがローカルの
.emlxストレージに同期されていること
EWS / Exchange アカウントでは意図的に高速パスを迂回します
Apple Mail の Exchange(EWS)アカウントでは .emlx ファイルは生成されません。メッセージ本文はサーバー上にあり、必要に応じて取得されます。これらのアカウントでは、get_email_metadata を含むすべての読み取りツール 8 種(#71 以降)は、透過的に AppleScript IPC にフォールバックします(正しい動作ですが、時間がかかります)。次のような症状があります。
- EWS メッセージ 500 件を一括取得すると、IMAP/Gmail メッセージ 500 件の場合より明らかに遅くなります
- これは バグではありません。Apple Mail のストレージアーキテクチャ上の制約です(#9 を参照)
高速パスの迂回を診断する
EWS 以外のアカウントで高速パスが失敗すると、#69 以降、失敗が stderr に記録されます。バイナリをターミナルで実行し、stderr を確認して次のように判別します。
EnvelopeIndexReader init failed: ...— DB にアクセスできません(よくある原因:フルディスクアクセスが許可されていない)SQLite get_email fast path failed for rowId=N: ...— メッセージ単位の失敗です(例:.partial.emlxしかない、MIME 形式が不正、ファイルがまだ同期されていない)
どちらの場合もログ行に ... falling through to AppleScript と記録され、透過的に AppleScript にフォールバックするため、動作は維持され、可観測性も回復します。
トラブルシューティング
| 問題 | 解決方法 |
|---|---|
| サーバーが切断される | swift build -c release で再ビルドしてください |
| Apple イベントの送信が許可されていない | システム設定 > オートメーションでアクセス権を追加してください |
| Mail.app が応答しない | Mail.app が起動しており、アカウントが設定されていることを確認してください |
| コマンドがタイムアウトする | メールボックスが大きいと時間がかかります。検索条件を絞ってお試しください |
| 一括取得が予想より遅い | stderr で ... falling through to AppleScript の行を確認してください。EWS/Exchange アカウントは常にフォールバックします(パフォーマンスとストレージを参照)。その他のアカウントでフォールバックが記録される場合は、修正可能な .emlx の問題があることを示しています |
save_attachment が -1728 "Can't get account" または -1719 "Invalid mailbox index" で失敗する | #173 以降、どちらのエラーにも、失敗した参照先(アカウント/メールボックス/メッセージ)を示す対処可能なヒントが付いて返されます。よくある原因:2 つの Mail.app アカウントで同じ display_name が使われている、またはメールアドレス形式の account_name が複数のアカウントに対応している。以下のアカウントの識別を参照してください。 |
アカウントの識別
2 つのアカウントで同じ display_name が使われている場合、Mail.app の AppleScript セレクター account "<display_name>" は 一意ではありません。これは、iCloud のキャッチオールエイリアスが Gmail アドレスを自身に転送する場合や、Google Workspace と個人用 Gmail が重複する場合によく見られるパターンです。その場合、AppleScript 経由のツール(save_attachment のフォールバック、get_email、mark_read など)は、非決定的に誤ったアカウントを選択し、-1728 / -1719 エラーが発生します。
解決方法:Mail.app 全体で一意な UUID である account_id を account_name と併せて渡します。これが指定されると、save_attachment は代わりに Mail.app の account id "<UUID>" セレクターを使用し、曖昧さを回避します。
// Tool call: save_attachment with account_id
{
"id": "273214",
"mailbox": "[Gmail]/全部郵件",
"account_name": "[email protected]",
"account_id": "C38E0583-47F8-4468-BE70-43155C15549D", // ← disambiguates
"attachment_name": "report.pdf",
"save_path": "/tmp/report.pdf"
}
account_id の確認方法:
search_emailsの結果から —results配列内の各オブジェクト(SearchResult)には、account_nameとともにaccount_idフィールドが含まれています(MailboxURL.decodeを通じて、SQLite のmailboxes.urlの authority からアカウント UUID をデコードして設定されます。Mail.app のストレージ規約では、メールボックス URL の authority にアカウント UUID がエンコードされています。SELECT mailboxes.account_idで直接取得することはできません)。推奨方法:そのまま渡してください。- 手動で確認する —
~/Library/Mail/V10/MailData/Signatures/AccountsMap.plistを読み取ります。トップレベルのキーが UUID で、AccountURL値には一致するメールアドレスが authority 内にパーセントエンコードされて格納されています。 - AppleScript で確認する —
tell application "Mail" to get id of every accountは UUID の一覧を返します。 後方互換性:account_idは任意です。省略した場合(または空の場合)、ツールは従来のaccount "<display_name>"パスにフォールバックします。これは #101 以前と同じ動作ですが、save_attachmentは例外です(#173)。account_nameに@が含まれる場合(search_emailsなどの SQLite パスのツールが出力する、メールアドレス形式の場合)、save_attachmentはまず AccountsMap から逆引きし、account id "<UUID>"セレクターに自動的に切り替えます(切り替えは stderr に記録されます)。一致が 1 件の場合はその UUID を使用します。1 つのアドレスに複数のアカウントが紐づいている場合(iCloud のキャッチオールと Gmail など)は、生の-1728ではなく、該当するすべての候補を列挙した対処可能なエラーを返します。一致しない場合は従来の表示名パスを変更せずに使用します。注意点:説明に正当に@が含まれ、その説明が別のアカウントのメールアドレスと一致する Mail アカウントは、メールアドレスの名前空間で先に解決されます。セレクターを固定するには、account_idを明示的に渡してください。他のツールは、#101 以前と同じ厳密なフォールバックを維持します(全ツールへの適用は #176)。
適用範囲:account_id は、アカウントを指定してメールを参照する AppleScript 経由のツール全体で受け付けられます。最初に対応したのは save_attachment です(#101)。続いて #104 の一斉対応で、以下の単一メッセージ/移動/中継/メールボックス関連の 13 個のツールにも追加されました。
save_attachment(#101) — 先行して対応- PR-A — 単一メッセージを変更する 5 個のツール:
mark_read、flag_email、set_flag_color、set_background_color、mark_as_junk - PR-B — 移動/削除を行う 3 個のツール:
move_email、copy_email、delete_email - PR-C — メッセージを中継する 3 個のツール:
reply_email、forward_email、redirect_email - PR-D — メールボックスの CRUD を行う 2 個のツール:
create_mailbox、delete_mailbox
その後、対応範囲は #104 の対象を超えて拡大しています。
- #176 — メールアドレスから UUID への変換を行う
resolveAccountIdForToolの要所を、AppleScript 経由の書き込みハンドラー 14 個すべてに共通化しました。これにより、メールアドレス形式のaccount_nameはaccount_idを受け付けるだけでなく、UUID セレクターに解決されます。 - #180 —
resolveMailboxRef/resolveMsgRefを使い、読み取りツールの AppleScript フォールバック(list_emails/search_emails/get_email/ヘッダー/ソース/メタデータ/添付ファイル/get_unread_count)にaccount_idを通しました。以前は延期されていた PR-E が完了しました。 - #179 —
get_special_mailboxesが、アカウントごとの特殊メールボックスの実名を取得するためのaccount_id/account_nameを受け付けるようになりました。 - #191 — アカウントレベルのアクションツール
check_for_new_mailとsynchronize_accountにaccount_idのエスケープハッチを追加しました(synchronize_accountはaccount_idのみでも受け付けます)。
account_id による対応がまだ行われていないもの(追跡中):get_account_info/list_mailboxes(#202)。
compose_email/create_draft では表示名の衝突による不具合は発生しません。既存のメールをアカウントで参照するのではなく、make new outgoing message を実行するため、account "<display_name>" セレクターを出力することがありません。任意の from_address パラメーターを使って、複数アカウントから送信元を選択できるようになりました(#131)。設定済みの Mail.app のメールアドレス("[email protected]" または RFC 5322 形式の "Alice <[email protected]>")を渡すと、送信メッセージの sender が設定されます。省略すると、Mail.app のデフォルトアカウントが使われます。実行中の Mac に設定されているアドレスを確認するには、list_accounts を使ってください。
account_id ではアカウント間の移動/コピーはサポートされていません(#129 — #127 からの検証)。move_email と copy_email が受け取る account_id は1つで、コピー元の msgRef とコピー先の mailboxRef の両方に渡されます。この設計上の選択は適切です(Mail.app の AppleScript 動詞 move msg to <mailboxRef> では、コピー先のメールボックスを1つのアカウントコンテキスト内で指定する必要があるため、移動は同じアカウント内に限定されます)。Mail.app の UI ではドラッグ&ドロップでアカウント間の移動ができますが、AppleScript 経由の move_email / copy_email ツールでは再現できません。あるアカウントの account_id を指定して move_email を呼び出し、コピー先の to_mailbox が別のアカウントに対して解決されることを想定すると、両方のアカウントに同名のメールボックスがある場合は、誤ったアカウントのメールボックスが黙って選ばれ、そうでない場合は -1719 "Invalid mailbox index" が発生します。別のアカウントにメッセージの内容をコピーする必要がある場合は、save_attachment と compose_email を使って手動で再構成できます。ただし、これは本当の移動/コピーではありません。元のメタデータ(Message-ID、受信日時、フラグ、ラベル)とメッセージの識別情報は保持されません。
開発テスト
macOS 上で Xcode Command Line Tools、Python 3、jq が PATH に含まれた状態で make test を実行します。このコマンドは Swift テストスイートに続いてプラグインテストスイートを実行し、いずれかが失敗すると失敗を返します。make test-plugin は、反復を速めるためプラグインテストスイートのみを実行します。
プラグインランナーは plugin/tests/test-*.sh と test-*.py を検出し、必要なフックテストスイートが存在することを確認します。依存関係が不足している場合は、明確なエラーを返します。一致する各ファイルは、単独で実行できる Bash または Python のテストスイートである必要があります。共有ヘルパーは、別の名前またはサブディレクトリに配置してください。プラグインテストでは、分離されたフィクスチャとモックプロセス/ダウンロードを使用します。
この Makefile の設定自体は、GitHub Actions ワークフローを追加しません。
技術詳細
- フレームワーク:MCP Swift SDK v0.10.0
- 読み取りパス:SQLite(Envelope Index)+
.emlxファイルパーサー。EWS または解析できない.emlxでは AppleScript にフォールバック - 書き込み/状態パス:
NSAppleScript経由の AppleScript - トランスポート:stdio
- プラットフォーム:macOS 13.0 以降(Ventura 以降)
署名と公証
配布されるバイナリはDeveloper ID 署名済みで、公証も受けています。これは単なる見せかけではありません。高速な読み取りパスにはフルディスクアクセス(FDA)が必要で、macOS の TCC は FDA の許可をバイナリの指定要件に関連付けます。アドホック署名のバイナリでは、その要件はcdhashであるため、バージョンを更新するたびに許可が無効になり、リリースのたびにバイナリをフルディスクアクセスのリストへ再登録する必要がありました。安定した Developer ID 署名では、許可は代わりに署名 IDに関連付けられるため、バージョン更新後も維持されます(#211)。この維持を実現するのは公証ではなく署名です。
公証が重要になるのは、ブラウザーからのダウンロードや .mcpb(Claude Desktop)のインストールなど、Gatekeeper が初回起動時にバイナリを評価する隔離状態での起動の経路です。プラグインのラッパーが使う curl + exec の経路では隔離属性が設定されないため、Gatekeeper は起動しません。それでも、公開リリースのアセットをどの方法で実行しても安全になるよう、公証を受けています。
最初の許可は、今でも手動で行う必要があります。 FDA(
kTCCServiceSystemPolicyAllFiles)にはプログラムから要求する API がありません。アプリからできるのは、設定パネルへのディープリンクだけです。署名により最初の許可は永続化されますが、自動で許可されるわけではありません。
メンテナー向けの初回セットアップ
# 1. Developer ID Application cert in your login keychain (needs an Apple Developer account)
security find-identity -p codesigning -v # find your identity
# 2. notarytool keychain profile (prompts for an app-specific password — never pass it on the CLI)
xcrun notarytool store-credentials <profile-name> \
--apple-id <your-apple-id> --team-id <your-team-id>
# 3. Export both for the signed targets
export DEVELOPER_ID='Developer ID Application: Your Name (TEAMID)'
export NOTARY_PROFILE='<profile-name>'
自分のマシンへの開発版インストール(高速 — 公証不要)
make install-signed # build + Developer ID sign + copy to ~/bin
Apple の公証を待たずに、自分の Mac で安定した FDA 許可を得るには、この方法を使ってください。自分の証明書ならローカルで問題なく起動でき、再ビルド後も許可が維持されます。~/bin/CheAppleMailMCP にフルディスクアクセスを一度許可すれば完了です。
配布リリース(署名・公証済み・公開)
make release-signed VERSION=vX.Y.Z # wraps scripts/release.sh with REQUIRE_CODESIGN=1
ユニバーサル(arm64 + x86_64)バイナリをビルドし、署名・公証(Appleとの往復に1~15分かかります)したうえで、GitHubリリースにアップロードします。証明書を持たないフォークでも、SKIP_CODESIGN=1 ./scripts/release.sh vX.Y.Zを使えば、署名なしの開発用リリースを作成できます。
コントリビューション
コントリビューションを歓迎します!お気軽にプルリクエストを送信してください。
ライセンス
MITライセンスです。詳細はLICENSEをご覧ください。
作者
Che Cheng(@kiki830621)が作成しました。
このプロジェクトが役に立ったら、ぜひスターを付けてください!
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。