meeting-brief について
meeting-briefは、会議録音からレポートを作成して保管し、テキストの代わりに音声で返答するスキルです。プライベートなS3受信箱からの取り込みに対応し、文字起こしの保管、話者確認、音声のプライバシー保護を重視します。
主な機能
- 01録音を文字起こしして会議レポートを作成
- 02話者別に時刻付きで整理
- 03元音声と文字起こしを保管
- 04プライベートS3受信箱から録音を取り込み
- 05音声で返答
活用シーン
- 01録音からアクション項目と決定事項を整理
- 02ブラウザー拡張がアップロードした録音を処理
- 03重要な会議の検証可能な記録を保管
- 04テキストではなく音声で返答
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marks97/ meeting-brief --skill meeting-briefインストール後、Claude Code で/meeting-briefを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
keyterms.txtextension/background.jscapture.main.jscontent.jsmanifest.jsonoffscreen.htmloffscreen.jsoptions.htmloptions.jspopup.htmlpopup.jsREADME.mdui.cssingest/ingest.shingest/presign-lambda/deploy.shindex.mjspackage.jsonscripts/aws-env.shextension-icons.mjsformat-transcript.mjslib.shsay.shshare.shtranscribe.shunshare.sh詳細
会議ブリーフ
録音をアーカイブ済みの会議レポートに変換する機能と、テキストではなく音声で返答する機能を組み合わせたものです。
どちらか片方だけでも使えます。.m4a ファイルのフォルダーに対して /meeting-brief を実行すると、前者を利用できます。「これからは音声で返答して」と指示すると、後者を利用できます。
厳守事項
- ユーザーの音声を公開ホストにアップロードしないでください。 tmpfiles、0x0.st、transfer.sh、簡易トンネルも使用しないでください。録音には機密情報が含まれている可能性があります。たとえば、給与交渉、株式報酬の条件、売上、顧客名などです。許可されている唯一の手段は、プライベートバケット内の事前署名付き S3 URL です。このルールがあるのは、以前に一度違反されたためです。
- 事前署名付き URL のみを使用し、ACL はプライベートにしてください。
--acl public-readの指定、バケットポリシーの変更、名前にpublicまたはassetsを含むバケットの使用は禁止です。 - ユーザーから返信があったら、各クリップを削除してください。 次のメッセージは、ユーザーが音声を聴いたことを示します。そのターンでほかの作業をする前に、前のオブジェクトに対して
unshare.shを実行してください。 - API キーやシークレットを文字起こしに出力しないでください。 スクリプトは環境変数または
.envからキーを読み込み、表示することはありません。
AWS 認証情報はグローバルプロファイルではなく、プロジェクトから取得します
プロジェクトごとに独自の AWS アカウントを設定した .env を保持できるため、認証情報はグローバルプロファイルではなく、プロジェクトから解決されます。scripts/aws-env.sh は作業ディレクトリから上の階層へ進み、使用可能な認証情報を取得できる最初の .env を探します。
変数名は必ずしも標準化されていません。リゾルバーはまず標準形式の AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY を試し、次に短縮形式の AWS_ACCESS_KEY / AWS_ACCESS_SECRET を試します。リージョンのデフォルト値は us-east-1 で、その後、get-bucket-location によってバケットごとに適切な値に修正されます。
音声の保存先とするプライベートバケットを MEETING_BRIEF_BUCKET に設定してください。パブリックアクセスをブロックする必要があります。このスキルはプライベート ACL でアップロードし、共有には事前署名付き URL のみを使います。どのデータも一般公開される状態にはしません。
フロー A:録音からアーカイブ済みレポートを作成する
S=.claude/skills/meeting-brief/scripts
OUT=/tmp/claude/<project>/meeting-<date>
$S/transcribe.sh $OUT *.m4a # parallel, diarised, resumable
$S/format-transcript.mjs $OUT/raw-<x>.json \
--map speaker_0=Alice,speaker_1=Bob # speaker-grouped, timestamped
次に文字起こしを読み、文脈からそれぞれの話者が誰かを特定して、レポートを作成します。
必ず keyterms を渡してください。 keyterms.txt はこのスキルに同梱されており、transcribe.sh が自動的に送信します。これがないと、Scribe v2 は珍しい製品名、会社名、ツール名を似た響きの一般的な単語に誤変換し、その後のあらゆる要約の精度を損ないます。プロジェクトに関する名詞が出てきたら、その都度このファイルに追加してください。
話者分離では、名前ではなく speaker_0、speaker_1 のようなラベルが付与されます。内容をもとに対応関係を判断してから作業を始め、要約では各ラベルが誰を指すのかを明記してください。フォローアップの担当者、翌日に不在の人、個人的な事情など、重要な事実に関して対応関係が少しでも曖昧な場合は、保存する前にユーザーに誰なのか確認してください。また、ユーザーがすぐに訂正できるよう、草稿には「X を speaker A、Y を speaker B としました。逆なら入れ替えてください」のように記載してください。
クォータ(quota_exceeded)
Scribe v2 の料金は、音声 1 秒あたり約 1.1 クレジットです。quota_exceeded が発生しても、そこで諦めないでください。長時間の会議には、開始前の準備、無音時間、長い間など、無音の箇所が含まれていることがほとんどです。ffmpeg を使って無音を取り除き、再試行してください。
ffmpeg -y -i input.m4a \
-af "silenceremove=stop_periods=-1:stop_duration=2:stop_threshold=-40dB" \
-c:a aac -b:a 64k trimmed.m4a
これにより、発話を一切失うことなく再生時間を 20~40% 短縮できます。再送信する前に、再生時間(ffprobe)を確認し、必要なクレジットを再計算してください。アーカイブには必ず元の音声を使い、トリミングしたコピーは使用しないでください。トリミングは文字起こし時にのみ使う処理用のデータであり、原本ではありません。
録音の取り込み(日付の特定、順序付け、アーカイブ優先)
録音は、プロジェクトが受け取る方法で届きます。ワークスペースのルートへのドロップ、~/Downloads へのエクスポート、スマートフォンのファイル、S3 の受信フォルダーへの自動アップロードなどです。ファイル名はたいてい汎用的(meet.m4a、rec.m4a、audio 3.m4a)で、信頼できる日付情報は含まれていません。どこから届いた場合でも、次の 4 つのルールを守ります。
- 要約する前に、必ずアーカイブします。 文字起こしが成功したらすぐに、レポートやアクション項目などを作成する前に、
arch/transcripts/に<audio>と.txtのペアを書き込みます。ユーザーの依頼が「何を決めたの?」だけであっても同じです。ユーザーにアーカイブを頼ませてはいけません。保存できたと思い込まず、コピーとソースのチェックサムを照合して、保存を確認します。 - 日付は録音日です。今日の日付でも、ダウンロード日でもありません。 ファイルの mtime はコピーまたはエクスポートの時刻です。同じ日に新しくドロップされたファイルなら会議の日付と一致しますが、エクスポートまたは再共有されたファイルでは数日ずれていることがあり、複数のファイルが同じセッションでエクスポートされると同じ mtime になります。文字起こし(曜日への言及、「昨日 X をリリースした」といった発言、最近の変更ログ)や、直近の
arch/transcripts/ファイルからの経過日数と照合します。証拠が食い違う場合に限り、ユーザーに確認します。ソースが Apple Voice Memos のオリジナル(20260806 104557.m4a)なら、そのファイル名が録音開始時刻です。共有されたコピーをバイトサイズ、次にチェックサムで照合します。一致すればそれが証明となるため、確認は不要です。 - 連番:
arch/transcripts/にあるrec-NNNの最大番号を確認し、次の整数を使います。番号が抜けている場合にユーザーが訂正できるよう、チャットでその番号を伝えます。エクスポート名にすでに番号が含まれている場合(Mi grabación 202.m4a→rec-202)は、その番号を維持します。番号が不確かだからといって、録音をアーカイブしないままにしてはいけません。 - ドロップボックスは保管場所ではありません。 録音が共有のドロップ先(ワークスペースのルート、Downloads フォルダー、S3 の受信フォルダー)に届いた場合、アーカイブしたコピーのチェックサムを確認したら、ファイルを
arch/transcripts/に移動し、次のドロップと混同しないようにソースを削除します。音声ファイルが 2 つ以上同時に待機している場合は、複数の会議が含まれています。古いものから順に処理するか、どれを処理するか確認し、決して結合してはいけません。
アーカイブの規約
アーカイブは任意の規約です。ワークスペース内のすべてのリポジトリを対象に、ワークスペースのルートに arch/ ツリーを保持します。プロジェクトに既存の arch/README.md があれば、その構成に従います。なければ、次の構成が適切な既定値です。
arch/
README.md
meetings/ YYYY-MM-DD-<counterpart>-<topic>.md
transcripts/ YYYY-MM-DD-rec-<N>.txt + the original .m4a alongside
reports/ YYYY-MM-DD-<topic>.md
一般的なレポートの骨子は、TL;DR、アクション項目、決定事項、覚えておくこと、未解決の質問、完了済み/進行中の内容、トピックです。次の 2 つの規約も守る価値があります。
- em dash は一切使いません。 ハイフン、コロン、ピリオド、括弧を使います。
- すべてのアクション項目に担当者を明記します。 「誰かが対応すべき」はアクション項目ではありません。
- 文字起こし全体をレポートに貼り付けてはいけません。
transcripts/内のファイルへのリンクを記載します。
ファイルサイズから推測するのではなく、ffprobe を使って実際の長さを取得します。
ffprobe -v error -show_entries format=duration -of csv=p=0 file.m4a
Flow C:S3 の受信箱から取り込む(ブラウザー拡張機能)
ここにある extension/ フォルダーは、ウェブ会議(Google
Meet、Zoom web、Teams web)を自動録音し、非公開の S3 受信箱にアップロードするブラウザー拡張機能です。そのため、電話を録音したり、ファイルを手動で渡したりする必要はありません。録音は inbox/<workspace>/<ts>-<title>.webm
と .json サイドカーファイルのペアで保存されます(プラットフォーム、タイトル、会議 URL、参加者、開始/終了時刻、マイク音声を録音したかどうか、contentType)。録音側については extension/README.md、エンドポイントについては
ingest/presign-lambda/ を参照してください。
ユーザーが通話について言及した場合、「受信箱を確認して」と言われたときに限らず、必ず最初に受信箱を確認してください。「さっき通話した」「通話で何を決めたっけ」「直近の会議を文字起こしして」「会議を処理して」などの場合は、ファイルを求める前に、すべてここから始めます。受信箱に該当するものがない場合に限り、プロジェクトのドロップファイル保存場所(Flow A)を確認し、それからユーザーに尋ねます。
I=.claude/skills/meeting-brief/ingest/ingest.sh # set MEETING_INBOX_BUCKET + AWS creds (env or AWS_PROFILE)
$I list # pending clips, newest first: title | start | participants
$I pull inbox/<ws>/<file>.webm /tmp/claude/<project>/meeting-in
クリップはまず時刻で選びます(「さっき」の通話なら終了から1~2時間以内です。startedAt/endedAt はサイドカーファイルに記載されています)。次に、タイトルや参加者がユーザーの言及したものと一致するかを確認します。該当するクリップが2つ以上ある場合は一覧を示して、どれかを尋ねてください。推測してはいけません。
必ず最初に .m4a に変換し、その .m4a に通常の Flow A を実行してください。
ffmpeg -v error -i clip.webm -vn -c:a aac -b:a 64k clip.m4a # then transcribe clip.m4a
これが必須である理由は2つあります。通話中にタブが閉じられたクリップ(サイドカーの reason: tab_closed または stalled)は、適切な終端がない webm(「File ended prematurely」)として届きます。ffmpeg では問題なくデコードできますが、Scribe ではできない場合があります。また、動画を有効にした手動録音は video/webm です。-vn を指定すると動画が除去されます。ユーザーが見返したい場合に限り、元の動画を残してください。サイドカーの capture には録音方法が記載されています。page は自動録音(会議ページ内で通話音声とユーザーのマイク音声を録音)、tab はポップアップからの手動録音です。
振り分け先は、現在のセッションやタグではなく、会議の議題で決めてください。workspace タグは、録音に使ったブラウザーに設定されたデフォルトにすぎません(1つのブラウザーで複数のプロジェクトの通話を録音できます)。そのため、通話に誤ったタグが付いて届くことがあります。会議の内容(参加者、タイトル、文字起こしの話題)から判断してください。どのプロジェクトに保存したか、その理由とともにチャットで伝えたうえで、そのプロジェクトの arch/ に直接アーカイブしてください。
サイドカーファイルから判断できず、誤ったプロジェクトで文字起こししてクレジットを消費したくない場合は、何も変更せずに次のコマンドで引き渡してください:$I retag <key> <workspace>。アーカイブの形式を通常の .m4a に統一するため、アーカイブ前に ffmpeg で .m4a に変換してください。ペアをアーカイブしてチェックサムを検証したら、次のようにします。
$I done inbox/<ws>/<file>.webm # deletes the clip + sidecar from the inbox
受信箱は一時的な置き場所であり、保管場所ではありません(Flow A のドロップされた録音と同じルールです)。arch/transcripts/ 内のコピーを検証した後に限り、各クリップを削除してください。
キャプチャ側:インストール、変更の反映、デバッグ
-
録画の仕組みと、元に戻してはいけないこと。 自動録画はミーティングページ内で行われます(
extension/capture.main.js。RTCPeerConnectionとgetUserMediaをラップするworld: MAINのコンテンツスクリプトです)。自動開始をchrome.tabCaptureに戻さないでください。Chrome では拡張機能をクリックした後にしかタブキャプチャを開始できないため、自動では開始できません。そのため、v0.1/v0.2 では最初の実際の Meet 通話が何も録画されませんでした。タブキャプチャはポップアップから手動で開始する場合にのみ使われ、動画を取得できる唯一の方法でもあります。設計の詳細はextension/README.mdを参照してください。 -
インストールまたは更新: デプロイ時に表示されるインストール用ワンライナー(
curl -fsSL <your-endpoint>/install | sh)を実行し、chrome://extensionsで「パッケージ化されていない拡張機能を読み込む」(初回のみ。Cmd+Shift+Gを押して貼り付けます)か、更新の場合は再読み込みの矢印をクリックします。安定したフォルダーからパッケージ化されていない拡張機能を読み込めば、更新後も同じ ID が維持されるため、オプションに保存されたトークンもそのまま使えます。Downloads から読み込まないでください。 -
拡張機能に変更を反映する:
extension/を編集し、manifest.jsonのversionを更新してから、cd ingest/presign-lambda && BUCKET=<your-inbox-bucket> TOKEN=<current> ./deploy.shを実行します(環境に自分のアカウントの AWS 認証情報が必要です。トークンは Lambda 環境変数にあります。extension/README.mdを参照してください)。これにより、/extensionで提供される zip が再バンドルされます。インストール用の行を再実行して、再読み込みをクリックしてください。完了とする前に、実際の WebRTC 通話でレコーダーの変更を検証してください(Chromium ハーネスについては README に説明があります)。 -
「通話は録画された?」なのに受信トレイが空の場合: コードではなく、エンドポイントを確認してください。
aws cloudwatch get-metric-statistics --region us-east-1 --namespace AWS/ApiGateway \ --metric-name Count --dimensions Name=ApiId,Value=<your-api-id> --statistics Sum --period 300 \ --start-time $(date -u -d '-3 hours' +%FT%TZ) --end-time $(date -u +%FT%TZ)通話中にリクエストがない場合:ブラウザーは処理を試みていません(自動録画がオフ、トークンがない、古いビルドがまだタブキャプチャを使っている、またはページフックが通話を検出できなかったなど)。4xx の場合:トークンまたはエンドポイントが間違っています。署名付き URL は発行されたのに S3 に何もない場合:PUT が失敗しました。ポップアップの「最終アップロード」行にも、ブラウザー側で同じ状況が表示されます。
-
ステータス: 実際の Google Meet 通話で確認済みです(2026-10-01、v0.3.0)。クリックなしで開始し(通話に自分しかいない場合も含む)、マイクをキャプチャし、通話終了時に停止して、アップロードされ、問題なく文字起こしされました。Zoom のウェブ版と Teams のウェブ版も同じレコーダーを使いますが、実環境ではまだ確認されていません。
meet.newの通話ではタイトルはミーティングコードのみです。カレンダーのミーティングではその名前が表示されます。参加者名は可能な範囲で取得されますが、空欄になることがよくあるため、文字起こしから人物を特定してください。
フロー B:音声返信モード
ユーザーはスマートフォンで読むことが多く、長い回答をざっと読むのが難しい場合があります。このモードでは、内容のある返信はすべて音声で読み上げます。
S=.claude/skills/meeting-brief/scripts
# 1. delete the clip from the previous turn; they have replied so they have heard it
$S/unshare.sh "s3://<bucket>/<previous-key>" <project-dir> <previous-local-file>
# 2. write the reply as a SPOKEN script, then
$S/say.sh reply.txt /tmp/claude/<project>/reply-<n>.mp3 1.5
# 3. private link
$S/share.sh /tmp/claude/<project>/reply-<n>.mp3 <project-dir>
その後、URL とともにテキストは最大でも二、三行投稿します。クリップの内容と、ユーザーが対応すべきことを記載してください。音声の文字起こしではありません。このモードの目的は、ユーザーに読ませないことです。
返された s3:// URI とローカルパスをメモしておき、次のターンで削除できるようにします。
デフォルトの速度は 1.5 です。 ElevenLabs 独自の speed 設定は最大 1.2 のため、say.sh は標準速度でレンダリングし、ffmpeg atempo で速度を変更します。0.5~2.0 の範囲外の値では、フィルターを連結して適用します。ピッチは維持されます。
耳で聞きやすい文章を書く
Markdown をそのまま読み上げると聞きづらくなります。say.sh を呼び出す前に変換してください。
- 数字は単語で書きます。「月額四百九十九ドル」とし、「$499/mo」とは書きません。
- ファイルパス、URL、コード識別子は使いません。これらはリンクに添えるテキストメッセージに記載します。
- 箇条書き記号、見出し、太字は使いません。「最初に」「次に」「次のこと」のように言い換えます。
- 頭字語は、文字ごとに読むものならそのように書きます。「M R R」「U X」「U I」などです。
- 要約に影響する既知の文字起こしの誤りがあれば、最初に注意を促します。
- 段落の間には空行を入れます。
say.shはその境界で分割し、previous_text/next_textを使ってつなぐことで、結合部分でも自然な抑揚を保ちます。
デフォルトの音声は、落ち着いた放送風の読み上げです(onwK4e9ZLuTAKqWW03F9)。MEETING_BRIEF_VOICE で変更できます。モデルは MEETING_BRIEF_MODEL を通じて eleven_multilingual_v2 がデフォルトに設定されています。
スクリプト
| スクリプト | 内容 |
|---|---|
scripts/transcribe.sh <outdir> <audio>... | Scribe v2、話者分離、キーターム指定、並列処理、既存の出力はスキップ |
scripts/format-transcript.mjs <raw.json> [--map s0=Name,...] | タイムスタンプ付き、話者ごとにグループ化されたトランスクリプト |
scripts/say.sh <script.txt> <out.mp3> [speed] [voice] | チャンク分割した TTS、結合、速度調整 |
scripts/share.sh <file> [project-dir] [expires] | 非公開の S3 アップロード、署名付き URL(最長 7 日) |
scripts/unshare.sh <s3-uri> [project-dir] [local-file] | オブジェクトを削除し、オプションでローカルファイルも削除 |
scripts/aws-env.sh | プロジェクトごとの認証情報の解決。上記のスクリプトから読み込まれます |
scripts/lib.sh | ElevenLabs キーの読み込み |
scripts/extension-icons.mjs | 拡張機能のツールバーアイコン(待機中+録音中)を再生成 |
ingest/ingest.sh {list,pull,done,retag} | S3 の会議受信トレイ(Flow C) |
ingest/presign-lambda/deploy.sh | エンドポイントを再デプロイし、<your-endpoint>/extension で配信される拡張機能の zip ファイルを再バンドル |
ELEVENLABS_API_KEY は環境変数から読み込まれます。環境変数に設定されていない場合は、ELEVENLABS_ENV_FILE で定義先となるローカルの .env を指定できます。
環境に関する注意事項
&やnohupによるバックグラウンド実行は、ツール呼び出し後も継続しない場合があります。 プロセスを確実に実行し続けるには、Bash ツールのrun_in_backgroundを使用してください。- 署名付き URL は HTTP メソッドごとに署名されます。 GET 用に署名された URL に対して
curl -Iを実行すると 403 が返りますが、これは正しい動作であり、失敗ではありません。範囲を指定した GET で確認してください:curl -r 0-2000 "$URL"。 ffmpegとffprobeが必要です(パッケージマネージャーでインストールしてください)。- 一時ファイルはリポジトリの外(例:
/tmp/claude/<project>/)に置いてください。
使用しない場合
- 短い事実だけの回答。1 文を聞くために、ユーザーに音声クリップを再生させないでください。
- ユーザーがコピーして貼り付ける必要のあるもの(パス、URL、コマンド、ID)。これらはテキストで提示してください。
- コードレビューや差分の確認。音声ではコードを読むのに役立ちません。