メインコンテンツへスキップ

Claude CodeのMCPとhooksの使い方!外部ツール連携と自動化でAIエージェントを強化する

    「AIに頼めるのはパソコンの中の作業だけ。Notionのメモまでは手が届かない」
    「CLAUDE.mdに『このファイルは触らないで』と書いたのに、うっかり触られないか心配」

    前回は、サブエージェントで「リサーチ担当」と「辛口レビュー担当」という2人の専門担当を作りました(前回の記事はこちら:[第3回のリンク])。ここまでで、僕たちの「note記事づくりエージェント」はかなり頼れる存在になっています。

    ただ、使い込むほど2つの壁にぶつかります。1つは、AIがパソコンの外のサービスに手を出せないこと。もう1つは、ルールを書いても100%守られるとは限らないことです。

    第4回では、この2つの壁をMCPとhooksで越えていきます。この記事を読むと、次のことができるようになります。

    • MCPでClaude CodeとNotionをつなぎ、会話だけでNotionにメモを追加できる

    • MCPの設定を確認・削除し、安全に使うコツがわかる

    • hooksで「Claudeが入力を待っているときにWindowsやMacに通知を出す」仕掛けを作れる

    • hooksで「大事なファイルの編集を必ずブロックする」仕掛けを作れる

    なお、この記事は2026年9月時点の情報です。Claude Codeは更新が速いので、最新の仕様は公式ドキュメント(code.claude.com/docs)もあわせて確認してください。

    Claude CodeのMCPとhooksで何が変わるか

    最初に、MCPとhooksがそれぞれ何者なのかを押さえておきましょう。結論からいうと、MCPは「AIに外の道具を持たせる差し込み口」、hooksは「決まったタイミングで必ず動く仕掛け」です。MCPで行動範囲を広げ、hooksで確実さを足す。この組み合わせで、AIエージェントが一気に実用レベルに近づきます。

    MCPはAIに外の道具を持たせる差し込み口

    MCPは「Model Context Protocol(モデル・コンテキスト・プロトコル)」の略で、AIを外部のサービスとつなぐための共通の規格です。規格というのは「こういう形でやり取りしましょう」という決まりごとのことですね。

    イメージしやすいのは、パソコンのUSBです。USBという共通の差し込み口があるおかげで、マウスもキーボードもUSBメモリも、メーカーを気にせず同じ穴に挿すだけで使えます。MCPも同じで、Claude Code側に「MCPという共通の差し込み口」があるので、MCPに対応したサービスなら同じ手順でつなげられます。

    MCPでつなげる相手の例は、次のようなものです。

    • Notion:メモやデータベースを管理するサービス

    • GitHub:プログラムの保管・共有サービス

    • データベース:大量のデータを整理してためておく仕組み

    • Sentry:アプリのエラーを記録するサービス

    つないだサービスのことを、Claude Codeでは「MCPサーバー」と呼びます。「サーバー」と聞くと身構えてしまうかもしれませんが、ここでは「Claudeに道具を貸してくれる相手」くらいの理解で大丈夫です。

    公式ドキュメントでは、MCPを足すべきタイミングの目安として「ブラウザからデータをコピーして貼り付け続けているとき」が挙げられています。たとえば、Notionに書いた記事ネタをいちいちコピーしてClaudeに貼り付けているなら、それはMCPでつなぐ合図です。

    hooksは決まったタイミングで必ず動く仕掛け

    hooks(フック)は、「このタイミングが来たら、必ずこの処理を動かす」という仕掛けです。たとえば「Claudeがファイルを編集しようとした瞬間」や「Claudeが通知を出した瞬間」などのタイミングに、自分で決めた命令を結びつけられます。

    家電でたとえるなら、タイマーやセンサーライトに近いです。センサーライトは、人が通るたびに「つけようかな、どうしようかな」と迷ったりしません。人が来たら必ず光ります。hooksも同じで、決めたタイミングが来ればAIの判断を通さずに必ず動きます。

    ここで大事なのが、第2回で扱ったCLAUDE.mdとの違いです。公式ドキュメントでは、CLAUDE.mdに「.envファイルを触らないで」と書くのはお願いであり、hookで止めるのは強制だ、という考え方が示されています。

    • CLAUDE.md:Claudeが読んで「守ろう」と努力するルール。状況によっては守られないこともある

    • hooks:Claudeの判断とは関係なく、仕組みとして必ず実行される

    第2回で「CLAUDE.mdはお願いであって強制ではない。強制したいことは第4回で扱う」と予告していたのは、このhooksのことでした。「絶対に守ってほしいこと」はhooksに任せる、と覚えておくと使い分けに迷いません。

    Claude CodeでMCPサーバーをつなぐ方法

    ここからは、実際にMCPサーバーをつないでいきます。手順は大きく「ターミナルでコマンドを1行打つ」「Claude Codeの中で認証する」の2段階です。まずはコマンドの基本の形を確認してから、Notionで実際に試してみましょう。

    MCPサーバーを追加するコマンドの基本の形

    MCPサーバーは、ターミナル(文字で命令する画面)で「claude mcp add」から始まるコマンドを打って追加します。つなぎ方には主に2つの形式があります。

    1つ目はHTTP形式です。HTTPはWebサイトを見るときにも使われている通信のルールで、インターネット経由でサービスとつなぐ形式だと考えてください。公式ドキュメントでも、この形式がおすすめとされています。

    claude mcp add --transport http <名前> <URL>

    「<名前>」には自分で決めた呼び名を、「<URL>」にはサービス側が用意しているMCPのアドレスを入れます。「--transport http」の部分は「HTTP形式でつなぎます」という指定です。

    2つ目はstdio形式です。stdio(スタンダード・アイオー)は「標準入出力」の略で、プログラム同士が文字を受け渡しする基本的な通り道のこと。ざっくりいうと、自分のパソコンの中でMCPサーバーのプログラムを動かし、Claude Codeと直接やり取りする形式です。

    claude mcp add --transport stdio <名前> -- <コマンド>

    こちらは「--」のあとに、MCPサーバーを動かすためのコマンドを書きます。どんなコマンドになるかはサービスごとに違うので、使いたいサービスの説明ページを確認してください。

    なお、古い記事では「SSE」という形式が紹介されていることがあります。SSEは現在非推奨(今後は使わないほうがよい扱い)になっているので、これから始める人はHTTP形式を選べば大丈夫です。

    形式の選び方は、次のように考えるとシンプルです。

    • サービスがMCPのURLを公開している → HTTP形式

    • 自分のパソコンでプログラムを動かすタイプ → stdio形式

    非エンジニアの僕たちがまず触るのは、ほとんどがHTTP形式になるはずです。

    Notionとつないでみる

    では、連載の題材である「note記事づくりエージェント」に、Notionという道具を持たせてみましょう。Notionで記事ネタを管理している人なら、Claudeが出したネタをそのままNotionに書き込めるようになります。

    手順1:ターミナルでコマンドを打つ

    まずターミナルを開き、第1回で作った「my-agent」フォルダに移動します。移動のコマンドは第1回と同じです。Macの場合は、次のように打ちます。

    cd ~/Desktop/my-agent

    Windows(PowerShell)の場合は、次のように打ちます。

    cd $HOME\Desktop\my-agent

    デスクトップがOneDriveの中にあるWindowsでは、このコマンドだと「フォルダが見つからない」という内容のエラーになります。その場合は、第1回で説明したように「cd 」(cdの後ろに半角スペース)まで打ってから、my-agentフォルダをターミナルの画面にドラッグ&ドロップし、Enterキーを押してください。第1回と別の場所にフォルダを作った人も、この方法なら迷わず移動できます。

    フォルダに移動できたら、Notionを追加するコマンドを打ちます。ここから先は、WindowsでもMacでも同じです。

    claude mcp add --transport http notion https://mcp.notion.com/mcp

    これは、「notion」という名前で、Notionが公開しているMCPのURLにHTTP形式でつなぐ、という意味のコマンドです。

    手順2:Claude Codeを起動して認証する

    次に、いつもどおり「claude」と打ってClaude Codeを起動します。起動したら、入力欄に次のように打ってください。

    /mcp

    「/mcp」は、つないでいるMCPサーバーの一覧や状態を確認する画面を開くコマンドです。一覧から「notion」を選び、画面の案内に従って認証(ログインと利用の許可)を済ませます。

    ここでの認証は、OAuth(オーオース)という仕組みで行われます。OAuthは、パスワードそのものをClaudeに渡さずに「このアプリに使わせてOK」と許可を出す仕組みです。GoogleアカウントやLINEで別のサービスにログインしたことがあれば、あの流れと同じ種類のものだと思ってください。

    手順3:日本語で頼んでみる

    認証が終わったら、あとは普段どおり日本語で頼むだけです。

    Notionの「記事ネタ帳」ページに、今日の記事ネタを3つ追加して

    「記事ネタ帳」の部分は、自分のNotionにあるページ名に置き換えてください。第2回で作ったネタ出しSkillと組み合わせて、「/neta 副業」でネタを出してもらってから「今出したネタをNotionの記事ネタ帳に追加して」と頼む使い方もできます。

    権限モードの設定によっては、Notionに書き込む前に「実行してもいいですか?」と確認を求められます。第1回で説明したとおり、内容を見てから許可すれば大丈夫です。慣れないうちは確認を挟んだまま使うほうが安心だと、僕は考えています。

    うまくいかないときは、もう一度「/mcp」を開いて、notionが一覧にあるか、認証が済んでいるかを確認しましょう。

    設定を保存する3つの範囲

    MCPサーバーの設定は、どの範囲で使うかによって保存される場所が変わります。この範囲のことを「スコープ」と呼びます。スコープは3種類です。

    • local(ローカル):初期設定。自分だけが、今いるプロジェクト(フォルダ)の中だけで使う。設定は自分のパソコンの「~/.claude.json」というファイルに保存される

    • project(プロジェクト):プロジェクトのフォルダに「.mcp.json」というファイルを作って保存する。フォルダごと共有すれば、チームのメンバーも同じMCPサーバーを使える

    • user(ユーザー):自分のパソコンの、すべてのプロジェクトで使える

    先ほどのNotionの例では範囲を何も指定していないので、初期設定のlocalになっています。つまり、my-agentフォルダでClaude Codeを起動したときだけNotionが使える状態です。

    どれを選べばいいか迷ったら、次のように考えてみてください。

    • まず試してみたい → local(何も指定しない)

    • 仲間と同じ設定を使いたい → project

    • どのフォルダで作業するときもNotionを使いたい → user

    範囲を指定するときは、コマンドに「--scope」を付けて、そのあとにlocal・project・userのどれかを書きます。公式ドキュメントには、projectを指定する次のような例が載っています。

    claude mcp add --transport http shared-server --scope project https://example.com/mcp

    「shared-server」が名前、「https://example.com/mcp」がURLの例です。このようにprojectを選ぶと、プロジェクトのフォルダの直下に「.mcp.json」というファイルが作られます。このファイルがフォルダごと共有されることで、仲間も同じMCPサーバーを使えるようになるわけです。

    とはいえ、最初はlocalのままで十分です。慣れてきて「ほかのフォルダでもNotionを使いたい」と感じたら、「--scope user」を付けてuserスコープで使うことを検討すればOKです。

    ちなみに「~」(チルダ)は、パソコンのユーザーフォルダを表す記号です。Windowsなら「C:\Users\自分のユーザー名」、Macなら「/Users/自分のユーザー名」にあたります。

    状態の確認と削除

    つないだMCPサーバーは、ターミナルからコマンドで管理できます。よく使うのは次の3つです。

    claude mcp list
    claude mcp get notion
    claude mcp remove notion
    • claude mcp list:追加したMCPサーバーの一覧を表示する

    • claude mcp get notion:「notion」という名前のMCPサーバーの詳しい設定を表示する

    • claude mcp remove notion:「notion」という名前のMCPサーバーを削除する

    get と remove のうしろには、追加したときに付けた名前を入れます。名前を忘れてしまったら、まず list で一覧を確認しましょう。

    Claude Codeを起動している最中なら、先ほどの「/mcp」の画面も使えます。この画面でできるのは、次の4つです。

    • 接続中のMCPサーバーの一覧を見る

    • OAuthの認証(ログインと利用の許可)をする

    • MCPサーバーごとにオンとオフを切り替える

    • それぞれのMCPサーバーの状態を確認する

    状態は、たとえば次のような英語で表示されます。

    • Connected(チェックマーク付き):つながっていて、使える状態

    • Needs authentication(「!」付き):認証がまだ済んでいない状態

    • Failed to connect(バツ印付き):つなぐのに失敗した状態

    Notionをつないだ直後に「Needs authentication」と出ていたら、認証がまだという意味です。MCPで困ったらまず「/mcp」を開いて状態を見る、と覚えておくと便利です。

    使わなくなったMCPサーバーは、remove で削除しておくのがおすすめです。つないだままでも大きな負担にはなりにくいものの(くわしくは後半のよくある質問で説明します)、使っていない道具が棚に並んでいると、何がつながっているのか把握しにくくなります。

    claude.aiのコネクタも使える

    「コマンドを打つのはまだ少し不安」という人には、もっと手軽な方法もあります。それがclaude.aiのコネクタです。

    コネクタは、ブラウザ版やアプリ版のClaude(claude.ai)で外部サービスとつなぐ機能です。claude.aiの設定画面(claude.ai/customize/connectors)で追加したコネクタは、Claude Codeにも自動で表示されます。

    つまり、普段ブラウザでClaudeを使っていて、すでにコネクタでサービスをつないでいるなら、Claude Code側で改めて設定しなくても使える可能性があるということです。

    • コマンドに慣れている人 → claude mcp add で追加

    • 画面で操作したい人 → claude.aiのコネクタで追加

    どちらの方法でも、つながった道具をClaudeが使う点は同じです。自分に合うほうを選んでください。Claude Codeで実際にどのサービスが使える状態かは、「/mcp」の画面で確認できます。

    MCPを安全に使うための注意点

    MCPは便利な反面、AIに外の世界への扉を開く機能でもあります。扉を開けるからには、戸締まりのルールも決めておきましょう。僕が大事だと考えるポイントは3つです。

    1. 信頼できる提供元のMCPサーバーだけを使う

    MCPサーバーは、サービスの公式が提供しているものもあれば、個人が作って公開しているものもあります。つないだMCPサーバーには、Claudeを通じて自分のデータを扱わせることになります。提供元がはっきりしない、どんな動きをするかわからないものは避けましょう。今回のNotionのように、サービスの公式が案内しているものを選ぶのが基本です。

    2. APIキーをファイルに直接書いて共有しない

    サービスによっては、つなぐときに「APIキー」や「トークン」が必要になります。APIは「ソフト同士がやり取りするための窓口」のことで、APIキーやトークンはその窓口を使うための合言葉です。合言葉が他人に知られると、自分になりすましてサービスを使われるおそれがあります。

    特に注意したいのが、先ほど説明した「.mcp.json」です。projectスコープの設定はフォルダごと共有される前提なので、ここに合言葉をそのまま書いてしまうと、共有した相手全員に見えてしまいます。記事や資料で説明するときも、「YOUR_TOKEN」のようなダミーの文字に置き換えておきましょう。

    3. 最初は読み取りだけで試す

    いきなり「Notionのページを整理して」のような書き換えを頼むのではなく、まずは「Notionの記事ネタ帳を読んで、内容を要約して」のように読むだけの頼みごとから始めるのがおすすめです。Claudeが正しいページを見ているか、意図どおりに動くかを確認してから、書き込みの作業に進みましょう。

    Claude Codeのhooksの仕組み

    ここからは後半、hooksの話です。hooksは「どのタイミングで」「何を動かすか」を設定ファイルに書いておく仕組みです。まずは、hooksが動くタイミングの種類と、設定ファイルの書き方を見ていきましょう。

    hooksが動くタイミング

    hooksが動くタイミングのことをイベントと呼びます。主なイベントは次のとおりです。

    • SessionStart:Claude Codeの会話(セッション)が始まったとき

    • UserPromptSubmit:自分が指示を入力して送信したとき

    • PreToolUse:Claudeがツールを使う直前。ここで処理を止める(ブロックする)こともできる

    • PostToolUse:Claudeがツールを使った直後

    • Notification:Claude Codeが通知を出したとき

    • Stop:Claudeが応答を終えたとき

    • SubagentStop:サブエージェントが作業を終えたとき

    ここで出てくる「ツール」とは、Claudeがファイルを読む・編集する・コマンドを実行するといった作業をするときに使う道具のことです。たとえばファイルを書き換えるときは「Edit」、新しくファイルを書くときは「Write」というツールが使われます。

    今回の実践で使うのは、NotificationとPreToolUseの2つです。

    Notificationは、Claudeが「許可をください」と待っているときや、応答を返したあと入力がないまましばらく経ったときなどに発生します。公式ドキュメントによると、たとえば許可待ちの通知(permission_prompt)は約6秒、応答後に入力がないときの通知(idle_prompt)は約60秒で出ます。ここに通知の仕掛けを結びつけておけば、別の作業をしていても「Claudeが待っている」と気づけます。

    PreToolUseは、ツールを使う直前に動くのがポイントです。直前に動くからこそ、「そのファイルを編集するのは待った!」と止められます。止める側の仕掛けは、ほぼこのPreToolUseを使うと覚えておきましょう。

    設定ファイルの場所と書き方

    hooksは、「settings.json」という設定ファイルに書きます。置き場所は3種類あり、どこに書くかで効く範囲が変わります。

    • ~/.claude/settings.json:自分のパソコンの、すべてのプロジェクトに効く

    • .claude/settings.json:そのプロジェクトだけに効く。フォルダごとチームで共有できる

    • .claude/settings.local.json:そのプロジェクトだけに効き、自分専用

    通知のように「どのフォルダで作業しているときでも欲しい仕掛け」は1つ目の全体用に、「このプロジェクトのこのファイルを守りたい」という仕掛けは2つ目か3つ目に書く、と使い分けるとわかりやすいです。

    settings.jsonは、JSON(ジェイソン)という書式で書きます。JSONは、設定やデータを書くための決まった書き方のことです。「"名前": 値」の組み合わせを「{ }」(波かっこ)や「[ ]」(角かっこ)で囲んで表します。

    hooksの設定は、次のような入れ子の構造になっています。

    {
      "hooks": {
        "イベント名": [
          {
            "matcher": "絞り込みの条件",
            "hooks": [
              { "type": "command", "command": "実行する命令" }
            ]
          }
        ]
      }
    }

    外側から順に読むと、こうなります。

    • hooks:ここからhooksの設定です、という目印

    • イベント名:どのタイミングで動かすか(NotificationやPreToolUseなど)

    • matcher:さらに条件を絞り込む欄。たとえば「Edit|Write」と書くと、EditツールかWriteツールのときだけ動く(「|」は「または」の意味)

    • command:実際に実行する命令

    matcherを空欄("")にすると、そのイベントのときは毎回動きます。

    JSONは、かっこの閉じ忘れやカンマ(,)の過不足があるだけで読み込めなくなる、少し繊細な書式です。書き写すときは、かっこの数が合っているかを必ず確認してください。自信がなければ、後で紹介するように「Claudeに書いてもらう」のがいちばん確実です。

    hooksの実践例

    仕組みがわかったところで、実際に2つのhookを作ってみましょう。1つは「Claudeが待っているときに通知を出す」hook、もう1つは「大事なファイルの編集をブロックする」hookです。どちらも公式ドキュメントに載っている例をもとにしています。

    作業が終わったら通知を出す

    Claude Codeに長めの作業を頼んだあと、別のウィンドウで作業していて「実はずっと許可待ちで止まっていた」ということはよくあります。そこで、作業が一段落してClaudeが自分の返事や許可を待っているときに、通知が出るようにしてみましょう。使うイベントはNotificationです。

    設定は、すべてのプロジェクトに効く「~/.claude/settings.json」に書きます。

    Windows(PowerShell)の場合

    {
      "hooks": {
        "Notification": [
          {
            "matcher": "",
            "hooks": [
              {
                "type": "command",
                "command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
              }
            ]
          }
        ]
      }
    }

    commandの中身は長いですが、「PowerShellを使って『Claude Code needs your attention(Claude Codeが対応を待っています)』というメッセージの小さな画面を出す」という意味です。

    Windows版は、画面の端に出るような通知というより、メッセージが書かれた小さなウィンドウ(ダイアログ)が開く形になります。このダイアログはターミナルの裏に隠れてしまうことがあるので、「何も出ない」と思ったら、ほかのウィンドウの後ろも確認してみてください。

    Macの場合

    Macでは、commandの部分を次のように書き換えます。

    {
      "hooks": {
        "Notification": [
          {
            "matcher": "",
            "hooks": [
              {
                "type": "command",
                "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
              }
            ]
          }
        ]
      }
    }

    Macでは画面の右上に通知が表示されます。もし通知が出ない場合は、Macの「システム設定」→「通知」を開き、「スクリプトエディタ」の通知を許可してください。

    matcherで通知のタイミングを絞る

    どちらの例も、matcherが空欄("")になっています。これは「すべての通知で動かす」という意味です。matcherに「permission_prompt」と書けば許可待ちのときだけ、「idle_prompt」と書けば応答後しばらく入力がないときだけ、というように絞り込めます。最初は空欄のまま使ってみて、通知が多すぎると感じたら絞る、という順番がおすすめです。

    すでにsettings.jsonに設定がある場合

    ここは特に注意してほしいポイントです。settings.jsonにすでに何か書かれている場合、ファイルの中身を丸ごと上の例に置き換えてはいけません。今ある設定が消えてしまいます。

    すでに「"hooks"」の項目がある場合は、その中に「"Notification"」を追加します。たとえば、my-agentフォルダの「.claude/settings.json」に、通知(Windows版)と、あとで紹介するファイル保護のhook(PreToolUse)を両方書く場合は、次のようにイベント名を横並び(兄弟の関係)にします。

    {
      "hooks": {
        "Notification": [
          {
            "matcher": "",
            "hooks": [
              {
                "type": "command",
                "command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
              }
            ]
          }
        ],
        "PreToolUse": [
          {
            "matcher": "Edit|Write",
            "hooks": [
              { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh" }
            ]
          }
        ]
      }
    }

    「Notification」のかたまりを閉じる「]」のあとに、カンマ(,)が入っている点に注目してください。イベントを並べるときは、このカンマを忘れると読み込めなくなります。Macの人は、Notificationのcommandの部分をMac版に置き換えてください。なお、PreToolUseのほうは、あとで作るスクリプト(protect-files.sh)を用意してから使います。

    登録できたか確認する

    設定を書いたら、Claude Codeの中で次のコマンドを打ちます。

    /hooks

    「/hooks」を開くと、登録されているhookの一覧を確認できます。Notificationの項目に自分の設定が表示されていれば成功です。

    大事なファイルの編集をブロックする

    2つ目は、大事なファイルをClaudeに編集させないhookです。ここでいう大事なファイルは、たとえば次のようなものです。

    • .env:APIキーなどの合言葉を書いておくことが多いファイル

    • package-lock.json:プログラムの部品の組み合わせを記録したファイル。手で書き換えると不具合のもとになる

    • .git/:ファイルの変更の履歴を管理しているフォルダ

    使うイベントはPreToolUseで、matcherは「Edit|Write」です。つまり、「Claudeがファイルを編集したり書き込んだりする直前」に毎回チェックが走ります。

    仕組み:終了コードで「続行」か「ブロック」かを伝える

    hookで動かす命令(スクリプト)は、処理を終えるときに終了コードという数字を返します。終了コードは「うまくいったか、どうなったか」をClaude Codeに伝える合図のようなものです。

    • exit 0:問題なし。そのまま続行する

    • exit 2:ブロックする。ツールの実行を止める

    exit 2で止めるときに理由を出力しておくと、その理由がClaudeに伝わります。Claudeは「このファイルは保護されているので編集できない」と理解して、別のやり方を考えてくれるわけです。

    手順1:スクリプトを作る

    my-agentフォルダの中に「.claude/hooks」フォルダを作り、「protect-files.sh」というファイルを置きます。中身は次のとおりで、公式ドキュメントの例そのものです(「(訳)」の行だけ、僕が日本語訳を書き足しています)。

    #!/bin/bash
    # protect-files.sh
    
    INPUT=$(cat)
    FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
    
    # Normalize Windows backslash separators so the patterns below match
    # (訳)Windowsの区切り文字「\」を「/」にそろえて、下のパターンと一致するようにする
    FILE_PATH="${FILE_PATH//\\//}"
    
    PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")
    
    for pattern in "${PROTECTED_PATTERNS[@]}"; do
      if [[ "$FILE_PATH" == *"$pattern"* ]]; then
        echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
        exit 2
      fi
    done
    
    exit 0

    上から順に、何をしているかを説明します。

    • 1行目は「このファイルはBash(バッシュ)というシェルで動かします」という宣言です。シェルは、ターミナルで打った命令を実行してくれる仕組みのことです

    • 「INPUT=$(cat)」で、Claude Codeから渡される情報を受け取ります。hookには、これから使われるツールの情報がJSONの形で渡されます

    • 「jq」の行で、受け取ったJSONの中から「編集しようとしているファイルの場所(file_path)」だけを取り出します

    • 「FILE_PATH="${FILE_PATH//\\//}"」の行で、Windowsのフォルダの区切り文字「\」を「/」に置き換えます。Windowsではファイルの場所が「\」で区切られるため、このままだと「.git/」のようなパターンと一致しないからです

    • 「PROTECTED_PATTERNS」に、守りたいファイルやフォルダの名前を並べます

    • 編集しようとしているファイルの場所に保護パターンが含まれていたら、理由をエラー用の出力(stderr)に書いて「exit 2」でブロックします

    • どれにも当てはまらなければ「exit 0」で、そのまま続行させます

    連載の題材に合わせるなら、たとえば公開済みの記事を入れているフォルダ名を保護パターンに加えておけば、「公開済みの原稿をClaudeがうっかり書き換える」という事故を防げます。保護パターンは、かっこの中に「"フォルダ名/"」の形で追加していけばOKです。

    Macの場合は、作ったスクリプトに実行権限を付ける必要があります。実行権限とは、「このファイルをプログラムとして動かしてよい」という許可のことです。my-agentフォルダに移動した状態で、ターミナルに次のように打ってください(Linuxでも同じです)。

    chmod +x .claude/hooks/protect-files.sh

    この一手間を忘れると、hookとして登録してもスクリプトが動きません。

    手順2:jqを用意する

    このスクリプトは、JSONから情報を取り出すために「jq」という小さなツールを使います。jqが入っていないと動かないので、先に用意しておきましょう。Macの場合は、Homebrew(Mac用のソフトを入れる道具)を入れていれば、次のコマンドで入れられます(公式ドキュメントでも案内されている方法です)。

    brew install jq

    手順3:settings.jsonに登録する

    最後に、my-agentフォルダの「.claude/settings.json」に次のように書きます。このプロジェクトだけに効かせたいので、全体用ではなくプロジェクト用の設定ファイルを使います。commandの部分は、公式ドキュメントの例そのままです。

    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Edit|Write",
            "hooks": [
              { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh" }
            ]
          }
        ]
      }
    }

    「$CLAUDE_PROJECT_DIR」は、今作業しているプロジェクトのフォルダ(ここではmy-agent)の場所を表す書き方です。フォルダの場所をまるごと書かなくても、スクリプトの場所を指定できます。

    Windowsの場合の補足

    このスクリプトはBash向けに書かれています。公式ドキュメントでは、WindowsではGit for Windowsを入れておくとClaude CodeがBashを使えるようになると案内されています。まずは第1回で紹介したGit for Windowsを入れておきましょう。Windowsでのjqの入れ方は環境によって変わるので、「protect-files.shのhookをこのパソコンで動くように準備して」とClaudeに相談しながら進めると安心です。

    設定が終わったら、試しにClaudeに「.envファイルを作って」と頼んでみてください。ブロックされて、編集できない理由が返ってくれば成功です。

    hooksもClaudeに書いてもらえる

    ここまで読んで「JSONを手で書くのは、やっぱり自信がない」と感じた人もいると思います。安心してください。hooksの設定も、Claudeに頼んで書いてもらえます。

    Claudeが入力を待っているときに、Windowsで通知が出るhookを設定して

    このように頼めば、Claudeが設定ファイルの中身を考えて書いてくれます。Macを使っている人は「Windows」を「Mac」に変えるだけです。自分で書くより、かっこの閉じ忘れのようなミスも起きにくくなります。

    1つ注意したいのは、「/hooks」の画面は見るだけだという点です。「/hooks」では登録されているhookの確認はできますが、画面の中で編集することはできません。hookを追加・変更したいときは、settings.jsonを直接書き換えるか、Claudeに頼んで書き換えてもらいます。

    頼んで作ってもらったあとは、「/hooks」を開いて、意図したイベントに登録されているかを確認しましょう。頼む→確認するの2ステップを習慣にすると、知らないうちに変な設定が入っていた、という事態を防げます。

    MCPとhooksでよくある質問

    最後に、MCPとhooksを使い始めた人が抱きがちな疑問に答えておきます。どちらも「困ったらまず確認する場所」を知っておくと、慌てずに対処できます。

    MCPを入れすぎると重くなる?

    結論からいうと、あまり心配しなくて大丈夫です。

    Claudeには、一度に覚えておける情報の量(コンテキスト)に限りがあります。MCPサーバーをたくさんつなぐと、「それぞれの道具の説明書」で記憶の容量が埋まってしまうのでは、と気になるかもしれません。

    ただ、Claude Codeではツール検索という機能が初期設定でONになっています。必要なときに必要な道具を探して使う仕組みなので、使っていないMCPのツールは記憶の容量をほとんど使いません。

    とはいえ、何がつながっているか自分で把握できなくなるのは困りもの。使わなくなったものは「claude mcp remove」で整理しておくのがおすすめです。

    hookが動かないときは?

    hookが動かないときは、次の3つを順番に確認してみてください。

    1. 「/hooks」で登録されているかを確認する:一覧に出ていなければ、設定ファイルの場所や書き方が違う可能性があります

    2. コマンドを単体で試す:commandに書いた命令をターミナルに直接打って、ちゃんと動くかを確かめます。単体で動かなければ、hookとしても動きません

    3. JSONの書き間違いを確認する:かっこの閉じ忘れ、カンマの過不足、「"」の抜けなどがないかを見直します

    特に多いのが3つ目の書き間違いです。自分で見つけられないときは、「このsettings.jsonに書き間違いがないか確認して」とClaudeに頼むのも手です。

    まとめと次回予告

    第4回では、MCPとhooksを使ってAIエージェントを強化しました。

    • MCPは、AIに外の道具を持たせる差し込み口。「claude mcp add」でNotionなどのサービスとつなぎ、「/mcp」で認証・確認する

    • hooksは、決まったタイミングで必ず動く仕掛け。CLAUDE.mdが「お願い」なら、hooksは「強制」

    • Notificationのhookで、Claudeが待っているときに通知を出せる

    • PreToolUseのhookと終了コード2で、大事なファイルの編集をブロックできる

    これで「note記事づくりエージェント」は、CLAUDE.mdで自分のやり方を覚え、Skillsで手順を持ち、サブエージェントで専門担当を抱え、MCPで外の道具を使い、hooksで大事なルールを確実に守る存在になりました。

    次回はいよいよ最終回です。ここまで作ってきたすべてを組み合わせて、役割ごとに担当者が分かれた「AIチーム」を作ります。僕が実際に使っている、営業からディレクター、リサーチ、ライター、編集、品質担保までの6役割のチーム構成も公開する予定です。


    ※この記事は2026年9月時点の情報です。Claude Codeは更新が速いので、最新の仕様は公式ドキュメント(code.claude.com/docs)を確認してください。

     
     
    初心者向けの記事を書いていきます。ストレート宮廷院->通信キャリアで転職経験なし。昨年度世帯売り上げで2000万超えを達成。3階低層RC住宅を購入。

    あなたへのおすすめ