mcpField
O
outlook-mac-mcp

outlook-mac-mcp

ローカル
github.com/valter-araujoコミュニケーション06 週間前に更新

outlook-mac-mcp について

outlook-mac-mcpは、Microsoft Graph を介して MCP クライアントを Outlook のメールボックスに接続します。個人用 Microsoft アカウントのほか、職場または学校のアカウントにも対応し、メールの読み取りと検索を提供します。カレンダー変更は設定フラグで有効化します。

主な機能

  1. 01メールの一覧表示、検索、件数取得、読み取り
  2. 02メールフォルダーの確認と送信者の集計
  3. 03今日と今後のカレンダー予定の確認
  4. 04名前の先頭一致またはメールアドレスによる連絡先検索
  5. 05有効化した場合のカレンダー変更のプレビューと適用

活用シーン

  1. 01送信者、日付、検索語によるメール検索
  2. 02未読メールやサイズの大きいメールの確認
  3. 03カレンダーの近日中の予定の確認
  4. 04適用前のカレンダー変更のプレビュー

MCP 対応

stdio の MCP サーバーとして、Microsoft Graph 経由で Outlook のメール、カレンダー、連絡先のツールを提供します。カレンダーの作成、更新、削除には設定フラグが必要です。メール送信はまだ実装されていません。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

outlook-mac-mcp

Microsoft Outlook 向けの MCP サーバーです。Exchange Online ではなくコンシューマー向けインフラストラクチャ上で動作する個人用 Microsoft アカウント(Hotmail、Outlook.com、Live)向けに構築されており、公式の「Claude for Outlook」アドインや Microsoft 365 コネクタではサポートされていません。

バックエンドには、委任されたユーザー同意済みの最小権限スコープを使用するMicrosoft Graph APIを採用しています。Python、トランスポートは stdio、テレメトリーはありません。

AppleScript を使用しない理由

Outlook for Mac 向けのコミュニティ製 MCP サーバーは、AppleScript を使ってアプリを操作します。この方法が動作するのは従来版 Outlookのみです。2026 年 8 月、Microsoft は新しい Outlook で予定していた AppleScript のサポートを中止し、新しい Outlook への移行は 2026 年 10 月に終了します。このプロジェクトは意図的に AppleScript に依存しない設計になっています。

このプロジェクトのリファレンス環境では新しい Outlookを実行しています(Outlook メニューに「従来版 Outlook」への切り替え項目があります)。この環境では AppleScript による自動化を利用できません。これが決め手となりました。

技術要件

ランタイム
コンポーネント要件備考
macOS13 Ventura 以降トークンの保存に Keychain を使用
Python3.12 以降uv で管理。依存関係は uv.lock で固定
MCP クライアント任意の stdio クライアント(Claude Desktop、Claude Code)Claude Desktop でテスト済み
ネットワークlogin.microsoftonline.com および graph.microsoft.com への HTTPS のみこれ以外の外部通信はありません
Microsoft アカウントとアプリ登録
項目要件
アカウントの種類個人用 Microsoft アカウント(Hotmail/Outlook.com/Live)または職場/学校アカウント
アプリ登録Microsoft Entra ID での一度限りの登録(無料。個人用アカウントでは専用のテナントが必要です。Azure Portal から作成できます)
サポートされるアカウントの種類「任意の組織ディレクトリ内のアカウントおよび個人用 Microsoft アカウント」
認証デバイスコードフロー(MSAL、パブリッククライアント、クライアントシークレットなし)
認証機関https://login.microsoftonline.com/consumers
デフォルトで要求されるスコープMail.Read、Calendars.Read、Contacts.Read、offline_access、User.Read
OUTLOOK_MCP_ENABLE_CALENDAR_WRITE=true で追加されるスコープCalendars.ReadWrite(オプション:カレンダーへの書き込みを参照)
管理者の同意不要です。上記のスコープはすべてユーザーが同意できます

offline_access、openid、profile は予約済みスコープです。MSAL はこれらをすべてのリクエストに自動で追加するため、明示的に渡すとエラーになります。アプリ登録時にはこれらにも同意しますが、コードが要求するスコープの一覧には表示されません。この同意により、Keychain のキャッシュに保存されるリフレッシュトークンが取得されます。

アプリ登録に、サーバーが要求するより広範なアクセス許可が含まれていてもかまいません。トークンに含まれるのは、実行中の設定が要求するスコープのみです。書き込みスコープは、デフォルトでオフになっている設定フラグが有効な場合にのみ要求され、有効にすると新たなサインインと同意のプロンプトが表示されます。

不要なもの
  • Microsoft Outlook デスクトップアプリ(サーバーはアプリではなく Graph と通信します)
  • Exchange Online/Microsoft 365 のビジネステナント
  • macOS のアクセシビリティまたはオートメーションのアクセス許可
  • Node.js、Bun、その他の Python 以外のランタイム

検証済みの環境

検証日順(古い順)に並べています。

バージョンOSPythonMCP クライアントアカウントの種類Outlook アプリのインストール状況ステータス
0.1.0macOS 27.0 (Golden Gate), Apple M53.14.7Claude Desktop個人用(@hotmail.com)Outlook for Mac 16.112.4 (26090911), 新しい Outlook, M365 サブスクリプション — サーバーでは未使用検証済み 2026-09-14
0.2.0 (カレンダーへの書き込みを有効化)macOS 27.0 (Golden Gate), Apple M53.14.7Claude Desktop個人用(@hotmail.com)上記と同じ検証済み 2026-09-15
0.9.0 (delete_event まで)macOS 27.0 (Golden Gate), Apple M53.14.7Claude Desktop個人用(@hotmail.com)上記と同じ検証済み 2026-09-17

その環境で実際のメールボックスを対象に、記載されているツールが正しい結果を返した後にのみ、行のステータスを検証済みに変更します。新しい行の追加も歓迎します。正確なバージョンを記載してください。

検証済みツール

ツール名のアルファベット順に並んでいます。リリース済みのツールが1つ、まだこの表に含まれていません。ユニットテストと respx によるカバレッジはありますが、実際のメールボックスに対するライブ検証は行われていません。

  • search_contacts — まだ検索対象となる連絡先がテスト用メールボックスにありません。
ツール検証日確認内容
count_emails2026-09-151か月分の受信日時範囲を指定し、正確な件数が返されることを確認しました。
create_event2026-09-15, 2026-09-16, 2026-09-17時刻指定の予定と終日予定を作成しました。Graph が解決済みタイムゾーンの名前を含む終日予定のペイロードを受け付け、どちらも読み取り可能な状態で返されることを確認しました。プレビューの本文が作成した予定に正しく書き込まれました。本文のない予定も問題なく作成でき、送信されていない本文を Graph が HTML として扱う問題の修正を確認しました。
delete_event2026-09-17preview_event_deletion のトークンでプレビューした予定を削除し、Outlook でカレンダーから直接削除されたことを確認しました。
get_email2026-09-14Prefer ヘッダーが尊重され、テキスト本文が返されました。不正な ID nope は ErrorInvalidIdMalformed として返され、InvalidRequestError にマッピングされました。
list_emails2026-09-15sort=oldest、limit=1 を指定すると、フォルダー内で最も古いメールと正確な合計件数が返されました。送信者を完全一致で絞り込み、sort=newest を指定すると、一致するメールが正確に1件返されました。また、Graph が送信者フィルターと $orderby の併用を InefficientFilter エラーなしで受け付けることを確認しました。
list_folders2026-09-17複数階層の入れ子を含む100以上のカスタムフォルダーが正しく検出され、各フォルダーの未読数と合計数も正確でした。文書化されている制限を実環境で確認しました。既知のフォルダーフラグがない Microsoft 管理フォルダー(Deleted Items)が、実際のユーザー作成フォルダーとともに、想定どおり custom に表示されました。
list_largest_emails2026-09-16拡張プロパティから取得した実際のサイズに基づく順位付きの結果が返され、skipped はほぼゼロでした。
list_todays_events2026-09-15予定のない日に、正確に0件の予定が返されました。
list_unread_emails2026-09-14Graph を通じて Hotmail の受信トレイを読み取ります。
list_upcoming_events2026-09-15該当する予定が最も早い順に返されました。終日予定と時刻指定の予定の両方が、解決済みタイムゾーンで正しくマッピングされることを確認しました。
preview_event2026-09-15, 2026-09-16時刻指定の予定と終日予定について、概要とトークンが返されました。省略のしきい値を大幅に下回る本文は、プレビューに全文がそのまま表示されました。
preview_event_deletion2026-09-17削除が行われる前に、取り消せない操作である旨の警告とともに、予定の全項目が省略なしで表示されました。
preview_event_update2026-09-17時刻の変更(10:00–10:30 → 11:00–11:30)に対し、変更された項目のみを旧値 → 新値の形式で示す差分の概要が生成されました。
search_emails2026-09-14, 2026-09-15, 2026-09-17複数のメールに一致する語句で検索すると、正確な合計件数が返されました。scope=subject と scope=sender は、それぞれ範囲が狭く、かつ正確な結果を返しました。フレーズから抜け出そうとする語句を検索すると、400 エラーにならず、空の結果が返されました。next_page_token を page_token として渡すと、実際に異なる2ページ目が返されました(日付範囲が異なり、1ページ目と重複する項目はありません)。そのページでも total/total_is_exact は正確でした。
top_senders2026-09-15受信トレイ全体のスキャンが設定済みの上限に達し、coverage_is_complete=false となりました。説明にあるとおり、クライアントが一部のみをカバーしていることを明示しました。
update_event2026-09-17プレビューした時刻の変更(10:00–10:30 → 11:00–11:30)が正確に適用され、更新された予定にはその変更だけが反映されました。

以下のすべてのツールは、上記の環境で実際のメールボックスに対して検証済みです。 search_contacts はユニットテストと respx によるカバレッジがありますが、まだライブ検証は行われていません(上記を参照)。

検索時の引用符の処理については、ライブの正常系チェックでも確認しています。統合テストを参照してください。

対象範囲

  • v1(読み取り専用): 未読メール、フォルダー内のメール(既知のフォルダーまたはカスタムフォルダー。フルパスで指定)、語句による検索、IDを指定したメールの取得(本文を含む)、フォルダー一覧、今日のイベント/今後のイベント、連絡先検索。
  • v2: カレンダーイベントの作成と更新 — 設定フラグで制御され、デフォルトではオフです。カレンダーイベントの削除 — 2つ目のフラグで制御され、1つ目のフラグがオンでもデフォルトではオフです。既読にする — まだ実装されていません。
  • v3: メールの送信 — 設定フラグで制御され、デフォルトではオフです。各呼び出しで明示的な確認が必要です。

ツール

読み取りツールは常に登録されます。v2, flagged と記された4つのツールは、OUTLOOK_MCP_ENABLE_CALENDAR_WRITE=true の場合にのみ登録されます(オプション:カレンダーへの書き込みを参照)。v2, flagged + calendar delete と記された preview_event_deletion と delete_event には、さらに OUTLOOK_MCP_ENABLE_CALENDAR_DELETE=true が必要です(オプション:カレンダーの削除を参照)。ツール名のアルファベット順です。

ツール機能
count_emailslist_emails と同じフィルターに一致するメールを、一覧表示せずに正確にカウントします。
create_event (v2, flagged)preview_event のトークンでプレビューしたイベントを作成します。
delete_event (v2, flagged + calendar delete)preview_event_deletion のトークンでプレビューしたイベントを削除します。取り消しできません。
get_emailIDを指定してメールを1件取得します。本文を含みます。
list_emailsフォルダー内のメールを、既読状態、送信者、日付範囲、添付ファイルの有無を任意に組み合わせたフィルターで一覧表示します。新しい順または古い順に並べ、正確な合計数も返します。
list_foldersメールボックスの既知のフォルダーについて、未読数とアイテムの合計数を一覧表示します。また、メールボックスのツリーをたどって見つかった、ユーザーが作成したすべてのフォルダーもフルパスで識別して一覧表示します。
list_largest_emailsフォルダー内のメールをサイズの大きい順に一覧表示します。1回の呼び出しで一致するメールを最大10,000件までスキャンします。サイズを特定できないメールは skipped に別途カウントされます。
list_todays_events今日のカレンダーイベントを開始時刻の早い順に一覧表示します。
list_unread_emailsフォルダー内の未読メールを新しい順に一覧表示します。
list_upcoming_events現在から1~30日先までのカレンダーイベントを一覧表示します。
preview_event (v2, flagged)新しいイベントを検証し、作成せずにトークンと概要を返します。
preview_event_deletion (v2, flagged + calendar delete)既存のイベントを取得し、何も削除せずに、すべてのフィールドを省略せずに示すトークンと概要を返します。
preview_event_update (v2, flagged)既存のイベントを取得し、指定された変更を検証して、何も適用せずにトークンと差分の概要(変更されたフィールドのみ。変更前の値 -> 変更後の値)を返します。
search_contacts表示名の先頭部分または完全一致するメールアドレスで連絡先を検索します。
search_emailsフォルダー内のメールを語句で検索し、日付順ではなく関連度順に表示します。
top_sendersフォルダー内の送信者を、送信したメールの件数順に並べます。1回の呼び出しで一致するメールを最大10,000件までスキャンします。
update_event (v2, flagged)preview_event_update のトークンでプレビューした変更を適用します。プレビューに実際に渡されたフィールドのみが変更されます。
カスタムフォルダー

カスタムフォルダーとは、Outlook でユーザーが作成したフォルダーのうち、既知の 5 つのフォルダー(受信トレイ、アーカイブ、迷惑メール、送信済みアイテム、下書き)以外のものです。search_emails、 list_emails、count_emails、top_senders、list_largest_emails、list_unread_emails は、いずれも folder 引数に次のいずれかを指定できます。

  1. 大文字と小文字を区別せずに照合される、名前で指定した既知のフォルダー — folder="inbox"、 folder="INBOX"、folder="Archive" はすべて同じフォルダーとして解決されます。
  2. all — すべての既知のフォルダーを統合します。カスタムフォルダーは、いくつ存在していても含まれません。 folder="all"。
  3. 完全なパスで指定したカスタムフォルダー。list_folders が custom の下に返すとおりのパスを指定します (メールボックス内ではフォルダー名が重複するため、完全なパスで区別します)。 folder="Entrevistas/Work/AWS"。
  4. 最上位のカスタムフォルダー。親フォルダーがないため、修飾するパスは不要です。 folder="Seguros"。

まず list_folders を実行して利用可能な正確なパスを確認し、その文字列を folder に指定してください。カスタムパスの解決には、呼び出しごとにメールボックスのフォルダーツリーをもう一度たどる必要があります(custom リストのために list_folders が行うのと同じ走査です)。呼び出し間でキャッシュされることはありません。

folder は、ツールがすでに受け付けるほかのすべてのフィルターと組み合わせて使用できます。

# Well-known folder (unchanged)
search_emails(term="Cargill", folder="archive")

# All well-known folders (unchanged — never includes custom folders)
count_emails(folder="all")

# A custom folder, addressed by its full path
list_emails(folder="Entrevistas/Work/AWS", sort="oldest")

# A top-level custom folder
top_senders(folder="Seguros")

# A custom folder combined with a date range
list_emails(
    folder="Entrevistas/Work/AWS",
    received_after="2026-01-01T00:00:00+00:00",
    sort="oldest",
)

# A custom folder combined with an exact sender filter
count_emails(folder="Entrevistas/Work/AWS", sender="[email protected]")

# A custom folder combined with a search term
search_emails(term="offer letter", folder="Entrevistas/Work/AWS")

入力ミスは拒否され、別のフォルダーに誤って振り分けられることはありません。 既知のフォルダー名に近い folder 値(1 文字または 2 文字の違いなど。例:folder="inbx")を指定すると、メールボックスツリー全体を走査して inbx という名前のカスタムフォルダーを探すのではなく、意図した可能性のある値を示すエラーが発生します("inbx" is not a recognized folder -- did you mean 'inbox'?)。

既知の制限事項: この入力ミスのチェックには、大まかな編集距離のヒューリスティックを使っており、辞書照合ではありません。そのため、既知のフォルダー名と 1 文字だけ異なる名前を持つ実在のカスタムフォルダー(たとえば、文字どおり Archives という名前のフォルダー)は、archive の入力ミスと区別できず、同じように拒否されます。現時点での回避策は、フォルダー名を変更することだけです。

セキュリティモデル

  • 最小権限:トークンが実行できるのは、要求されたスコープで許可された操作だけです。サーバープロセスが侵害された場合も同様です。
  • トークンは macOS Keychain に保存され、ファイルや環境変数には保存されません。
  • メールの内容は信頼できない入力として扱います。サーバーはメッセージ本文内の指示に従って動作することはありません。
  • 構造化 JSON ログは stderr に出力されます(stdout は MCP のトランスポートです)。ログに含まれるのはメタデータと件数のみで、件名、本文、アドレス、連絡先名は含まれません。

アーキテクチャ

domain/           entities and rules — no Graph, no MCP
application/      use cases depending on ports (interfaces)
infrastructure/   Graph API adapter — the only place that knows Microsoft
interface/mcp/    tool registration and input/output translation only

依存関係は内側に向かっています。バックエンドを交換する場合、変更が必要なのは infrastructure/ だけです。

アーキテクチャの概要

依存関係は内側に向かっています。Graph アダプターがほとんどのポートを実装します。唯一の例外は Clock で、SystemClock が実装しています。SystemClock は Microsoft と通信しないため、infrastructure/graph の外に配置されています。domain/ と application/ のいずれも、これらをインポートしません。

flowchart TB
    subgraph interface["interface/mcp — translation only"]
        tools["MCP tools<br/>pydantic input · flat output views"]
    end
    subgraph application["application — use cases"]
        uc["ListUnreadEmails · SearchEmails · GetEmail<br/>ListEmails · CountEmails · TopSenders · ListLargestEmails<br/>ListTodaysEvents · ListUpcomingEvents<br/>PreviewEvent · CreateEvent<br/>PreviewEventUpdate · UpdateEvent<br/>PreviewEventDeletion · DeleteEvent<br/>ListFolders · SearchContacts"]
        ports["Ports (Protocol)<br/>MailRepository · CalendarRepository · CalendarWriter<br/>ContactRepository · MailFolderRepository · Clock"]
    end
    subgraph domain["domain — entities and rules"]
        ent["Email · Event · Contact · Page · TimeWindow<br/>frozen dataclasses · no Graph, no MCP"]
    end
    subgraph infra["infrastructure/graph — the only place that knows Microsoft"]
        adapters["Graph adapters<br/>query builders · JSON→entity mappers"]
        auth["MSAL device-code<br/>token cache in macOS Keychain"]
        http["httpx client<br/>host-pinned to graph.microsoft.com"]
    end
    clock["infrastructure/system_clock<br/>SystemClock — reads the resolved time zone"]
    tools --> uc
    uc --> ports
    uc --> ent
    adapters -. implements .-> ports
    clock -. implements .-> ports
    adapters --> http
    http --> auth

読み取り呼び出しの一連の流れです。入力はクエリになる前に検証され、ログには内容ではなくメタデータと件数が記録されます。

sequenceDiagram
    participant CD as Claude Desktop
    participant S as MCP server (stdio)
    participant UC as Use case
    participant A as Graph adapter
    participant K as macOS Keychain
    participant G as Microsoft Graph
    CD->>S: tools/call list_unread_emails {folder, limit}
    S->>S: validate input (pydantic) → request object
    S->>UC: execute(request)
    UC->>A: list_unread(folder, limit)
    A->>K: read cached token (MSAL silent refresh)
    K-->>A: access token
    A->>G: GET /me/mailFolders/inbox/messages?$filter…&$orderby…&$top…&$count=true
    G-->>A: JSON page + @odata.count
    A-->>UC: Page[Email]
    UC-->>S: Page[Email]
    S-->>CD: {items, returned, total, total_is_exact}
    Note over S: JSON log to stderr: correlation id, tool, duration, count — never content

開発

uv sync
uv run ruff check .
uv run ruff format --check .
uv run mypy
uv run pytest
インテグレーションテスト

@pytest.mark.integration が付いたテストは実際の Microsoft Graph API に接続し、デフォルトでは選択対象から除外されています。サインインが完了していること(インストールを参照)と、環境変数にクライアント ID が設定されていることが必要です。

export OUTLOOK_MCP_CLIENT_ID=<your client id>
uv run pytest -m integration

これらのテストはサインイン済みのメールボックスを読み取りますが、書き込みは行いません。また、テスト用のフィクスチャは独自に用意します。特定のメッセージが存在する必要はなく、メールボックスにテスト対象が何もない場合は、失敗ではなくテストをスキップします。

そのうちの 1 つは、単なる補助ではなく重要なテストです。test_search_query_live.py は、Graph が検索語をクエリとしてではなくリテラルテキストとして解析することを確認します。同じ文字列を安全な形式と、このプロジェクトが以前送信していた形式で送り、メールボックス自体から取得した送信者を使って結果数を比較します。ユニットテストではこれを確認できません。ユニットテストで検証できるのは送信するバイト列だけであり、実際には検索語がクエリとして実行されていたにもかかわらず、すべてのユニットテストが成功していました。クエリの引用、エスケープ、エンコード方法に関する変更を行った後は、このテストを実行してください。

インストール

1. Microsoft Entra ID にアプリを登録する

Microsoft アカウントとアプリの登録の表に従ってください。アプリケーション(クライアント)IDを控えてください。これはシークレットではありませんが、登録を識別するものであり、このリポジトリに含めてはいけません。

2. インストールする
git clone https://github.com/valter-araujo/outlook-mac-mcp.git
cd outlook-mac-mcp
uv sync
3. 一度サインインする

MCP サーバーが独自にサインインを開始することはありません。デバイスコードフローではブラウザーを待つために数分間処理がブロックされます。また、stdio サーバーにはコードを表示する場所がありません。標準出力には MCP プロトコルが出力されるためです。その代わり、別途認証します。

export OUTLOOK_MCP_CLIENT_ID=<your client id>
uv run outlook-mac-mcp sign-in

コードと URL は標準エラー出力に表示されます。URL を開き、コードを入力して、要求されたスコープを承認してください。生成されたトークンは outlook-mac-mcp サービスの下で macOS Keychain に保存されます。ファイルや環境変数に書き込まれることはありません。

更新トークンの有効期限が切れた場合、または同意を取り消した場合にのみ、これを繰り返してください。

4. Claude Desktop からサーバーに接続する

~/Library/Application Support/Claude/claude_desktop_config.json を編集します。

{
  "mcpServers": {
    "outlook-mac-mcp": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/outlook-mac-mcp", "run", "outlook-mac-mcp"],
      "env": {
        "OUTLOOK_MCP_CLIENT_ID": "<your client id>"
      }
    }
  }
}

この設定では、次の 3 点を正しく設定する必要があります。

  • OUTLOOK_MCP_CLIENT_ID は env ブロックに設定する必要があります。 Claude Desktop はサーバーを GUI プロセスとして起動するため、シェル環境を継承しません。~/.zshrc の export は認識されません。サーバーから参照できるのは env ブロックだけです。
  • --directory には絶対パスを指定します。 起動されたプロセスは、プロジェクトディレクトリをカレントディレクトリとして起動するわけではありません。
  • uv が起動プロセスの PATH に含まれている必要があります。 この PATH もシェルのものとは異なります。サーバーが起動しない場合は、"command": "uv" を which uv で確認した絶対パス(通常は ~/.local/bin/uv)に置き換えてください。

Claude Desktop を再起動します。list_unread_emails とその他の読み取りツールがツール一覧に表示されます。4 つの作成/更新ツールは書き込みフラグを有効にした場合にのみ表示され、preview_event_deletion/delete_event を使うには、それに加えて削除フラグも有効にする必要があります(オプション:カレンダーの削除を参照)。

オプション:ログレベル

OUTLOOK_MCP_LOG_LEVEL はログの詳細度を設定します(デフォルトは INFO)。構造化 JSON ログは標準エラー出力に出力され、メタデータのみを含みます。内容はツール名、相関 ID、所要時間、結果、項目数であり、件名、アドレス、本文は含まれません。同じ env ブロックに追加してください。

オプション:タイムゾーン

カレンダーツールはすべての時刻を単一のタイムゾーンで扱い、「今日」の基準もそのタイムゾーンに基づいて決定します。デフォルトでは、オペレーティングシステムが報告するマシンのタイムゾーンが使われます。上書きするには、America/Sao_Paulo や Europe/Lisbon などの IANA 名を指定して、OUTLOOK_MCP_TIMEZONE を同じ env ブロックに追加します。名前は起動時に検証されます。不明な名前を指定すると、ConfigurationError が発生し、サーバーと sign-in の両方が停止します。解決されたタイムゾーンは起動時にログに記録されます。

任意:カレンダーへの書き込み

デフォルトでは無効です。env ブロックに OUTLOOK_MCP_ENABLE_CALENDAR_WRITE=true を設定すると、サーバーは読み取りスコープに加えて Calendars.ReadWrite スコープを要求し、作成ツールと更新ツールを登録します。受け付ける値は true、false、1、0 です。それ以外の値を設定すると、ConfigurationError が発生してサーバーが停止します。

スコープのセットが変わるため、Keychain に保存済みのトークンはそのままでは使えなくなり、再度サインインするまで、すべてのツールが「使用可能なキャッシュ済み認証情報がありません」というエラーで失敗します。同じシェルでフラグを設定してサインインし直し、新しい同意プロンプトでカレンダーへの書き込みアクセスを許可してください。

export OUTLOOK_MCP_CLIENT_ID=<your client id>
export OUTLOOK_MCP_ENABLE_CALENDAR_WRITE=true
uv run outlook-mac-mcp sign-in

フラグを再びオフにしても、すでに付与した同意の範囲は縮小されません。書き込み権限を削除する場合は、https://account.live.com/consent/Manage で取り消してください。

フラグをオンにすると、作成と更新のそれぞれについて、プレビューしてから確定する2段階の組み合わせが表示され、ツールは合計4つになります。3つ目の組み合わせである削除には、このフラグに加えて専用の追加フラグが必要です。適用ステップを取り消せないのが削除だけであるためです。任意:カレンダーの削除を参照してください。各組み合わせは常に2段階のハンドシェイクで、トークンの名前空間もそれぞれ独立しています。ある組み合わせのトークンは、別の組み合わせの適用ツールでは拒否されます。自身の組み合わせ内でしか使用できません。

  1. preview_event は新しいイベントの詳細をすべて受け取り、検証します。詳細には、件名、UTC オフセット付きの開始日時と終了日時、終日フラグ、任意の自由記述の場所、最大32,768文字の任意のプレーンテキスト本文、最大50件の出席者アドレス、任意のリマインダー通知までの時間(分)、任意の機密度(normal、personal、private、confidential)、および任意の表示上の空き時間情報(free、tentative、busy、oof、workingElsewhere)が含まれます。検証後、1行の概要と不透明なトークンを返します。ここでは何も書き込まれません。create_event はそのトークンだけを受け取り、実際に変更を行います。
  2. preview_event_update はイベント ID と、同じフィールドのうち任意の一部を受け取ります。ただし、終日フラグは作成後に変更できず、現在のイベントの値が常に引き継がれるため、対象外です。対象となるフィールドは、件名、開始日時、終了日時、場所、本文、出席者、リマインダー通知までの時間、機密度、表示上の空き時間情報です。現在のイベントを取得し、トークンと、変更された各フィールドの差分を旧値 -> 新値の形式で示す概要を返します。変更後の状態だけを示すことはありません。呼び出しで指定されなかったフィールドは、まったく変更されません。update_event はそのトークンだけを受け取り、変更されたフィールドだけを適用します。

各適用ツールのトークンは、同じサーバープロセス内で1回だけ使用できます。不明なトークン、使用済みのトークン、または別の組み合わせのプレビューツールが発行したトークンは拒否されます。サーバーを再起動すると、保留中のすべての下書きが破棄されます。このルールは、次に説明する削除を含む、すべての組み合わせに適用されます。

各ツールの説明では、適用前にクライアントが概要を表示し、ユーザーの同意を得るよう指示しています。また、内容の一部でもメールから取得したものである場合は、プレビューする前に、すべての詳細について明示的な確認を得るよう指示しています。メールは信頼できない入力です。メッセージには、モデルをそそのかしてカレンダーを変更させる内容が書かれている可能性があります。決めるのはユーザーであり、メールではありません。

オプション:カレンダーの削除

デフォルトでは無効で、カレンダーへの書き込みとは独立しています。OUTLOOK_MCP_ENABLE_CALENDAR_DELETE=true だけを設定しても何も起こりません。 preview_event_deletion と delete_event は、両方のフラグが true の場合にのみ登録されます。カレンダーへの書き込みによって、この2つのツールが呼び出す Graph カレンダーライターが構築され、このフラグによって、その上に取り消し不能な操作が1つ追加されます。Graph のスコープは追加で要求されません。カレンダーへの書き込みですでに必要な Calendars.ReadWrite は、Graph 側での削除にも適用されるため、オプション:カレンダーへの書き込みでの同意確認以外に追加の同意確認は必要ありません。

export OUTLOOK_MCP_CLIENT_ID=<your client id>
export OUTLOOK_MCP_ENABLE_CALENDAR_WRITE=true
export OUTLOOK_MCP_ENABLE_CALENDAR_DELETE=true
uv run outlook-mac-mcp sign-in

preview_event_deletion はイベント ID を受け取り、現在のイベントを取得して、イベントのすべてのフィールドを省略せずに表示する概要とトークンを返します。対象となるフィールドは、件名、開始、終了、場所、本文、出席者です。これにより、削除される内容を確認時に正確に把握できます。これは、類似したイベントが2つ存在し、詳細をすべて見なければ区別できない場合に特に重要です。delete_event はそのトークンだけを受け取り、イベントを削除します。この操作はサーバーから元に戻せません。この2つのツールは、作成および更新と同じトークンのルールに従います。トークンは1回のみ使用でき、独自の名前空間を持ち、他のすべてのペアの適用ツールでは拒否されます。

トラブルシューティング
症状原因
ツールが「使用可能なキャッシュ済み資格情報がありません」というエラーで失敗する手順3が完了していないか、トークンが取り消されています。もう一度 sign-in を実行してください。
ConfigurationError が発生してサーバーの起動に失敗するenv ブロックに OUTLOOK_MCP_CLIENT_ID がないか、OUTLOOK_MCP_TIMEZONE が IANA タイムゾーン名ではありません。
Claude Desktop にサーバーが表示されないuv がランチャーの PATH にありません。command には絶対パスを指定してください。

免責事項

このプロジェクトは、いかなる種類の保証もなく「現状のまま」提供されます(LICENSE を参照)。作成者は、他者がこのコードをどのように設定、実行、デプロイするかについて責任を負いません。また、その結果生じるデータ損失やその他のあらゆる事象についても責任を負いません。

カレンダーへの書き込みツールは Microsoft Graph を通じて実際に変更を行い、delete_event はこのサーバーから元に戻せません。重要な用途で利用する前に、影響の少ないイベント、または使い捨てのイベントでテストしてください。オプション:カレンダーへの 書き込みを参照してください。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。