Claude Codeで作業終了時VOICEVOXの方法で呼んでもらう方法〜WSL版〜
はじめに
以下の記事でClaude Codeのhooks機能を使って、Claude Codeで「作業終了時」もしくは「人間の指示待ち時」にVOICEVOXを使って音声を生成し、それを再生して音声で呼びかけてもらうというテクニックが公開されています。
元記事はMac版で、Windows(WSL)ではそのままでは動かなかったのでメモがてら手順をまとめておきます。
前提
- WSL環境セットアップ済み
- VOICEVOX(無料の音声合成ソフト)インストール済み
- Claude Code(AnthropicのAIコーディングアシスタント)インストール済み
手順
Claude Codeにhooksの設定
Claude Codeのsettings.jsonは以下の場所に作成できます。格納する場所によって設定が適用される範囲が違うので、自分に適した場所に設定をいれます。
-
~/.claude/settings.json- User settings -
.claude/settings.json- Project settings -
.claude/settings.local.json- Local project settings (not committed)
私はClaude Codeを使うときいつも音声呼び出ししてほしいのでUser Settingsにしています。
ちなみに公式ドキュメントにあるようにClaude Codeを呼び出してから、/hooksでも設定できますが、これだと「作業終了時」もしくは「人間の指示待ち時」をそれぞれ別で設定しないといけない(ファイルの内容コピペでできない)のでファイルを直接編集しました。
settings.jsonに以下の内容を設定します。
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash -c 'read -r j; txt=\"クロードコードが呼んでいます。\"; f=$(mktemp /tmp/vv_XXXXXX.wav); curl -s -X POST \"http://127.0.0.1:50021/audio_query?speaker=14\" --get --data-urlencode text=\"${txt}\" | curl -s -X POST -H \"Content-Type: application/json\" -d @- \"http://127.0.0.1:50021/synthesis?speaker=14\" -o \"$f\"; cp \"$f\" /mnt/c/temp/claude_voice.wav; cmd.exe /c \"start /min wmplayer C:\\\\temp\\\\claude_voice.wav\"; sleep 3; rm \"$f\" /mnt/c/temp/claude_voice.wav'"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash -c 'read -r j; txt=\"すべてのタスクが終了しました。\"; f=$(mktemp /tmp/vv_XXXXXX.wav); curl -s -X POST \"http://127.0.0.1:50021/audio_query?speaker=14\" --get --data-urlencode text=\"${txt}\" | curl -s -X POST -H \"Content-Type: application/json\" -d @- \"http://127.0.0.1:50021/synthesis?speaker=14\" -o \"$f\"; cp \"$f\" /mnt/c/temp/claude_voice.wav; cmd.exe /c \"start /min wmplayer C:\\\\temp\\\\claude_voice.wav\"; sleep 3; rm \"$f\" /mnt/c/temp/claude_voice.wav'"
}
]
}
]
}
}
流れは大まかに以下です。
- WSL側でVOICEVOXのAPIを利用して音声データ(WAV)を作成 →
/tmp/に保存 -
/tmp/の一時ファイルを/mnt/c/temp/にコピー - /mnt/cはWindowsのC:のマウントなのでWindows側の
C:\temp\にコピーしたのと同じになる - Windowsのwmplayer(Windows Media Player)でそのファイルを最小化して再生開始
VOICEVOXの起動
Windows側でVOICEVOXのアプリを起動しておきます。
WSLのMirroringモードの設定
以下の記事などを参考にWSLにMirroringモードを設定します。
Claude CodeはWSLで起動していますが、VOICEVOXはWindowsで起動しています。Windows側のVOICEVOXにアクセスするためにMirroringモードを設定します。
Mirroringモードが設定できたら、WSLから以下のコマンドを実行しVOICEVOXにアクセスできるか確認しておきます。
curl http://localhost:50021/speakers
正常にアクセスできると、Speaker一覧が取得できます。ちなみに、この値を使ってさきほどのsettings.jsonでspeaker=14の部分を変えると自分の好きな声質に変えられます。speaker=14は冥鳴ひまりの声です。他にもずんだもん(speaker=3)やめたん(speaker=2)などさまざまな声質が選べます。
2025/7/7時点ではSpeaker一覧は以下の内容でした。
Speaker一覧
[
{
"supported_features": {"permitted_synthesis_morphing": "SELF_ONLY"},
"name": "四国めたん",
"speaker_uuid": "7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff",
"styles": [
{"name": "ノーマル", "id": 2, "type": "talk"},
{"name": "あまあま", "id": 0, "type": "talk"},
{"name": "ツンツン", "id": 6, "type": "talk"},
{"name": "セクシー", "id": 4, "type": "talk"},
{"name": "ささやき", "id": 36, "type": "talk"},
{"name": "ヒソヒソ", "id": 37, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "SELF_ONLY"},
"name": "ずんだもん",
"speaker_uuid": "388f246b-8c41-4ac1-8e2d-5d79f3ff56d9",
"styles": [
{"name": "ノーマル", "id": 3, "type": "talk"},
{"name": "あまあま", "id": 1, "type": "talk"},
{"name": "ツンツン", "id": 7, "type": "talk"},
{"name": "セクシー", "id": 5, "type": "talk"},
{"name": "ささやき", "id": 22, "type": "talk"},
{"name": "ヒソヒソ", "id": 38, "type": "talk"},
{"name": "ヘロヘロ", "id": 75, "type": "talk"},
{"name": "なみだめ", "id": 76, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "春日部つむぎ",
"speaker_uuid": "35b2c544-660e-401e-b503-0e14c635303a",
"styles": [{"name": "ノーマル", "id": 8, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "雨晴はう",
"speaker_uuid": "3474ee95-c274-47f9-aa1a-8322163d96f1",
"styles": [{"name": "ノーマル", "id": 10, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "波音リツ",
"speaker_uuid": "b1a81618-b27b-40d2-b0ea-27a9ad408c4b",
"styles": [{"name": "ノーマル", "id": 9, "type": "talk"}, {"name": "クイーン", "id": 65, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "玄野武宏",
"speaker_uuid": "c30dc15a-0992-4f8d-8bb8-ad3b314e6a6f",
"styles": [
{"name": "ノーマル", "id": 11, "type": "talk"},
{"name": "喜び", "id": 39, "type": "talk"},
{"name": "ツンギレ", "id": 40, "type": "talk"},
{"name": "悲しみ", "id": 41, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "白上虎太郎",
"speaker_uuid": "e5020595-5c5d-4e87-b849-270a518d0dcf",
"styles": [
{"name": "ふつう", "id": 12, "type": "talk"},
{"name": "わーい", "id": 32, "type": "talk"},
{"name": "びくびく", "id": 33, "type": "talk"},
{"name": "おこ", "id": 34, "type": "talk"},
{"name": "びえーん", "id": 35, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "青山龍星",
"speaker_uuid": "4f51116a-d9ee-4516-925d-21f183e2afad",
"styles": [
{"name": "ノーマル", "id": 13, "type": "talk"},
{"name": "熱血", "id": 81, "type": "talk"},
{"name": "不機嫌", "id": 82, "type": "talk"},
{"name": "喜び", "id": 83, "type": "talk"},
{"name": "しっとり", "id": 84, "type": "talk"},
{"name": "かなしみ", "id": 85, "type": "talk"},
{"name": "囁き", "id": 86, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "冥鳴ひまり",
"speaker_uuid": "8eaad775-3119-417e-8cf4-2a10bfd592c8",
"styles": [{"name": "ノーマル", "id": 14, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "SELF_ONLY"},
"name": "九州そら",
"speaker_uuid": "481fb609-6446-4870-9f46-90c4dd623403",
"styles": [
{"name": "ノーマル", "id": 16, "type": "talk"},
{"name": "あまあま", "id": 15, "type": "talk"},
{"name": "ツンツン", "id": 18, "type": "talk"},
{"name": "セクシー", "id": 17, "type": "talk"},
{"name": "ささやき", "id": 19, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "SELF_ONLY"},
"name": "もち子さん",
"speaker_uuid": "9f3ee141-26ad-437e-97bd-d22298d02ad2",
"styles": [
{"name": "ノーマル", "id": 20, "type": "talk"},
{"name": "セクシー/あん子", "id": 66, "type": "talk"},
{"name": "泣き", "id": 77, "type": "talk"},
{"name": "怒り", "id": 78, "type": "talk"},
{"name": "喜び", "id": 79, "type": "talk"},
{"name": "のんびり", "id": 80, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "剣崎雌雄",
"speaker_uuid": "1a17ca16-7ee5-4ea5-b191-2f02ace24d21",
"styles": [{"name": "ノーマル", "id": 21, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "WhiteCUL",
"speaker_uuid": "67d5d8da-acd7-4207-bb10-b5542d3a663b",
"styles": [
{"name": "ノーマル", "id": 23, "type": "talk"},
{"name": "たのしい", "id": 24, "type": "talk"},
{"name": "かなしい", "id": 25, "type": "talk"},
{"name": "びえーん", "id": 26, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "後鬼",
"speaker_uuid": "0f56c2f2-644c-49c9-8989-94e11f7129d0",
"styles": [{"name": "人間ver.", "id": 27, "type": "talk"}, {"name": "ぬいぐるみver.", "id": 28, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "No.7",
"speaker_uuid": "044830d2-f23b-44d6-ac0d-b5d733caa900",
"styles": [
{"name": "ノーマル", "id": 29, "type": "talk"},
{"name": "アナウンス", "id": 30, "type": "talk"},
{"name": "読み聞かせ", "id": 31, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "ちび式じい",
"speaker_uuid": "468b8e94-9da4-4f7a-8715-a22a48844f9e",
"styles": [{"name": "ノーマル", "id": 42, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "櫻歌ミコ",
"speaker_uuid": "0693554c-338e-4790-8982-b9c6d476dc69",
"styles": [
{"name": "ノーマル", "id": 43, "type": "talk"},
{"name": "第二形態", "id": 44, "type": "talk"},
{"name": "ロリ", "id": 45, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "小夜/SAYO",
"speaker_uuid": "a8cc6d22-aad0-4ab8-bf1e-2f843924164a",
"styles": [{"name": "ノーマル", "id": 46, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "ナースロボ_タイプT",
"speaker_uuid": "882a636f-3bac-431a-966d-c5e6bba9f949",
"styles": [
{"name": "ノーマル", "id": 47, "type": "talk"},
{"name": "楽々", "id": 48, "type": "talk"},
{"name": "恐怖", "id": 49, "type": "talk"},
{"name": "内緒話", "id": 50, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "†聖騎士 紅桜†",
"speaker_uuid": "471e39d2-fb11-4c8c-8d89-4b322d2498e0",
"styles": [{"name": "ノーマル", "id": 51, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "雀松朱司",
"speaker_uuid": "0acebdee-a4a5-4e12-a695-e19609728e30",
"styles": [{"name": "ノーマル", "id": 52, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "麒ヶ島宗麟",
"speaker_uuid": "7d1e7ba7-f957-40e5-a3fc-da49f769ab65",
"styles": [{"name": "ノーマル", "id": 53, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "春歌ナナ",
"speaker_uuid": "ba5d2428-f7e0-4c20-ac41-9dd56e9178b4",
"styles": [{"name": "ノーマル", "id": 54, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "猫使アル",
"speaker_uuid": "00a5c10c-d3bd-459f-83fd-43180b521a44",
"styles": [
{"name": "ノーマル", "id": 55, "type": "talk"},
{"name": "おちつき", "id": 56, "type": "talk"},
{"name": "うきうき", "id": 57, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "猫使ビィ",
"speaker_uuid": "c20a2254-0349-4470-9fc8-e5c0f8cf3404",
"styles": [
{"name": "ノーマル", "id": 58, "type": "talk"},
{"name": "おちつき", "id": 59, "type": "talk"},
{"name": "人見知り", "id": 60, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "SELF_ONLY"},
"name": "中国うさぎ",
"speaker_uuid": "1f18ffc3-47ea-4ce0-9829-0576d03a7ec8",
"styles": [
{"name": "ノーマル", "id": 61, "type": "talk"},
{"name": "おどろき", "id": 62, "type": "talk"},
{"name": "こわがり", "id": 63, "type": "talk"},
{"name": "へろへろ", "id": 64, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "栗田まろん",
"speaker_uuid": "04dbd989-32d0-40b4-9e71-17c920f2a8a9",
"styles": [{"name": "ノーマル", "id": 67, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "あいえるたん",
"speaker_uuid": "dda44ade-5f9c-4a3a-9d2c-2a976c7476d9",
"styles": [{"name": "ノーマル", "id": 68, "type": "talk"}],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "満別花丸",
"speaker_uuid": "287aa49f-e56b-4530-a469-855776c84a8d",
"styles": [
{"name": "ノーマル", "id": 69, "type": "talk"},
{"name": "元気", "id": 70, "type": "talk"},
{"name": "ささやき", "id": 71, "type": "talk"},
{"name": "ぶりっ子", "id": 72, "type": "talk"},
{"name": "ボーイ", "id": 73, "type": "talk"},
],
"version": "0.15.3",
},
{
"supported_features": {"permitted_synthesis_morphing": "ALL"},
"name": "琴詠ニア",
"speaker_uuid": "97a4af4b-086e-4efd-b125-7ae2da85e697",
"styles": [{"name": "ノーマル", "id": 74, "type": "talk"}],
"version": "0.15.3",
},
]
Windowsとの連携フォルダの作成
settings.jsonでは生成された音声ファイルを/mnt/c/tempに格納しています。tempフォルダは初期状態だとないので作成しておきます。
おわりに
手順は以上となります。
Claude Codeを利用して、「こんにちは」など適当にチャットするとWindows Media Playerが起動し、音声再生されるはずです。毎回Windows Media Playerが起動するのは少しわずらわしいので、本当はGUIなしで再生されるようにしたかったのですが、やりかたわからずです。
わかる方、教えていただけると嬉しいです。
以上です。ありがとうございました。
Discussion