用 WordPress Abilities API 寫 MCP server:從手刻 Function Call 到官方標準


這禮拜的主題比較硬一點,但如果你有在用 AI 開發外掛然後想讓自己的 Antigravity 或是 Claude Code 讀到網站的內容像是查訂單,這篇教學就非常適合貼給 AI 請它幫你開發~

話說之前做 DWP 的 LINE 聊天機器人查 WooCommerce 訂單,會員可以直接在 LINE 裡問訂單狀態、查活動,背後是 OpenAI 的 Function Call 在跑。整個架子是自己刻的——每一個會員問句能對應到的後端動作,要自己定義一份 JSON Schema 告訴模型「這個工具吃什麼參數、回什麼結構」,再寫一個 dispatcher 收到 model 的 tool_calls 之後手動 routing 到對應的 WP 函式,回傳值也要自己塞回對話 context。

換一家模型供應商就要重做一次 schema 格式(OpenAI、Anthropic、Gemini 的欄位名稱都不一樣),漏處理一個錯誤路徑 LINE 那邊就吐出一堆奇怪的字。一份「查訂單狀態」的能力,被綁死在這個 LINE Bot 專案裡,搬不到別處用。

直到 WordPress 6.9 把 WordPress Abilities API 正式收進 core,加上 Automattic 維護的 MCP Adapter,這套東西就有了官方標準。同一個 ability 一次註冊,就同時能從 PHP、REST API、跟 MCP(給 Claude Code、Claude Desktop、Cursor 這些 AI client 直接呼叫)三個路徑使用。這篇就是用我們做的 cdx-mcp 外掛當實例,把整條路走過一次。

WordPress Abilities API 是什麼

Abilities API 是 WordPress 6.9 開始進 core 的官方標準,讓你把一段「可被外部呼叫的功能」用統一格式註冊起來,附上輸入/輸出 schema、權限檢查跟標籤——之後 PHP、REST、AI agent 都能用同一份定義去呼叫它。

對應到之前 LINE Bot 自刻 Function Call 的痛點,差別在:

手刻 Function CallAbilities API每個 model 廠商一份 schema一份 input/output schema 全平台共用自己寫 dispatcher routing用 wp_register_ability( $name, $args ) 註冊自己驗證權限、自己回錯誤permission_callback + 回 WP_Error 是標準約定只能在那個專案內用註冊完同時走 PHP/REST/MCP

註冊一個 ability 需要的關鍵欄位:

  • labeldescription:description 是寫給 AI 看的,講清楚做什麼、吃什麼、回什麼
  • category:先用 wp_register_ability_category() 註冊好,ability 才能歸到那個 category 底下
  • input_schema / output_schema:JSON Schema 格式
  • execute_callback:實際做事的 PHP function
  • permission_callbackRequired,不是 optional(官方 PHP API 文件曾經寫成 optional,後來修正)
  • meta.annotations:標示這個 ability 的特性(唯讀、是否會破壞資料、是否冪等)

meta.annotations 這幾個旗標被 MCP Adapter 自動映射成 readOnlyHintdestructiveHintidempotentHint,AI 會看這幾個值來決定要不要自動呼叫。特別注意 destructive 預設值是 true,純查詢的 ability 一定要手動設成 false,不然 Claude 會以為這動作有破壞性而拒絕自動執行。這是文件埋得比較深的雷。

MCP Adapter 把 ability 轉成 MCP tool

Abilities API 解決了「功能怎麼註冊」,MCP Adapter 解決的是「怎麼讓 AI agent 找得到並呼叫它」。

Model Context Protocol(MCP)是 Anthropic 推出的開放協定,讓 AI client(Claude Code、Claude Desktop、Cursor、VS Code 等)能透過統一介面去呼叫外部工具。MCP Adapter 就是 WordPress 這端的橋——把已註冊的 ability 包裝成 MCP server 暴露出去,AI client 用 tools/listtools/call 兩個方法就能讀到 schema 並執行。

裝起來有兩種選擇:

  1. 用 default server:裝完 mcp-adapter 外掛就會自動建一個叫 mcp-adapter-default-server 的 server,要把 ability 加進去得在註冊時加一個 meta.mcp.public = true 旗標
  2. 自己建 custom server:在自己的外掛裡明確指定要暴露哪些 ability,乾淨可控,且不需要那個 public 旗標

我走第二條直接用 Composer 安裝,就不用讓使用者還要另外去裝 adapter 外掛了。

實戰:cdx-mcp 外掛把 WooCommerce 訂單查詢變 MCP tool

我做了一個外掛叫 cdx-mcp,功能很單純:給一個 WooCommerce 訂單 ID,回傳這筆訂單的完整結構化資料(狀態、金額、客戶、付款方式、品項),給 Claude Code 直接拿來查訂單。整個外掛大概 200 行 PHP,因為程式碼有點多,請幫我移駕到這邊吧:https://oberonlai.blog/wordpress-abilities-api-mcp-server/

WordPress 開發日常

Read more from WordPress 開發日常

之前朋友約出來喝咖啡時他分享下一個階段的 AI 可能會發展成監督式的 AI,也就是當 AI 自己在跑的時候,會有另外一個 AI 來檢查它現在做的每一件事情是否都真的有往正確的方向推進。 當下聽到覺得這個 idea 很棒,但具體要怎麼實作完全沒有概念,更不用說這樣子 token 消耗的成本會不會變成兩倍?而且監督 AI 的 AI 需要有什麼能力?該以哪一種方式來進行監督?然後又該如何把找出的問題回報給原本的 AI 呢? 這一切問題在我最近研究 Claude Code 以外的工具時意外發現了解決方案,那就是之前我拿來做為 Discord Bot 的 AI 引擎 OMP。 OMP 是 PI 的分支,想理解什麼是 OMP 可以先從 PI 開始理解,PI 是一套開源且輕量化的 Coding CLI,也是跟 Claude Code 一樣跑在終端機的寫程式 Agent。 相較於 Claude Code 的封閉,PI 完全開源,並且支援多家不同的模型,PI 強調有需要什麼工具再自己額外安裝,就不會像 Claude Code 一樣原廠給你什麼就只能用什麼。 而 OMP 是 PI 的分支,它的概念跟...

之前分享我請 AI 設計的一套專門用來管理手邊待辦清單的專案管理軟體,邊用的時候我就在邊思考著:當我新增這些任務之後,我還是要回到終端機去把這些任務的描述、相關的文件以及完成的目標告訴 AI,然後等它跑完之後我再驗收,再回到我的計時軟體裡面來記錄是已完成還是該暫停。 如果可以在開立任務的時候,就能直接指派 AI 來做這件事情,是不是就可以少一個重複描述、開發需求的流程?剛好有了這個想法之後,就在 YouTube 上面看到一個叫做 Auto Claude 的專案。 它把 Claude 直接跟看板軟體整合,並且可以在裡面詢問 AI 關於專案的細節以及產生開發藍圖,也能設定專案的亮點與相關資訊。 我看到後驚為天人,覺得這似乎是另外一種理想的 AI 開發軟體,本想直接下載裝起來用,但請 Claude 研究後發現它有一些問題,於是就想說自己來開發,順便理解關於整個 Loop Engineering 的概念。 Claude Orchestrator 這次一樣是使用 Glaze 來開發,請它建立好專案的環境之後,然後再回到終端機去接手後續的多工並行。我的做法是先請 AI 去參考 Auto...

常常在社群媒體上看到各種自動化工具的廣告,從早期的 n8n 開始到現在 AI Agent 自動完成任務,這些工具跟流程都很棒。但是回到使用者本身,我們真的知道自己有哪些工作是可以被自動化或是應該「自動化」的嗎? 這就讓我回想起以前給自己的工作要求,那就是要把手上所做的每一件事情都記錄下來,並且可以明確看到每項任務的執行時間以及頻率,這樣事後才有辦法做回顧,我把這樣的理念也應用到承接專案的層面上。 這也是為什麼我有一些專案都是採取時薪計價的開發模式,因為我需要讓客戶知道他的預算都花在哪些項目,來藉此把資源用在合適的任務上。 我最早使用的即時軟體叫做 Ora,這是一套結合看板管理、敏捷開發流程、時數統計,甚至還有內建聊天討論串的一套強大工具。 它長期都是免費的,付費方案是團隊成員超過計算,所以我都是使用它來進行與客戶的專案管理,它的介面十分清楚且一目瞭然,可以縱觀地知道是哪一類型的任務花最多時間,也可以細看到具體是在處理哪一個問題所消耗的時數。 但當某天我打開準備使用它的時候,發現它被另外一套專案管理軟體 ClickUp...