mcpField
M
microsoft-outlook

microsoft-outlook

github.com/acedatacloud生産性17260 回インストール2 日前に更新
リポジトリ

microsoft-outlook について

`curl + jq` で Microsoft Graph を呼び出し、Outlook のメールとカレンダーを扱うシェルスキルです。メール検索や下書き・添付ファイルの操作、予定や空き時間の確認に対応し、送信や変更などの前に確認する手順も示します。

主な機能

  1. 01メールの閲覧・絞り込み・検索
  2. 02メール下書きの作成と管理
  3. 03メッセージと添付ファイルの処理
  4. 04カレンダー予定の確認と更新
  5. 05空き時間とメールボックス設定の確認

活用シーン

  1. 01未読メールや特定の差出人のメールを探す
  2. 02送信前にメール下書きを確認する
  3. 03繰り返し予定を含む当日の予定を確認する
  4. 04複数人の会議候補時間を探す

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/acedatacloud/skills --skill microsoft-outlook

インストール後、Claude Code で/microsoft-outlookを入力して読み込まれたか確認します。

詳細

curl + jq を使って、Outlook / Microsoft 365 の Microsoft Graph(メールと カレンダーの両方)を操作します。ユーザーの OAuth ベアラートークンは $MICROSOFT_OUTLOOK_TOKEN に格納されています。各呼び出しで Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN として指定する必要があります。 トークンには、インストール時にユーザーが同意したスコープのうち、 Mail.Read、Mail.ReadWrite、Mail.Send、MailboxSettings.Read、 MailboxSettings.ReadWrite、Calendars.Read、Calendars.ReadWrite、 および *.Shared バリアントが含まれています。 Microsoft Graph ではメールとカレンダーは同じメールボックスの兄弟機能として扱われるため、 両者をひとつのコネクター(ひとつの OAuth 許可)に統合しています。スキルレイヤーで 分割しても利点はありません。

Graph API は JSON を返します。エラーは {"error": {"code": "...", "message": "..."}} として返されるため、 そのエラーをそのままユーザーに表示してください。

必ず /me から開始し、接続が機能することを確認して、 操作対象のメールボックスを把握してください。カレンダーを操作する場合は、 日付を正しく表示するために mailboxSettings.timeZone も取得してください。


メール — レシピ

認証を確認する(必ず最初に実行)
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  https://graph.microsoft.com/v1.0/me \
  | jq '{displayName, mail, userPrincipalName}'
最近のメッセージを一覧表示する
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages?\$top=10&\$select=id,subject,from,receivedDateTime,isRead,hasAttachments&\$orderby=receivedDateTime desc" \
  | jq '.value[] | {subject, from: .from.emailAddress.address, received: .receivedDateTime, unread: (.isRead | not)}'

フィルター:URL に & を付けて追加します(スペースは URL エンコードしてください)。

条件追加する値
未読のみ&$filter=isRead eq false
添付ファイルあり&$filter=hasAttachments eq true
特定の送信者から&$filter=from/emailAddress/address eq '[email protected]'
期間&$filter=receivedDateTime ge 2026-04-01T00:00:00Z and receivedDateTime lt 2026-05-01T00:00:00Z
組み合わせるフィルター句の間に and / or を使用します
メッセージを検索する(件名と本文の全文検索)
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  --data-urlencode '$search="quarterly report"' \
  --data-urlencode '$top=10' \
  --data-urlencode '$select=id,subject,from,receivedDateTime' \
  --get https://graph.microsoft.com/v1.0/me/messages

$search は同じクエリ内で $filter や $orderby と組み合わせられません。 いずれかひとつを選んでください。$search は関連度順の検索結果を返します。

メッセージ本文を読む
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}?\$select=subject,body,from,toRecipients,receivedDateTime" \
  | jq '{subject, from: .from.emailAddress.address, received: .receivedDateTime, body: .body.content}'

body.contentType は通常 "HTML" です。生の HTML が必要な場合は、 jq -r .body.content を使用してください。

メールを送信する

⚠️ 必ず「下書き → 確認 → 送信」の手順を踏んでください。 /me/sendMail を直接呼び出してはいけません。取り消しできず、即座に送信されます。

# Step 1: create draft
DRAFT=$(curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc \
        --arg subj "Project update" \
        --arg body "<p>Wanted to share the latest numbers.</p>" \
        --arg to "[email protected]" \
        '{subject:$subj, body:{contentType:"HTML", content:$body}, toRecipients:[{emailAddress:{address:$to}}]}')" \
  https://graph.microsoft.com/v1.0/me/messages)
DRAFT_ID=$(echo "$DRAFT" | jq -r .id)

# Step 2: present the draft to the user — subject, recipients, body preview
echo "$DRAFT" | jq '{subject, to: .toRecipients[0].emailAddress.address, body: .body.content}'

# Step 3: ONLY after user confirms — send (returns 202 No Content)
curl -sS -X POST -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${DRAFT_ID}/send" \
  -w "HTTP %{http_code}\n"

CC / BCC:toRecipients と同じ形式の配列を ccRecipients / bccRecipients に含めます。

返信 / 全員に返信 / 転送

⚠️ 送信前に、下書きの本文と宛先をユーザーに表示してください。

# Quick reply (sends immediately on /reply — for explicit user-confirmed flow)
curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"comment":"Thanks for the update!"}' \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}/reply"

# Or: createReply → review → /send (preferred for non-trivial replies)
DRAFT=$(curl -sS -X POST -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}/createReply")
DRAFT_ID=$(echo "$DRAFT" | jq -r .id)
# PATCH body if needed, then /send

# Forward
curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc --arg to "[email protected]" \
        '{comment:"FYI", toRecipients:[{emailAddress:{address:$to}}]}')" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}/forward"
既読 / 未読にする
curl -sS -X PATCH \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"isRead": true}' \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}"
フォルダーを一覧表示する+特定のフォルダーを読む
# Well-known folder names: Inbox, Drafts, SentItems, DeletedItems, Archive, JunkEmail
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/mailFolders('SentItems')/messages?\$top=5&\$select=subject,toRecipients,sentDateTime" \
  | jq '.value[] | {subject, sent: .sentDateTime}'
添付ファイルを一覧表示する+ダウンロードする
# Metadata
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}/attachments?\$select=id,name,size,contentType" \
  | jq '.value[] | {id, name, size}'

# Download a single attachment
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}/attachments/${ATT_ID}/\$value" \
  -o "$SKILL_DIR/tmp/attachment.bin"
メールボックスの設定(タイムゾーン、署名、自動返信)
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/mailboxSettings"

不在時の自動返信を設定する:

⚠️ 変更前にユーザーに確認してください。自動返信は受信メールのたびに送信されます。

curl -sS -X PATCH \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"automaticRepliesSetting":{
        "status":"scheduled",
        "scheduledStartDateTime":{"dateTime":"2026-05-10T09:00:00","timeZone":"China Standard Time"},
        "scheduledEndDateTime":{"dateTime":"2026-05-15T18:00:00","timeZone":"China Standard Time"},
        "internalReplyMessage":"<p>I'm out this week, back Monday.</p>"}}' \
  "https://graph.microsoft.com/v1.0/me/mailboxSettings"

MailboxSettings.ReadWrite スコープが必要です。

メッセージを削除する

⚠️ 必ず最初に件名を取得し、ユーザーに確認してください。

# 1) show what's about to be deleted
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}?\$select=subject,from,receivedDateTime" \
  | jq '"Delete \"\(.subject)\" from \(.from.emailAddress.address) (\(.receivedDateTime))?"'

# 2) after user confirms (moves to Deleted Items, returns 204)
curl -sS -X DELETE -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages/${MSG_ID}" \
  -w "HTTP %{http_code}\n"

カレンダー — レシピ

ユーザーのタイムゾーンを取得する(カレンダー操作の開始時に一度実行)
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/mailboxSettings" \
  | jq '.timeZone'
# → e.g. "China Standard Time"

すべてのカレンダー呼び出しで、このタイムゾーンを Prefer: outlook.timezone ヘッダーに指定してください。そうすると start.dateTime / end.dateTime がユーザーの現地時間で返されます。

TZ_HEADER='Prefer: outlook.timezone="China Standard Time"'
今日の予定(calendarView)

calendarView は期間内の繰り返し予定を個々の予定に展開するため、予定の確認に最適です。 通常の /events は繰り返し予定のマスターのみを返します。

START=$(date -u +'%Y-%m-%dT00:00:00Z')
END=$(date -u -v+1d +'%Y-%m-%dT00:00:00Z')   # macOS; use -d on Linux
curl -sS \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Prefer: outlook.timezone=\"China Standard Time\"" \
  --data-urlencode "startDateTime=$START" \
  --data-urlencode "endDateTime=$END" \
  --data-urlencode '$select=id,subject,start,end,location,attendees,onlineMeeting,isCancelled' \
  --data-urlencode '$orderby=start/dateTime' \
  --get https://graph.microsoft.com/v1.0/me/calendarView \
  | jq '.value[] | {subject, start: .start.dateTime, end: .end.dateTime, location: .location.displayName, attendees: [.attendees[].emailAddress.address]}'
今週の予定(月〜日)
START=$(date -u -v-Mon +'%Y-%m-%dT00:00:00Z' 2>/dev/null || date -u -d 'last monday' +'%Y-%m-%dT00:00:00Z')
END=$(date -u -v+7d -v-Mon +'%Y-%m-%dT00:00:00Z' 2>/dev/null || date -u -d 'next monday' +'%Y-%m-%dT00:00:00Z')
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Prefer: outlook.timezone=\"China Standard Time\"" \
  --data-urlencode "startDateTime=$START" \
  --data-urlencode "endDateTime=$END" \
  --data-urlencode '$select=subject,start,end' \
  --data-urlencode '$orderby=start/dateTime' \
  --get https://graph.microsoft.com/v1.0/me/calendarView
空き時間 / 予定ありの時間帯を探す(getSchedule)

複数の人に都合のよい時間帯を探すのに最適な方法です。指定した期間について、 空き、予定あり、仮の予定の状態を30分単位で返します。

curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc '{
        schedules: ["me", "[email protected]", "[email protected]"],
        startTime: {dateTime: "2026-05-05T09:00:00", timeZone: "China Standard Time"},
        endTime:   {dateTime: "2026-05-05T18:00:00", timeZone: "China Standard Time"},
        availabilityViewInterval: 30
      }')" \
  https://graph.microsoft.com/v1.0/me/calendar/getSchedule \
  | jq '.value[] | {who: .scheduleId, view: .availabilityView}'
# availabilityView is a string of digits: 0=free 1=tentative 2=busy 3=oof 4=workingElsewhere
単一の予定を読む(出席者と本文を含む)
curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Prefer: outlook.timezone=\"China Standard Time\"" \
  "https://graph.microsoft.com/v1.0/me/events/${EVENT_ID}?\$select=subject,start,end,location,attendees,body,organizer,onlineMeeting" \
  | jq '{subject, start: .start.dateTime, attendees: [.attendees[] | {addr: .emailAddress.address, response: .status.response}], body: .body.content}'
予定を作成する

⚠️ 作成前に、必ず件名 / 時刻 / 出席者をユーザーに表示してください。 イベントを POST した時点で招待が自動送信されます。

PAYLOAD=$(jq -nc \
  --arg subj "Project sync" \
  --arg body "<p>Quarterly review.</p>" \
  --arg start "2026-05-06T10:00:00" \
  --arg end   "2026-05-06T10:30:00" \
  --arg tz    "China Standard Time" \
  --arg loc   "Meeting room 3F" \
  --arg a1    "[email protected]" \
  '{
    subject: $subj,
    body:    {contentType:"HTML", content:$body},
    start:   {dateTime:$start, timeZone:$tz},
    end:     {dateTime:$end,   timeZone:$tz},
    location:{displayName:$loc},
    attendees:[{emailAddress:{address:$a1}, type:"required"}],
    isOnlineMeeting: true,
    onlineMeetingProvider: "teamsForBusiness"
  }')
curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$PAYLOAD" \
  https://graph.microsoft.com/v1.0/me/events \
  | jq '{id, subject, start: .start.dateTime, joinUrl: .onlineMeeting.joinUrl}'

isOnlineMeeting: true と onlineMeetingProvider: "teamsForBusiness" を指定すると、 Teams 会議リンクが自動生成されます。対面の予定では両方を省略してください。

更新 / 日程変更(PATCH)

⚠️ 更新すると、すべての出席者に「更新しました」という通知が送信されます。 先に確認してください。

curl -sS -X PATCH \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc \
        --arg start "2026-05-06T14:00:00" \
        --arg end   "2026-05-06T14:30:00" \
        --arg tz    "China Standard Time" \
        '{start:{dateTime:$start, timeZone:$tz}, end:{dateTime:$end, timeZone:$tz}}')" \
  "https://graph.microsoft.com/v1.0/me/events/${EVENT_ID}"
会議をキャンセルする(キャンセル通知を送信します)

⚠️ ユーザーに確認してください — すべての出席者に通知されます。

curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"comment":"Need to reschedule, sorry."}' \
  "https://graph.microsoft.com/v1.0/me/events/${EVENT_ID}/cancel" \
  -w "HTTP %{http_code}\n"
受信した招待を承諾/辞退/仮承諾する
curl -sS -X POST \
  -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"comment":"See you there", "sendResponse":true}' \
  "https://graph.microsoft.com/v1.0/me/events/${EVENT_ID}/accept"

# Or /decline, /tentativelyAccept
共有カレンダーを読む

Calendars.Read.Shared が必要です。

curl -sS -H "Authorization: Bearer $MICROSOFT_OUTLOOK_TOKEN" \
  "https://graph.microsoft.com/v1.0/users/${USER_UPN}/calendarView?startDateTime=${START}&endDateTime=${END}&\$select=subject,start,end" \
  -G
タイムゾーンの扱い
フィールド意味
start.dateTime / end.dateTime現地の壁時計時刻です。
start.timeZone / end.timeZoneIANA 風の名前("Pacific Standard Time"、"China Standard Time"、"UTC")です。
Prefer: outlook.timezone="..." リクエストヘッダー返されるすべての dateTime 値をこのタイムゾーンに変換します。

読み取り時には必ず Prefer: outlook.timezone を設定し、JSON が UTC ではなくユーザーの想定するタイムゾーンで返されるようにしてください。

繰り返し

calendarView を使用してください(予定の各回を展開します)。?$expand= は使用しないでください。 繰り返しイベントを作成するには、recurrence を含めます。

{
  "recurrence": {
    "pattern":  {"type":"weekly", "interval":1, "daysOfWeek":["monday","wednesday"]},
    "range":    {"type":"endDate", "startDate":"2026-05-06", "endDate":"2026-08-06"}
  }
}

一連の予定の特定の回を変更するには、シリーズのマスターではなく、calendarView が返すその回の ID に対して PATCH してください。


OData クイックリファレンス(メール+カレンダー)

パラメーターメールの例カレンダーの例
$selectid,subject,from,receivedDateTime,isReadsubject,start,end,location,attendees
$filterisRead eq falsestart/dateTime ge '2026-05-01T00:00:00'
$orderbyreceivedDateTime descstart/dateTime
$top閲覧は 10、検索は 25閲覧は 10
$search"keyword"(メールのみ — $filter / $orderby とは併用できません)該当なし
$expandattachmentsattendees、attachments

シェルでの $ やスペースのクォートを避けるには、curl で --data-urlencode "$key=$value" --get を使用してください。

ルール

  • 必ず $select を渡してください — デフォルトではアイテムごとに 30 個以上のフィールドが返されます。
  • 閲覧では $top=10、検索では 25 を指定してください。求められない限り、50 件を超えてページネーションしないでください。
  • メール本文は HTML のみにしてください。contentType: "Text" は空白をまとめます。
  • 予定表や「カレンダーに何があるか」という質問には、calendarView を使用してください。/events が返すのは繰り返し予定のマスターのみです。
  • カレンダーの読み取り時には Prefer: outlook.timezone を設定してください。設定しない場合、dateTime は UTC で返されます。
  • パスでメッセージ/イベント/添付ファイルの ID を使う場合は、URL エンコードしてください — ID には +、/、= が含まれることがあります。jq -sRr @uri を使用してください。
  • 日付計算:macOS では date -u -v+1d、Linux では date -u -d 'tomorrow' が使えます。

重要:破壊的操作/通知を伴う操作にはユーザーの同意が必要です

送信済みメールは取り消せません。カレンダーへの書き込みは出席者にメールを送信します。削除したメッセージは完全に失われる場合があります。 手順:準備 → 提示 → 実行。

操作準備手順ユーザーに提示する内容
メールを送信POST /me/messages(下書き)件名、宛先、本文のプレビュー
返信/転送createReply / createForward引用部分+返信文
メールを削除先に subject を取得「{sender} からの「{subject}」を削除しますか?」
不在時の自動応答先に現在の設定を表示新しいスケジュール+メッセージのプレビュー
イベントを作成ペイロードを作成件名、時刻、出席者、オンライン会議のオン/オフ
イベントを更新現在の内容との差分変更内容、通知される出席者の数
イベントをキャンセル先にイベントを取得件名、時刻、出席者の数
招待を承諾/辞退先にイベントを取得イベントの件名+開催者
一括操作対象を一覧表示件数+サンプル

/me/sendMail は決して呼び出さないでください — 取り消しできずに即時送信されます。必ず下書きを作成 → 確認 → /send の順に行ってください。

エラー

  • 401 InvalidAuthenticationToken → トークンの有効期限が切れています。ユーザーはコネクターを再インストールする必要があります。
  • 403 ErrorAccessDenied → 書き込みスコープがありません(例:許可されていない Mail.Send の使用、または作成/キャンセルに必要な Calendars.ReadWrite の不足)。ユーザーに再インストールして、書き込みスコープにチェックを入れるよう依頼してください。
  • 429 TooManyRequests → Retry-After ヘッダーに従ってください。
  • 404 ErrorItemNotFound → メッセージ/イベント ID が間違っています(または、すでに削除/キャンセルされています)。

Reference

コメント