Claude Code v2.1.118:Hooks 現在能直接呼叫 MCP 工具了

今天早上看 Claude Code 更新日誌,v2.1.118 的 changelog 裡有一行:

Hooks can now invoke MCP tools directly via type: "mcp_tool"

這句話看起來平淡,但停下來想了幾秒——這件事的意義比表面上大得多。

Hooks 原本能做什麼

Claude Code 的 hooks 是在特定生命週期事件點(PreToolUsePostToolUseStop 等共 27 個事件)自動觸發的處理器。設定在 settings.jsonhooks 欄位裡:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude 完成任務了'"
          }
        ]
      }
    ]
  }
}

在 v2.1.118 之前,hook handler 支援四種類型:

類型說明
command執行 shell 指令,透過 exit code 和 stdout 回傳結果
http以 POST 請求送 JSON 到指定 URL
prompt送 prompt 給 Claude 模型做單輪判斷,回傳 yes/no
agent啟動 subagent 進行複雜驗證(實驗性)

這四種已經很夠用,特別是 command 幾乎萬能——需要打 API?寫個 curl;需要送通知?叫個 script。但中間有個摩擦:所有跟 MCP server 的互動都要繞一圈,先用 shell 去呼叫對應的 CLI 工具或 HTTP API,或者自己架一個 endpoint 橋接,token 和驗證設定也要重新處理一遍。

type: “mcp_tool” 讓什麼變得不同

新的 mcp_tool handler 讓 hooks 可以直接調用已設定的 MCP server 工具,不再需要 shell 中轉。這是 changelog 裡的示例片段:

hooks:
  - event: "UserPromptSubmit"
    type: "mcp_tool"

換算成 settings.json 的 JSON 格式,大概會是這樣的結構(官方完整語法文件應該在近期補上):

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "mcp_tool",
            "tool": "mcp__slack__send_message",
            "arguments": {
              "channel": "#dev-log",
              "text": "Claude 完成本輪任務"
            }
          }
        ]
      }
    ]
  }
}
NOTE — 語法仍在確認中

v2.1.118 在 2026-04-23 當天釋出,官方 hooks 文件尚未更新 mcp_tool 的完整 JSON 語法。建議查看 Claude Code Hooks Reference 取得最新說明。

為什麼這件事重要

MCP(Model Context Protocol)是 Claude Code 的工具擴充系統,社群已經有大量的 MCP server:Slack、GitHub、Notion、PostgreSQL、Filesystem、Jira、Sentry……不勝枚舉。所有工具的驗證設定(OAuth token、API key、連線字串)都已經統一在 mcpServers 設定裡配好。

以前,如果想在 PostToolUse hook 裡把 Claude 改過的每個檔案記錄到 Notion,需要:

  1. 自己寫一個 Python 或 Node.js script 呼叫 Notion API
  2. 在 hook 的 command 欄位指向這個 script
  3. 確保 script 有執行權限、相依套件都裝好
  4. 另外處理 Notion token(不能直接複用 MCP 的設定)

現在 mcp_tool 讓 hooks 直接重用 MCP server 的連線,理論上:

  1. 在 hook 設定裡指定 type: "mcp_tool" 和工具名稱就好

少了好幾個中間層,驗證設定也不需要重複維護。

幾個可以想到的應用場景

Stop hook + Slack MCP 通知

每次 Claude 完成一輪對話,自動送訊息到 Slack 頻道。以前要自己存 Webhook URL 並寫 curl 指令,現在如果已經裝了 Slack MCP server,可以直接重用。

PostToolUse + GitHub MCP 自動記錄

搭配 matcher: "Write|Edit|MultiEdit" 攔截所有寫入事件,Claude 每次成功修改檔案,自動在對應的 GitHub issue 加一條進度留言。

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "mcp_tool",
            "tool": "mcp__github__add_issue_comment",
            "arguments": {
              "issue_number": 42,
              "body": "Claude 修改了 $TOOL_OUTPUT_PATH"
            }
          }
        ]
      }
    ]
  }
}

PreToolUse + 資料庫 MCP 驗證 policy

在執行任何 Bash 指令前,先查資料庫確認目前環境的執行 policy,不符合的話 hook 回傳 exit code 2 直接攔截。比起 command 類型還要自己接 DB 連線,邏輯會乾淨許多。

TIP — 先用 /mcp 確認 server 狀態

mcp_tool hook 依賴已設定的 MCP server。設定前先在對話裡輸入 /mcp 確認目標 server 已連線且工具名稱正確,避免 hook 觸發時才發現 server 未啟動。

v2.1.118 其他幾個值得注意的地方

同一版本還有幾個值得記下來的更新:

自訂主題/theme 現在可以建立和切換命名主題,JSON 設定放在 ~/.claude/themes/ 目錄下,plugin 也可以隨附 themes/ 子目錄。一直用預設主題的人終於有理由客製化了。

/usage 整合了 /cost/stats:兩個指令合併成一個,進去之後用分頁切換。原本的 /cost/stats 仍然可以當捷徑輸入,只是不再是獨立指令頁面。

Auto Mode 支援 "$defaults" 佔位符autoMode.allowautoMode.soft_denyautoMode.environment 三個設定欄位現在可以放入 "$defaults" 字串,讓自訂規則追加在內建預設清單之後,而不是直接替換整份清單。對有在調整 Auto Mode 行為的人很實用——以前一旦自訂就得手動維護整份預設清單,現在只需要寫額外想加的部分。

Vim 視覺模式vV 進入 visual 和 visual-line 選取模式,支援完整的 operator,對習慣 vim 操作的人算是補齊了一個缺口。

個人觀點

Claude Code hooks 系統一直有種「幾乎完美但差一口氣」的感覺。command 類型太底層,什麼都能做但什麼都要自己搭;promptagent 很聰明,但每次觸發都要打 LLM API,代價不低;http 則需要自己架 endpoint 才能接 MCP 工具。

mcp_tool 剛好補在這個空缺裡:已知工具、確定語意、不需要 LLM 介入、也不需要自己寫橋接 script。

如果最後的文件跟概念一樣簡潔,這會是 hooks 設定體驗最明顯的一次躍進。更深遠來看,這讓 hooks 從「事件發生時執行 shell 指令」升級成「事件發生時呼叫任意外部服務」——差異不只是語法,而是整個可以串接的生態系範圍。

當然,v2.1.118 剛上線,arguments 傳遞格式、錯誤處理行為、hook 回傳值如何影響後續流程,這些細節都還要等文件更新才能確認。但今天看到這行更新的時候,直覺就知道是值得記下來的一筆。


資料來源

留言