Claude Code の hooks の matcher に書ける値一覧:イベント別の対象と書き方

Claude Code 公開:

hooks の matcher が何と照合されるかはイベントごとに違います。完全一致・正規表現・ワイルドカードの判定ルール、matcher を無視するイベント、MCP ツールの指定方法を一覧で整理します。

検証日 2026年9月15日 仕様変更が早い分野です。最新の公式ドキュメントも併せてご確認ください。
目次
  1. 値の書き方で判定方法が変わる
  2. イベント別:matcher は何と照合されるか
  3. matcher を書いても無視されるイベント
  4. 書き方の実例
  5. MCP ツールを指定する
  6. matcher で足りないときは if を使う
  7. まとめ

settings.json に hooks を書くとき、matcher に何を書けばよいのか迷います。Bash のようなツール名が書けることは分かっても、正規表現が使えるのか、SessionStart では何と照合されるのかは、書いてみないと分かりません。

結論として、matcherイベントごとに照合対象が違い、値の書き方によって完全一致か正規表現かが自動的に切り替わります。この記事では、その判定ルールとイベント別の対象を一覧にします。

KEY POINT

この記事で分かること

  • 完全一致・正規表現・ワイルドカードがどう切り替わるかの判定ルール
  • イベントごとに matcher が何と照合されるかの一覧
  • MCP ツールの指定方法と、matcher が無視されるイベント

値の書き方で判定方法が変わる

matcher は 3 つのモードのどれかで評価されます。どのモードになるかは、書いた文字で自動的に決まります

書いた値評価
"*"""、または省略すべてに一致そのイベントのたびに実行
英数字・_-・空白・,| だけ完全一致(複数可)BashEdit|WriteEdit, Write
それ以外の文字を 1 つでも含むJavaScript の正規表現(アンカーなし)^Notebookmcp__memory__.*

ここが最も間違えやすい点です。Bash は完全一致ですが、^Bash$ にはアンカー記号が含まれるため正規表現として扱われます。どちらも同じ結果になりますが、意識せずに .* を含む名前を書くと、意図せず正規表現になります。

正規表現は RegExp.prototype.test() で評価されます。つまり アンカーなしの部分一致 です。Edit を正規表現として評価させると NotebookEdit にも一致します。完全一致させたいなら ^Edit$ と書いてください。

大文字小文字は区別される

matcher は大文字小文字を区別します。bash と書いても Bash ツールには一致しません。ツール名は公式ドキュメントの綴りをそのまま使ってください。

バージョンによる違いも 2 点あります。

  • ハイフンを含む名前の完全一致は Claude Code v2.1.195 以降が必要です。それより前のバージョンでは code-reviewer のような名前はアンカーなしの正規表現として評価されるため、^code-reviewer$ と書きます
  • カンマ区切りの列挙(Edit, Write)は v2.1.191 以降が必要です

イベント別:matcher は何と照合されるか

matcher はツール名専用ではありません。イベントごとに照合対象が変わります。

イベント照合対象値の例
PreToolUse / PostToolUse / PostToolUseFailure / PermissionRequest / PermissionDeniedツール名BashEdit|Writemcp__.*
SessionStartセッション開始の理由startupresumeclearcompactfork
Setupセットアップを起動した CLI フラグinitmaintenance
SessionEndセッション終了の理由clearresumelogoutprompt_input_exitother
Notification通知の種類permission_promptidle_promptauth_success など
SubagentStart / SubagentStopエージェントの種類general-purposeExplorePlan、独自の名前
PreCompact / PostCompact圧縮のきっかけmanualauto
PreModelSwitch / PostModelSwitch正規化されたモデル名claude-opus-5
ConfigChange設定のソースuser_settingsproject_settingslocal_settingspolicy_settingsskills
DirectoryAddedディレクトリの追加方法slash_commandregister_repo_root
FileChanged監視するファイル名(リテラル).envrc|.env
StopFailureエラーの種類rate_limitoverloadedauthentication_failedserver_error など
InstructionsLoaded読み込みの理由session_startnested_traversalpath_glob_matchincludecompact
UserPromptExpansionコマンド名自分のスキル名・コマンド名
Elicitation / ElicitationResultMCP サーバー名設定済みの MCP サーバー名

InstructionsLoaded を使った実例は InstructionsLoaded フックの使い方 にまとめています。

matcher を書いても無視されるイベント

次のイベントは matcher に対応していません。書いても エラーにはならず、黙って無視されます

  • UserPromptSubmit
  • PostToolBatch
  • Stop
  • CwdChanged
  • TeammateIdle
  • TaskCreated
  • TaskCompleted
  • WorktreeCreate
  • WorktreeRemove
  • MessageDisplay

「フックが絞り込まれずに毎回動く」と感じたら、まずこの一覧を確認してください。エラーが出ないため気づきにくい種類の設定ミスです。

書き方の実例

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check-bash.sh"
          }
        ]
      },
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/lint-check.sh"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "matcher": "startup|resume",
        "hooks": [
          {
            "type": "command",
            "command": "echo started >> ~/session.log"
          }
        ]
      }
    ]
  }
}

ツール名の正確な綴りは公式のツールリファレンスで確認してください。よく使うものは BashReadEditWriteGlobGrepWebFetchWebSearchNotebookEditTodoWriteAgentSkill です。

MCP ツールを指定する

MCP サーバーのツールは mcp__<サーバー名>__<ツール名> という命名になります。

やりたいことmatcher
あるサーバーのツールすべてmcp__memory__.*
ハイフンを含むサーバー名mcp__brave-search__.*
サーバー横断で特定のツール名mcp__.*__write.*
プラグイン同梱のサーバーmcp__plugin_my-plugin_db__.*

末尾の .* を忘れない

mcp__memory とだけ書くと完全一致として扱われ、mcp__memory__create_entities には一致しません。サーバー配下のツールをまとめて対象にするなら mcp__memory__.* のように .* を付けてください。

matcher で足りないときは if を使う

matcher はツール名までしか絞れません。「TypeScript ファイルの編集だけ」のようにパラメータで絞りたい場合は、フック側の if フィールドを使います。

{
  "matcher": "Edit",
  "hooks": [
    {
      "type": "command",
      "if": "Edit(*.ts)",
      "command": "./check-typescript.sh"
    }
  ]
}

if は permissions と同じルール記法で書きます(permissions を設計する)。ツールのイベントでのみ評価され、それ以外のイベントでは無視されます。

用語解説

アンカーなしの部分一致: 正規表現が文字列のどこかに一致すれば成立する評価方法です。先頭と末尾を固定したい場合は ^$ を明示します。

フック本体の書き方と終了コードの扱いは hooks で lint と format を自動実行するhooks の終了コードの意味 を参照してください。

まとめ

  • matcher は書いた文字で完全一致・正規表現・全一致が自動的に切り替わる
  • 記号を含むと正規表現になり、アンカーなしの部分一致で評価される
  • 大文字小文字は区別される。ハイフンの完全一致は v2.1.195 以降、カンマ区切りは v2.1.191 以降
  • 照合対象はイベントごとに違う。ツール名とは限らない
  • StopUserPromptSubmit など 10 個のイベントは matcher を黙って無視する
  • MCP ツールをまとめて対象にするなら mcp__<サーバー名>__.* と末尾に .* を付ける

よくある質問

matcher を省略するとどうなりますか?
すべてに一致します。省略、空文字 `""`、`"*"` の 3 つは同じ意味で、そのイベントが起きるたびにフックが実行されます。
matcher に正規表現は書けますか?
書けます。ただし常に正規表現として扱われるわけではありません。英数字・アンダースコア・ハイフン・空白・カンマ・縦棒だけで構成された値は完全一致として扱われ、それ以外の文字が 1 つでも入ると正規表現になります。
matcher は大文字小文字を区別しますか?
区別します。`bash` と書いても `Bash` ツールには一致しません。
SessionStart のようなツール以外のイベントで matcher は何に一致しますか?
イベントごとに照合対象が異なります。SessionStart なら開始理由(startup、resume、clear など)、PreCompact なら圧縮のきっかけ(manual、auto)です。

参考にした一次情報

この記事は公式ドキュメントを基に AI が下書きを作成し、運営者が内容を確認して公開しています。誤りを見つけた場合は お問い合わせからお知らせください。