Windows TerminalでClaude Code実行時に通知センター表示

Claude Codeの処理が終わったタイミングでWindowsへ通知する設定をしたときの覚書。
Geminiと対話。

環境: Windows 11 Pro 25H2, PowerShell 7.6.3


1. BurntToastをインストール

Windowsターミナルがアクティブ状態でも通知してほしいので、BurntToastをインストールする。
参考: Windos/BurntToast: Module for creating and displaying Toast Notifications on Microsoft Windows 10.
> Install-Module -Name BurntToast -Scope CurrentUser -Force

通知テストのコマンド。
> New-BurntToastNotification -Text '処理が完了しました。成果物を確認してください。'

画像を表示しない通知。
> Submit-BTNotification -Content (New-BTContent -Visual (New-BTVisual -BindingGeneric (New-BTBinding -Children (New-BTText -Content '処理完了'), (New-BTText -Content '画像表示領域のないクリーンな通知です。'))))


2.Claude CodeのHooks(フック)機能を使う

ユーザーの確認を待っているパターンと、タスクが完了したパターンで通知を分ける。

Claude CodeはWindowsの標準的なシェルインターフェースで立ち上げるので、通知テストするときはcmd.exeで動作確認する。

cmdで動作確認
> pwsh.exe -NoProfile -Command "New-BurntToastNotification -Text '💡 cmdからのテスト', 'PowerShell 7経由での通知です。'"


Claude Codeの設定ファイル(~/.claude/settings.json)を編集する。
Gemini先生から言われた下記内容を追記。

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "pwsh.exe -NoProfile -Command \"New-BurntToastNotification -Text '💡 Claude Code(要入力)', 'ユーザーの入力・確認を待っています。'\""
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "pwsh.exe -NoProfile -Command \"New-BurntToastNotification -Text '✅ Claude Code(完了)', 'リクエストされたタスクの処理が完了しました。'\""
          }
        ]
      }
    ]
  }
}



3. 通知センターへの送信を外部スクリプトにする

いろいろ修正してたらsettings.jsonのcommandがわけがわからないことになったので、通知文の作成は外部スクリプトにまとめることにした。

~/.claude/claude-notify.ps1として作成。

# ===================================================================
# Claude Code 通知連携スクリプト (BurntToast 版)
#
# 【BurntToast とは?】
# PowerShell から Windows 10/11 の通知センター(トースト通知)を
# 簡単に呼び出すための、非常に軽量で人気のある外部モジュールです。
# 複雑な Windows API(XML構造)を直接書くことなく、テキストや音、
# 画像付きのリッチな通知を安全に送出できます。
#
# 【インストールの手順】
# このスクリプトを動かす前に、PowerShell 7 (pwsh) で以下のコマンドを
# 1度だけ実行して、モジュールをインストールしておいてください。
#
#   Install-Module -Name BurntToast -Scope CurrentUser -Force
#
# -------------------------------------------------------------------
# 【コマンドプロンプト (cmd) で動作確認を行う理由と手順】
#
# ◆ なぜ PowerShell 7 上ではなく「cmd」でテストするのか?
# Claude Code は、バックグラウンドで独立したプロセス(環境)としてこの
# スクリプトを呼び出します。その際、PowerShell 7 の環境から直接実行する
# のではなく、Windows 標準のシェルインターフェース(cmd.exe と同等の
# 引数解析)を経由して呼び出される仕様になっています。
#
# そのため、PowerShell 7 の画面上だけでテストして動いたとしても、
# 「クォーテーションの解釈の違い」によって Claude Code から呼び出した
# 瞬間にエラーになるケースがあります。Claude Code の実行環境を正確に
# シミュレートし、本番での動作を100%保証するために「cmd」でのテストが必要です。
#
# ◆ cmd での動作確認テスト手順
# 1. Windows ターミナル等で「コマンドプロンプト (cmd)」を起動します。
# 2. 以下のコマンドを丸ごとコピー&ペーストして Enter キーを押します。
#
#   pwsh.exe -NoProfile -File %USERPROFILE%/.claude/claude-notify.ps1 -Type "Notification"
#
# 3. 画面右下に「💡 Claude Code(要入力)」の通知が出現すれば大成功です。
# ===================================================================

# スクリプト外部から受け取る引数(パラメーター)を定義します
param (
    [Parameter(Mandatory = $true)]
    [ValidateSet("Start", "Notification", "Stop", "Error")]
    [string]$Type
)

# -NoProfile 実行対策として、BurntToast モジュールを明示的に読み込みます
Import-Module BurntToast -ErrorAction SilentlyContinue

# 1. どんな状況でも絶対にエラーにならない方法でフォルダ名を取得します
# $PWD (PowerShellの自動変数) から安全にパスを文字列として抽出し、最後のフォルダ名を切り出します
$RepoName = "Project"
try
{
    if ($PWD)
    {
        $RepoName = Split-Path $PWD.ProviderPath -Leaf
    } elseif ($env:PWD)
    {
        $RepoName = Split-Path $env:PWD -Leaf
    } else
    {
        $RepoName = Split-Path ([System.IO.Directory]::GetCurrentDirectory()) -Leaf
    }
} catch
{
    # 万が一すべて取得に失敗した場合は、クラッシュを避けるため既定の文字を入れます
    $RepoName = "ClaudeCode"
}

# 2. 通知のタイプ(引数)に応じて、表示するタイトルと本文を切り替えます
switch ($Type)
{
    "Start"
    {
        $Title  = "🚀 Claude Code(開始)"
        $Body   = "[${RepoName}] 処理を開始しました。"
    }
    "Notification"
    {
        $Title  = "💡 Claude Code(要入力)"
        $Body   = "[${RepoName}] コマンドの実行確認、または入力を待っています。"
    }
    "Stop"
    {
        $Title  = "✅ Claude Code(完了)"
        $Body   = "[${RepoName}] リクエストされたタスクの処理が完了しました。"
    }
    "Error"
    {
        $Title  = "⚠️ Claude Code(エラー)"
        $Body   = "[${RepoName}] 処理中にエラーが発生しました。"
    }
}

# 3. BurntToast の関数を組み合わせて、画像なし(テキストのみ)のトースト構造を組み立てます
$TextLines = @(
    (New-BTText -Content $Title),
    (New-BTText -Content $Body)
)

$ToastContent = New-BTContent -Visual (
    New-BTVisual -BindingGeneric (
        New-BTBinding -Children $TextLines
    )
)

# 4. 組み立てたコンテンツを Windows の通知センターへ送信
Submit-BTNotification -Content $ToastContent

外部スクリプトを起動するように「~/.claude/settings.json」を修正。

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "pwsh.exe -File ~/.claude/claude-notify.ps1 -Type Notification"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "pwsh.exe -File ~/.claude/claude-notify.ps1 -Type Stop"
          }
        ]
      }
    ]
  }
}


 Claude Codeを再起動して動作確認する。


▼ 参考記事