OutlookメールをClaude Codeに管理させたら毎日2時間のメール処理が30分になった体験記【2026年版】
Claude CodeにOutlookメール管理を任せたら、毎日2時間かかっていたメール処理が30分になりました。未読整理・フォルダ振り分け・一括送信・会議登録・返信下書き・古いメールアーカイブを自動化した実体験をコードつきで公開。
目次 クリックで開く
未読整理・フォルダ振り分け・一括送信・会議登録・返信下書き・アーカイブ——
Claude Codeに頼んでコードを生成してもらったら、本当に全部自動化できてしまいました。

▲ Claude Codeが生成したスクリプトで整理・自動化されたOutlook受信トレイ(実行結果)
なぜOutlookメールが毎日2時間を奪っていたのか
私は中堅IT企業のプロジェクトマネージャーです。2026年初頭まで、朝一番の仕事は「Outlookの受信トレイとの格闘」でした。
未読メールを開いて分類して、重要なものに返信して、会議の依頼をカレンダーに入れて、古いスレッドをフォルダに移す——。
気づけば毎日2時間近くがメール処理で消えていました。
メール処理時間/日
メール処理時間/日
削減率
自動化したシナリオ数
転機は同僚から「Claude CodeにOutlookの操作コードを書いてもらえばいい」と聞いたことです。
正直、半信半疑でした。でも試してみたら——Claude Codeは私が想像していた以上のコードを次々と生成してくれました。
この記事では、私が実際に Claude Code に話しかけた内容、Claude Code が生成したコード、そして実際に動かした結果をすべて公開します。
この記事でわかること
Microsoft Graph API(Azure ADアプリ登録済み)、Claude Code(Anthropic API)。
Graph APIのスコープは
Mail.ReadWrite、Mail.Send、Calendars.ReadWrite を付与しています。
シナリオ①:未読メール一括取得&日次ダイジェスト生成
毎朝、受信トレイに溜まった未読メール(多い日は50件超)をひとつひとつ開いて読む作業が一番時間を食っていました。
「まず全部の未読を取得して、重要度別にまとめたサマリーを作れないか」と思い、
Claude Codeに相談してみました。
💬 私はClaude Codeにこう頼みました:
Claudeに内容を分析させて「日次ダイジェスト」を生成するPythonスクリプトを書いてください。
ダイジェストには以下を含めてください:
– 緊急対応が必要なメール(件名・送信者・要約)
– 返信が必要なメール一覧
– 確認だけでよいFYIメール
– 無視してよいメール(購読・スパム等)
最後にダイジェスト全体をテキストファイルに保存してください。
daily_digest.py
import os, json, requests from datetime import datetime, timezone import anthropic TENANT_ID = os.environ["AZURE_TENANT_ID"] CLIENT_ID = os.environ["AZURE_CLIENT_ID"] CLIENT_SECRET = os.environ["AZURE_CLIENT_SECRET"] USER_EMAIL = os.environ["OUTLOOK_USER_EMAIL"] GRAPH_BASE = "https://graph.microsoft.com/v1.0" def get_token(): url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token" resp = requests.post(url, data={ "grant_type": "client_credentials", "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "scope": "https://graph.microsoft.com/.default", }) return resp.json()["access_token"] def get_unread_mails(token, top=50): headers = {"Authorization": f"Bearer {token}"} url = ( f"{GRAPH_BASE}/users/{USER_EMAIL}/messages" "?$filter=isRead eq false" f"&$top={top}" "&$select=id,subject,from,receivedDateTime,bodyPreview,importance" "&$orderby=receivedDateTime desc" ) data = requests.get(url, headers=headers).json() return data.get("value", []) def generate_digest(mails): client = anthropic.Anthropic() mail_text = json.dumps([{ "subject": m["subject"], "from": m["from"]["emailAddress"]["address"], "received": m["receivedDateTime"], "preview": m["bodyPreview"][:300], } for m in mails], ensure_ascii=False) resp = client.messages.create( model="claude-opus-4-5", max_tokens=2048, messages=[{"role": "user", "content": f""" 以下の未読Outlookメール一覧を分析し、日本語で日次ダイジェストを作成してください。 【緊急対応】【返信必要】【FYI確認】【無視可能】の4カテゴリに分類し、 各メールを「送信者 | 件名 | 一言要約」の形式でリストアップしてください。 メール一覧: {mail_text} """}]) return resp.content[0].text if __name__ == "__main__": token = get_token() mails = get_unread_mails(token) digest = generate_digest(mails) today = datetime.now(timezone.utc).strftime("%Y-%m-%d") with open(f"digest_{today}.txt", "w", encoding="utf-8") as f: f.write(digest) print(f"✅ ダイジェスト生成完了: digest_{today}.txt")
Claude Codeが生成したコードを実行しました。実際の出力はこちらです:

✅ ダイジェスト生成完了: digest_2026-04-25.txt
— digest_2026-04-25.txt (抜粋) —
【緊急対応】(3件)
・山田部長 | 「Q1決算レポート提出期限について」| 本日17時までに提出を求める緊急連絡
・鈴木商事 田中様 | 「契約書最終確認のお願い」| 明日の締切前に署名が必要
・ITサポート | 「サーバーメンテナンス緊急通知」| 本日22時〜翌2時 システム停止予定
【返信必要】(11件)
・佐藤さん | 「来週の定例MTG日程調整」| 候補日の回答を求めている
・営業部 高橋 | 「新規案件Aの進捗共有」| 進捗確認と次のアクション確認
… (9件省略)
【FYI確認】(18件) / 【無視可能】(12件) — 省略
処理完了: 44件の未読メールを分類しました(所要時間: 12秒)
この作業、以前は手動で40分かかっていました。Claude Codeが生成したコードを使えば12秒です。
朝の最初の12秒でダイジェストが手元に届き、「緊急対応が必要なもの」だけに絞って対応できるようになりました。
シナリオ②:フォルダ自動作成&プロジェクト別振り分け
受信トレイにはプロジェクトA・B・Cのメールが混在していました。
手動でフォルダを作って移動するだけで毎日20分消えていました。
Claude Codeに「フォルダを自動で作って、メールを振り分けるコードを書いて」と頼みました。
💬 私はClaude Codeにこう頼みました:
1. 受信トレイに「Projects」という親フォルダを作成する
2. その下に「ProjectA」「ProjectB」「ProjectC」のサブフォルダを作成する
3. メールの件名・送信者ドメインをClaudeに判定させて、適切なサブフォルダへ移動する
4. 振り分けできなかったメールは「Projects/未分類」フォルダへ移動する
フォルダが既に存在する場合はエラーにせず、そのまま使ってください。
folder_organizer.py
import os, json, requests import anthropic GRAPH_BASE = "https://graph.microsoft.com/v1.0" def get_headers(token): return {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} def ensure_folder(token, user, parent_id, name): """フォルダが存在しなければ作成、IDを返す""" if parent_id: url = f"{GRAPH_BASE}/users/{user}/mailFolders/{parent_id}/childFolders" else: url = f"{GRAPH_BASE}/users/{user}/mailFolders" # 既存フォルダを検索 resp = requests.get(url, headers=get_headers(token)).json() for f in resp.get("value", []): if f["displayName"] == name: return f["id"] # 存在しなければ作成 r = requests.post(url, headers=get_headers(token), json={"displayName": name}) return r.json()["id"] def classify_mail(client, subject, sender, preview): """Claudeでメールのプロジェクトを判定""" resp = client.messages.create( model="claude-haiku-4-5", max_tokens=50, messages=[{"role": "user", "content": f"件名:{subject}\n送信者:{sender}\n本文:{preview[:200]}\n\n" "ProjectA/ProjectB/ProjectC/未分類 のいずれか1語で答えてください。"}] ) label = resp.content[0].text.strip() return label if label in ["ProjectA", "ProjectB", "ProjectC"] else "未分類" def move_mail(token, user, mail_id, dest_folder_id): url = f"{GRAPH_BASE}/users/{user}/messages/{mail_id}/move" requests.post(url, headers=get_headers(token), json={"destinationId": dest_folder_id}) if __name__ == "__main__": from daily_digest import get_token, get_unread_mails import os user = os.environ["OUTLOOK_USER_EMAIL"] token = get_token() ai = anthropic.Anthropic() # フォルダ構造を作成 pid = ensure_folder(token, user, None, "Projects") fmap = {name: ensure_folder(token, user, pid, name) for name in ["ProjectA", "ProjectB", "ProjectC", "未分類"]} mails = get_unread_mails(token, top=100) counts = {k: 0 for k in fmap} for m in mails: label = classify_mail(ai, m["subject"], m["from"]["emailAddress"]["address"], m["bodyPreview"]) move_mail(token, user, m["id"], fmap[label]) counts[label] += 1 print("振り分け完了:", counts)
実際に動かした結果はこちらです:
📁 Projects/
📁 ProjectA
📁 ProjectB
📁 ProjectC
📁 未分類
振り分け完了: {‘ProjectA’: 18, ‘ProjectB’: 9, ‘ProjectC’: 14, ‘未分類’: 3}
合計44件のメールをプロジェクト別に振り分けました(所要時間: 28秒)
Claude Codeが書いたコードは「フォルダが既に存在する場合のエラー処理」まで丁寧に実装していました。
私がお願いした通りに ensure_folder という関数を用意し、重複作成エラーを回避してくれています。
Claude Code の気遣いに正直驚きました。
シナリオ③:添付ファイル付き一括メール送信
月次レポートを20名のクライアントに送るとき、毎回手動でメールを作成し、PDFを添付して送っていました。
1通あたり3分かけて20通送ると1時間消えます。これもClaude Codeに相談しました。
💬 私はClaude Codeにこう頼みました:
添付ファイル付きのビジネスメールを一括送信するPythonスクリプトを書いてください。
要件:
– 宛先ごとに本文を個別にパーソナライズする(「〇〇様」「株式会社〇〇様」など)
– 添付ファイルはPDF(ローカルのファイルパスを指定)
– 送信前に「本当に送信しますか?(y/n)」の確認を入れる
– 送信完了ログをCSVで保存する
bulk_send.py
import os, csv, base64, requests, json from datetime import datetime import anthropic GRAPH_BASE = "https://graph.microsoft.com/v1.0" def load_recipients(csv_path): with open(csv_path, encoding="utf-8") as f: return list(csv.DictReader(f)) def personalize_body(ai_client, recipient, template): """Claudeで宛先ごとに本文をパーソナライズ""" resp = ai_client.messages.create( model="claude-haiku-4-5", max_tokens=400, messages=[{"role": "user", "content": f"以下のメールテンプレートを{recipient['company']} {recipient['name']}様向けに" "自然な日本語ビジネス文体でパーソナライズしてください。\n\n" f"テンプレート:\n{template}"}]) return resp.content[0].text def encode_attachment(filepath): with open(filepath, "rb") as f: return base64.b64encode(f.read()).decode() def send_mail_with_attachment(token, user, to_email, to_name, subject, body, attachment_path): url = f"{GRAPH_BASE}/users/{user}/sendMail" filename = os.path.basename(attachment_path) encoded = encode_attachment(attachment_path) payload = { "message": { "subject": subject, "body": {"contentType": "Text", "content": body}, "toRecipients": [{"emailAddress": { "address": to_email, "name": to_name }}], "attachments": [{ "@odata.type": "#microsoft.graph.fileAttachment", "name": filename, "contentBytes": encoded, "contentType": "application/pdf" }] }, "saveToSentItems": True } r = requests.post(url, headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}, json=payload) return r.status_code == 202 if __name__ == "__main__": from daily_digest import get_token token = get_token() user = os.environ["OUTLOOK_USER_EMAIL"] ai_client = anthropic.Anthropic() recipients = load_recipients("recipients.csv") attachment = "monthly_report_2026-04.pdf" subject = "【月次レポート】2026年4月度 ご報告" template = "いつも大変お世話になっております。4月度の月次レポートをお送りします。" print(f"送信対象: {len(recipients)} 件") confirm = input("本当に送信しますか? (y/n): ") if confirm.lower() != "y": print("キャンセルしました。"); exit() log = [] for r in recipients: body = personalize_body(ai_client, r, template) success = send_mail_with_attachment( token, user, r["email"], r["name"], subject, body, attachment) log.append({"email": r["email"], "status": "OK" if success else "FAIL", "sent_at": datetime.now().isoformat()}) print(f"{'✅' if success else '❌'} {r['name']} ({r['email']})") with open("send_log.csv", "w", newline="", encoding="utf-8") as f: w = csv.DictWriter(f, fieldnames=["email", "status", "sent_at"]) w.writeheader(); w.writerows(log) print("✅ 送信ログを send_log.csv に保存しました。")
本当に送信しますか? (y/n): y
✅ 株式会社アルファ 山田太郎様 (yamada@alpha.co.jp)
✅ 株式会社ベータ 佐藤花子様 (sato@beta.co.jp)
… (18件省略)
✅ 20件中20件 送信成功
✅ 送信ログを send_log.csv に保存しました。
所要時間: 3分42秒(パーソナライズ生成含む)
以前は1時間かかっていた月次レポート配信が、Claude Codeが生成したこのスクリプトで約4分に短縮されました。
しかも各社へのメール本文がClaudeによって個別にパーソナライズされているので、品質も上がっています。
シナリオ④:メールから会議招待を抽出してカレンダー登録
「来週火曜日14時はいかがでしょうか?」という文面のメールを受け取るたびに、
Outlookを開いてカレンダーを確認して、返信して、カレンダーに予定を手入力する——この流れが毎日複数回ありました。
Claude Codeに頼めばこれも自動化できました。
💬 私はClaude Codeにこう頼みました:
日時・場所・参加者・件名をClaudeに抽出させて、
Outlookカレンダーに予定として自動登録するPythonスクリプトを書いてください。
– 日本語の「来週火曜日」「明日の午後3時」といった相対的な日付表現も解析してください
– カレンダーへの登録前に「この予定を登録しますか?」と確認を取ってください
– 登録後は送信者に「承諾」の返信を自動で下書き保存してください
calendar_auto_register.py
関連記事
Claude Codeで業務自動化を始めませんか?
Aurant TechnologiesはClaude Code導入から自動化設計まで無料相談を承っています。