Claude Codeで長めの処理を走らせていると、終わったタイミングに気づけないことがよくあります。
通知音を鳴らすだけでもいいんですが、なんとなく「しゃべってくれた方がうれしいな」と思って、処理完了時に音声で読み上げてくれる仕組みを作ってみました。音だけより、声で教えてもらえると可愛いし、内容もわかるしで一石二鳥な感じです。
やったこと
Claude Codeが処理を停止したタイミングで、出力内容を150文字に要約して音声で読み上げてくれるようにしました。
使ったもの:
- Claude Code Hooksの「Stop」イベント – 処理停止時にスクリプトを実行できる機能
- Edge TTS – Microsoftの音声合成エンジン(無料で使える)
- pygame – 音声ファイルの再生用
- Nanamiの声で+60%速度 – 等倍だと遅くて全体把握に時間がかかるので早くした。このへんは完全に個人の好み
全体の流れ

セットアップ
必要なパッケージ
pip install edge-tts pygame
フックスクリプトの作成
以下のPythonスクリプトを適当な場所に保存します。
#!/usr/bin/env python3
import sys
import os
import subprocess
import tempfile
import pygame
# 標準入力から要約テキストを受け取る
summary = sys.stdin.buffer.read().decode("utf-8", errors="replace")
# 150文字に切り詰め
summary = summary[:150]
# 一時ファイルに音声を出力
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp:
audio_path = tmp.name
# Edge TTSで音声合成
subprocess.run([
"edge-tts",
"--voice", "ja-JP-NanamiNeural",
"--rate", "+60%",
"--text", summary,
"--write-media", audio_path
], check=True)
# pygameで再生
pygame.mixer.init()
pygame.mixer.music.load(audio_path)
pygame.mixer.music.play()
# 再生完了まで待機
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
# 後片付け
pygame.mixer.quit()
os.unlink(audio_path)
Claude Code Hooksへの登録
.claude/settings.json の hooks セクションに、Stopイベントとしてスクリプトを登録します。
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "python /path/to/claude_stop_hook.py"
}
]
}
]
}
}
/path/to/claude_stop_hook.py は実際のスクリプトパスに置き換えてください。matcher を空にしておくと、すべてのStop時に発動します。
音声のカスタマイズ
Edge TTSの日本語音声は2種類あります。
ja-JP-NanamiNeural– 女性の声(今回はこれ)ja-JP-KeitaNeural– 男性の声
速度は --rate で調整できます。+60% で1.6倍速、+0% で等倍。自分は等倍だとまどろっこしかったので+60%にしています。
ハマったポイント
標準入力の文字化け(Windows環境)
最初 sys.stdin.read() で読んでいたら、Windows環境で日本語が文字化けしました。sys.stdin.read() はcp932で読み込んでしまうためです。
sys.stdin.buffer.read().decode("utf-8", errors="replace") にしたら解決。Windows + Pythonのstdinあるあるですね。
音声が途中で切れる
pygameで再生した直後にスクリプトが終了すると、音声が途中で切れます。
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
この待機ループが必須です。地味だけど忘れるとまったく聞こえない。
並列セッションでの音声再生
Claude Codeを複数セッション並列で走らせている場合、ほぼ同時にStopフックが発動することがあります。
pygameは内部でSDLを使っていて、各プロセスが独立したmixer.init()を持つので、プロセス間での直接的な競合は起きません。一時ファイルもtempfile.NamedTemporaryFileでユニークな名前が生成されるので衝突しません。
ただし、実際に並列セッションで同時にStopが走ると再生エラーが起きることがあります。Windowsのオーディオデバイスの同時再生数制限が原因のようで、自分の環境でも発生しました。頻繁に並列実行する人は注意してください。
まとめ
Edge TTS + pygame + Claude Code Hooksの組み合わせで、処理完了時にしゃべってもらえるようになりました。
通知音でもよかったんですが、内容を読み上げてくれると「ああ、あの処理終わったんだな」とすぐわかるので便利です。何より声で教えてもらえるのがちょっとうれしい。
仕組み自体はシンプルなので、Claude Code使っている人はぜひ試してみてください。地味に作業効率上がりますよ!


コメント