投稿する

meeting-task-autopilot ── 議事録かmeeting-task-autopilot ── 議事録から翌朝のSlackまでをLLM+MCPで全自動化する1人法人向けオートパイロット

議事録のNotion保管からタスク抽出、翌朝のSlack通知、さらにリプライによるステータス更新までを完結させる個人・小規模チーム向けオートパイロットシステムです。 15分ごとのポーリングで議事録から「自分と相手の宿題」を自動判別してNotion DBへ集約。毎朝7:30にはGoogleカレンダーと連携した本日のブリーフがSlackに届きます。最大の特徴は、Slackのスレッドに「完了」や「+タスク名」と返信するだけで、PCを開かずにNotion側のタスク操作や翌日のブリーフ更新が完了する、双方向のエージェント体験にあります。 会議のたびに発生する「次にやるべきこと」の整理や、ツールを開きに行く摩擦を極限まで減らし、コア業務に集中するための脳内リソースを確保したいエンジニアやオーナーに最適です。
zip未取得

meeting-task-autopilot

MTGとタスク管理を全自動化するオートパイロット

── 会議の宿題を、脳内RAMから消すための自動操縦システム。

会議が終わった瞬間、その宿題は勝手にタスクDBに溜まる。
翌朝、Slackに今日やることが届く。
スレッドに T-1 完了 + 来週月曜までに資料送る と返信するだけで、
完了処理も新規登録も翌朝までに反映される。
PCを開く必要は、もうない。

---

なぜ作ったか(解決したい課題)

1人法人や小規模チームのオーナーは、複数の顧客・案件を自分の頭の中だけで並走させています。1日3〜5本の会議をこなすうち、こんな状況が常態化します:

  • 会議のたびに「これ自分の宿題」「これは相手のボール」を頭の中で判別する
  • 議事録はAI Meeting Note等で自動取得できても、そこから「次に自分が動くこと」を切り出す作業が手作業で残る
  • タスク管理ツールに書いても、毎朝それを開きにいく動作自体が摩擦になる
  • 「相手のボール」の状態が頭に居座り続けて、脳内のメモリリークを起こす

この最後の問題が一番重い。中核要求はシンプル:

「自分のボールじゃない時は、脳内RAMから完全に消したい」

本システムはこれを満たすために、議事録から朝のSlackまでの動線を完全自動化します。

コアバリューを一つだけ選べと言われたら、これです:

Slackのスレッド返信だけで、タスクDBと双方向にやりとりできる。

これを成立させているのが [brief:YYYY-MM-DD] という小さなマーカー発明(後述)です。cron的なバッチを、対話的なエージェントに変える小さな仕掛け。これが本作品の最大の独自性です。

---

使い方デモ(朝のSlackで起きていること)

月曜の朝 07:30、Slackに届くブリーフ:

*朝のブリーフ 2026-05-19 (月)*

*今日の予定*
10:00-11:00 A社定例
14:00-15:00 採用面談
19:00-20:00 ジム

*今日のフォーカス*
1. A社の提案資料を最終確認(10時定例で出す)
2. B社の見積もり修正(金曜までに送る約束)
3. 採用面談の質問項目を見直す

*議事録由来の宿題*
A社(顧客):
  `T-1` 提案資料のv3を最終確認 _(A社定例 / 05-16)_
  `T-2` 見積もり修正版を送付 _(A社定例 / 05-16)_
B社(顧客):
  `T-1` 契約書のレビューコメント返却 _(B社キックオフ / 05-15)_

[brief:2026-05-19]

オーナーは通勤電車で、こうリプライする:

T-1, T-2 完了
A社のT-1 → 来週でいい
+ 木曜までに採用面談のフィードバックを返す
+ 急ぎ:今日中に経費精算

翌朝のブリーフは、それを反映済み:

*朝のブリーフ 2026-05-20 (火)*
...
*処理結果*
T-1, T-2 → 完了として除外
A社のT-1 → 先送りとして除外
+ 木曜までに採用面談のフィードバックを返す → ToDoの通常に追加(期限 05-22)
+ 急ぎ:今日中に経費精算 → ToDoの最優先に追加(期限 05-20)

これだけです。PCも、タスク管理ツールも、開かなくていい。

---

システム全体像

                ┌────────────────────────────┐
                │  AI Meeting Note 等で      │
                │  Notion議事録DBに自動投入  │
                └─────────────┬──────────────┘
                              │ 15分ごとに polling
                              ▼
   ┌──────────────────────────────────────────────────┐
   │  poll_minutes.py                                 │
   │  ・transcriptionブロックを再帰展開               │
   │  ・Claude Sonnet で My Turn / Their Turn 判定    │
   │  ・抽出ステータスでロック(二重起動回避)        │
   │  ・dual_property で1ページ作成APIから3関係を同期 │
   └─────────────┬────────────────────────────────────┘
                 │
                 ▼
        ┌──────────────────────────┐
        │  Notion タスクDB         │
        │  「ボール状態」select で │
        │  My/Their/Snoozed/Done  │
        │  /Blocked を可視化       │
        └─────────────┬────────────┘
                      │
                      ▼
   ┌──────────────────────────────────────────────────┐
   │  morning-brief.sh                                │
   │  ・毎朝 07:30、launchd 起動                      │
   │  ・Claude Code CLI + MCP で3システム横断         │
   │    GoogleCalendar / Notion / Slack               │
   │  ・前日ブリーフID `[brief:YYYY-MM-DD]` をSlack   │
   │    検索 → スレッドリプライから完了/除外/         │
   │    新規追加/昇格 を解釈                          │
   └─────────────┬────────────────────────────────────┘
                 │ Incoming Webhook
                 ▼
        ┌──────────────────────────┐
        │  Slack に朝ブリーフ      │
        └──────────┬───────────────┘
                   ▲
                   │ スレッド返信するだけで翌朝反映
                   │
        ┌──────────┴───────────────┐
        │  T-1 完了                 │
        │  T-3 来週でいい           │
        │  + 来週月曜までに資料送付 │
        └──────────────────────────┘

---

このシステムの3つの核となる工夫

工夫1:[brief:YYYY-MM-DD] マーカーで「Slackを状態ストア化」する小発明

朝ブリーフの末尾に必ず [brief:2026-05-19] のような小文字マーカーを1行付けます。

これは人間には不要に見えますが、翌朝、システム自身がSlack検索クエリとして使うためのものです。

仕組み:

  1. システムが翌朝、slack_search_public_and_private で [brief:前日日付] を検索
  2. ヒットしたメッセージの thread を取得 → リプライを LLM に解釈させる
  3. 当日ブリーフから完了タスクを除外したり、新規タスクをToDoファイルに追加したりする

つまり Slack の標準機能(スレッド返信)だけで、ボットコマンドも独自UIも作らずに双方向の対話的タスク操作を実現しています。Slackを「メッセージ配信先」ではなく「状態ストア」として再利用する設計です。

cron的なバッチを、対話的なエージェントに変える小さな発明。

工夫2:「ボール位置」を一級プロパティに昇格、LLMにそれを判定させる

タスクDBに ボール状態 という select プロパティを持たせ、選択肢を 🙋 My Turn / 🤝 Their Turn / ⏸ Snoozed / ✅ Done / 🔴 Blocked の5つに固定しました。

これは GTD(Getting Things Done)の "Waiting For" を一段強くしたもので、「相手のボールは My Turn ビューから物理的に見えなくなる」 ことで、脳内RAMからの追い出しを実現します。

LLMに議事録を渡すとつい「タスクを出してください」と書きがちですが、その結果は人が読み返す前提のリストになります。本システムでは抽出スキーマを以下に固定し、LLMに「ボール位置」を判定させるプロンプト設計にしました:

{
  "task_name": "動詞始まりの命令文",
  "ball_state": "🙋 My Turn | 🤝 Their Turn",
  "counterparty": "参加者から推定した相手の氏名 | null",
  "due_date": "YYYY-MM-DD | null",
  "priority": "🔴 最優先 | 🟡 高 | 🟢 通常",
  "notes": "補足"
}

「事実報告・議論の経過は抽出しない、次に誰かが動く必要があるものだけ」という制約をシステムプロンプトに明文化することで、ダッシュボードがゴミタスクで溢れることを防いでいます。

工夫3:「重要ロジックは自分で書き、横断集約はLLMに任せる」棲み分け

朝ブリーフの生成には Slack / Notion / Google Calendar の3つを横断するアクセスが必要です。

通常ならそれぞれのSDKで認証・API呼び出し・エラーハンドリングを書きますが、本システムは:

  • claude -p コマンドに自然言語プロンプトで指示するだけ
  • MCP(Model Context Protocol)経由で接続済みの3つのツールに、Claudeが自律的に問い合わせる
  • 出力は Slack mrkdwn 形式の本文1つ

shell 200行弱で済んでいます。一方、議事録抽出側(poll_minutes.py)はコスト・品質・並走耐性が重要なので、こちらはあえて Anthropic SDK 直叩きで実装しました。

コア判断軸:重要なロジックは自分で書く。横断的な情報集約は LLM + MCP に任せる。
「LLMが横断アクセスできる時代に、なぜ自分でSDKラッパーを書くのか?」という問いへの答え。

---

実装上の堅牢性(裏側の地味な工夫)

工夫内容
軽量ロック抽出ステータス プロパティを 未処理 → 処理中 に PATCH することで、launchdの並走時の二重起動を回避(厳密なmutexではなく、Notion APIにIf-Match等が無いことを踏まえた実用的な軽量ロック)
dual_property の活用タスクDBの relation 3つ(関連議事録 / 顧客 / Counterparty)を1ページ作成APIに含めるだけで、議事録側・顧客側・担当者側の逆方向プロパティも自動整合
transcriptionブロックの再帰展開AI Meeting Note 固有の transcription ブロックを最大深度6で再帰的に plain text 化、ノイズになる image/embed等はスキップ
指数バックオフリトライNotion API の 429 / 5xx / Connection/Timeout/SSL エラーに対し、最大5回の指数バックオフ+Retry-Afterヘッダ尊重
2.5 req/s スロットルNotion APIレート制限(3 req/s)に対し保守的に 2.5 req/s で動作、本文取得込みで1議事録あたり数秒
自然言語の期限ヒント正規化リプライ中の「今日中」「明日」「来週月曜」「N月N日」を YYYY-MM-DD に正規化、年補完も自動

---

既存ツールとの差別化

Notion AIReclaim / MotionSunsama本システム
議事録 → タスク自動切り出し△(要プロンプト)××◎
ボール位置(My/Their)の一級プロパティ化×××◎
Slackスレッド返信だけで完了/追加×××◎
顧客×担当者の関係ネットワーク×××◎(Notion relation活用)
サーバーレス(クラウド料金ゼロ)n/a××◎(launchd常駐)
カスタマイズ性△××◎(自分のNotion構造に合わせて改造可)

差別化の核は 「議事録→ボール位置タスク化」と「Slack双方向UX」の組み合わせです。

このセットを既存SaaSで実現しようとすると、複数ツールを跨ぐワークフローを自分で組む必要があります。

---

ランニングコスト

項目最小構成推奨構成
サーバー0円(macOS常駐機のlaunchd)0円
Notion既存プランを流用(追加0円)Plus $10/月
Slack既存ワークスペース(追加0円)Pro $7.25/月
Anthropic API(議事録抽出)30〜100円/議事録(Sonnet)同左
Anthropic API(朝ブリーフ)数十円/日同左
月間目安(議事録 20本/月想定)約 1,000〜2,500円約 3,000〜5,000円

サーバーを立てないので固定費は実質ゼロ。コストはLLM呼び出しの従量分のみで、議事録の本数に比例します。

---

ファイル構成

meeting-task-autopilot/
├── README.md
├── .env.sample              # 必須環境変数の雛形(13項目)
├── .gitignore
├── requirements.txt         # anthropic / requests / python-dotenv
├── notion_client.py         # Notion REST薄ラッパ(429/5xx指数バックオフ)
├── prompts.py               # 抽出用 system / user プロンプト
├── poll_minutes.py          # 議事録ポーリング本体(15分間隔)
├── scripts/
│   └── morning-brief.sh     # 朝ブリーフ生成(毎朝 07:30)
└── launchd/
    ├── com.example.morning-brief.plist
    └── com.example.poll-minutes.plist
ファイル行数役割
poll_minutes.py約400議事録DB→タスクDBの自動化エンジン
scripts/morning-brief.sh約180朝ブリーフ生成(Claude Code CLI + MCPに委譲)
prompts.py約45LLM抽出プロンプトを宣言的に管理
notion_client.py約50Notion REST薄ラッパ

---

Notion DB の前提構造

議事録DB(Meeting Notes)

プロパティ型用途
名前title議事録タイトル
作成日date会議日
顧客relation顧客リストへの参照
参加者relation担当者リストへの参照
抽出ステータスselect未処理 / 処理中 / 完了 / エラー
抽出済みタスクrelationタスクDBとの dual_property

タスクDB(Tasks)

プロパティ型用途
タスク名title
ボール状態select🙋 My Turn / 🤝 Their Turn / ⏸ Snoozed / ✅ Done / 🔴 Blocked
Last Ball Movementdate最終更新日(自動セット)
Priorityselect🔴 最優先 / 🟡 高 / 🟢 通常
完了予定日date
関連議事録relation議事録DBとの dual_property
顧客relation顧客リストへの参照
Counterpartyrelation担当者リストへの参照(誰のボールか)

推奨ビュー(タスクDB)

  1. 🙋 Now(My Turn、グループ=顧客)
  2. 🚨 Stale Their Turn(Their Turn かつ Last Ball Movement が7日以上前、グループ=Counterparty)
  3. ⏰ Snooze Queue(Snoozed、ソート=Snooze Until)
  4. 🔴 Blocked(Blocked、グループ=顧客)
  5. 📅 Recently Done(Done で30日以内、ソート=Last Ball Movement 降順)
  6. 📊 Client Board(boardビュー、グループ=ボール状態、Done除外)

---

セットアップ

前提

  • macOS(launchd利用)/ Linux(cron や systemd timer に読み替え可能)
  • Python 3.10+
  • Claude Code CLI インストール済み
  • 以下をMCPとして接続済み: Slack / Notion / Google Calendar
  • Notion Internal Integration を作成し、議事録DB / タスクDB / 担当者DB に接続
  • Anthropic API キー
  • Slack Incoming Webhook URL

インストール

git clone <this-repo>
cd meeting-task-autopilot

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

mkdir -p ~/.meeting-task-autopilot
cp .env.sample ~/.meeting-task-autopilot/.env
vim ~/.meeting-task-autopilot/.env   # 値を埋める

動作確認

# 1件だけdry-runで抽出プロンプト+LLM応答を表示
python poll_minutes.py --dry-run --limit 1

# 1件だけ本実行(タスクDBにページが作られる)
python poll_minutes.py --limit 1

# 朝ブリーフを今すぐ手動実行(Slackに飛ぶ)
bash scripts/morning-brief.sh

launchd 登録

cp launchd/com.example.morning-brief.plist ~/Library/LaunchAgents/
cp launchd/com.example.poll-minutes.plist ~/Library/LaunchAgents/

# パスを自分の環境に合わせて書き換え
vim ~/Library/LaunchAgents/com.example.morning-brief.plist
vim ~/Library/LaunchAgents/com.example.poll-minutes.plist

# 登録
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.morning-brief.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.poll-minutes.plist

---

拡張ロードマップ

  • Snooze自動復帰: 朝6時の launchd で Snooze Until ≤ 今日 のタスクを My Turn に戻す
  • Counterparty 名寄せ: 「◯◯さん」「◯◯」「◯◯チーム」等の表記揺れを fuzzy matching で解決
  • Stale Their Turn の自動リマインド生成: 7日以上動きがない相手ボールに対して、追いリマインドのDM下書きを生成
  • 議事録ポーリング完了の通知: Slackに「📌 ◯月◯日XX定例から、自分Y件・相手Z件登録」を投稿
  • チーム展開: OWNER_LABEL を複数化し、メンバーごとに My Turn ビューを切り替え

---

ライセンス

MIT