前端開發 別再讓 Agent 猜按鈕:30 天打造並實測 Agent-ready 的 WebMCP 活動網站 · 第 3 / 30 篇

Day 03|先別急著做 Tool,我把活動網站自己走了一遍

2026 iThome 鐵人賽 WebMCP Day 3:安安~我是ChiYu~ 昨天把專案切到固定 tag,Web、API、測試和 build 也都跑起來了。照這個進度,今天最容易做 的事情,就是立刻替網站加上第一支 WebMCP Tool。 但我先把 Inspector 關掉。 不是它做錯了什麼,只是今…

快速導覽 查看本文目錄

本文同步自 2026 iThome 鐵人賽原文 。完整系列可見 iThome 系列頁 。

安安~我是ChiYu~

昨天把專案切到固定 tag,Web、API、測試和 build 也都跑起來了。照這個進度,今天最容易做 的事情,就是立刻替網站加上第一支 WebMCP Tool。

但我先把 Inspector 關掉。

不是它做錯了什麼,只是今天還輪不到它上班。我想先用一般使用者的身分,從活動列表開始, 親手搜尋、看詳情、收藏,再一路走到報名與取消。如果連我自己都說不清楚任務從哪裡開始、 改了什麼狀態,以及哪一步必須停下來,Agent 只會很有效率地把混亂重播一次。

按鈕也不能直接等於 Tool。把「搜尋活動」「收藏活動」「確認報名」翻成三個英文名稱,catalog 確實會立刻變熱鬧,產品邊界卻還是一團霧。今天真正要整理的是 Human-first Journey:使用者 想完成什麼、網站回了什麼,以及決定權最後留在誰手上。

活動網站剛好能放進不同風險的操作:搜尋與查看詳情是唯讀;收藏會改變 session 狀態,但還能 Undo;報名與取消會影響使用者權益,送出前應該讓人看清楚內容。這些已經足夠,不需要為了讓 Demo 看起來更豪華,再搬來付款、OAuth 和管理後台。

今天固定使用同一筆公開活動:

項目固定值
活動 IDevt-webmcp-intro
活動名稱WebMCP 入門工作坊
條件台北、免費、入門
時間2027 年 1 月 23 日 10:00–12:00
剩餘名額8

活動資料固定後,搜尋結果、route、測試斷言與後面的 Inspector trace 才能互相核對。文章若 寫「前端高峰會」,程式卻回傳「WebMCP 入門工作坊」,兩邊就算都亮綠燈,也只是各自成功, 拼不起同一條證據鏈。

AgentReady Events 三條人類 Journey

圖 1:三條 Journey 都先由人類走過一次。後面加入 Agent 時,才知道它可以協助到哪裡,又該在哪裡停下來。

用可見表單完成搜尋,沒有 WebMCP 也要能用

開啟 http://127.0.0.1:5173/events,設定:

  • 地點:台北
  • 費用:免費
  • 程度:入門

按下「搜尋活動」後,結果只留下 evt-webmcp-intro,也就是「WebMCP 入門工作坊」。卡片顯示 日期與摘要,接著由「查看詳情」進入下一步。

人類使用篩選條件找到 WebMCP 入門工作坊

圖 2:人類使用可見表單完成搜尋;右下方 audit trail 記錄的是 human 操作。

我刻意確認這條流程在沒有 document.modelContext 時仍能使用。WebMCP 在這個專案裡扮演 progressive enhancement;瀏覽器不支援,使用者照樣可以填表單、按搜尋、讀取結果。若加完 Agent 能力後,人類反而不能用了,那比較像換了一扇新門,順手把原本的門封起來。

搜尋找到活動後,下一個問題也跟著出現:網站要怎麼知道使用者目前正在看哪一場?答案不能 靠 Agent 猜 current 或 active,而是交給詳情 route。

詳情 route 決定目前活動,收藏狀態交給 Server

按「查看詳情」後,route 變成:

/events/evt-webmcp-intro

詳情頁列出 2027 年 1 月 23 日 10:00–12:00、台北前端共學空間與剩餘 8 名。使用者可以收藏 活動,也可以前往報名。收藏成功後,按鈕與狀態訊息會同步更新;再按一次只會得到冪等結果, 不會多塞一筆相同資料。

WebMCP 入門工作坊詳情與收藏入口

圖 3:詳情 route 提供完整活動上下文;收藏是低風險寫入,報名則進入另一個流程。

route 在這裡不只是拿來顯示網址。它直接回答「目前是哪一場活動」,讓畫面、API 與後續 Tool 共用 evt-webmcp-intro。等 Agent 進場後,也不必拿看似合理、其實查無此人的字串代替活動 ID。

收藏則示範低風險寫入該怎麼呈現。它會寫入目前 session,畫面立即顯示已收藏,也提供 Undo。 重新整理後,狀態仍由 Server 回傳,不靠按鈕文字自說自話。不過它依然只是 session Demo, 不能假裝成永久帳號收藏。

收藏做錯還能 Undo,報名就不能這麼隨便。接下來我把資料填好,但不讓任何自動化替人按下 最後送出。

報名與取消先準備,最後一步留給人類

從詳情頁前往:

/events/evt-webmcp-intro/register

報名頁顯示活動、姓名與 Email。表單可以先帶入資料,按鈕則明確寫著「我確認並送出報名」。 只有人類真的按下它,/registrations 才會出現一筆有效報名。

報名資料已填入,等待人類確認送出

圖 4:填好欄位不等於已報名;正式 POST 發生在人類確認之後。

「我的報名」頁也沒有放一顆按下去就直接刪除的按鈕。使用者先選「準備取消」,看完活動名稱 與取消後果,再決定保留報名或確認取消。兩條高影響流程使用同一個原則:資料可以先準備, 影響要先說清楚,最後一步由人類完成。

這裡先把可見 UI 當成基線。之後 Agent 會協助準備報名與取消,但走到確認畫面就得停下來; 不能因為參數填對了,順便把使用者的決定也一起送出去。

用 Playwright 重播 Journey,準備階段必須維持零 POST

手動走過一次還不夠。今天把三條 Human-first Journey 交給 browser test 重播:

npx playwright test `
  tests/browser/events-human.spec.ts `
  tests/browser/saved-event.spec.ts `
  tests/browser/registration.spec.ts `
  tests/browser/cancellation.spec.ts

這一輪得到 8 passed。案例涵蓋鍵盤搜尋、沒有 modelContext 時的 fallback、收藏與 Undo、 報名準備階段零 POST,以及取消 dialog 的 human confirmation。

我最在意的不是畫面有沒有順利跳頁,而是「準備」和「送出」真的分開。報名頁可以先顯示姓名 與 Email,但 Network 在準備階段必須維持零 POST;只有人類確認後,Server 才能建立報名。 取消也是一樣,打開 dialog 不得改變狀態,確認按鈕才送出 mutation。

這條界線之後會原封不動交給 prepare Tool。Agent 可以省下填表和整理摘要的時間,不能省略 使用者本人。

功能先凍結,明天只把搜尋交給 Playwright

走完這一輪,活動網站已經有資訊讀取、可復原寫入與需要人類確認的操作。再加付款、OAuth、 資料庫或管理後台,專案會變大,今天的問題卻不會因此變清楚。功能就停在這裡。

三條 Journey 都會保留,但第一個交給機器重播的任務,我選搜尋。理由一點也不炫:它是唯讀, 條件與結果都看得見,腳本就算跌倒,也不會多收藏一筆或占掉一個名額。連這段都還沒拆清楚, 就急著自動報名,多少有點把屋頂扛在肩上找地基。

目前 Demo 使用 session 與 Server authority 驗證操作,但它不是正式會員系統。這個 non-goal 得寫清楚,否則 session Demo 很容易在文章裡被讀成完整 RBAC,責任突然膨脹得比功能還快。

活動案例還有一個實際優點:每個結果都能回到畫面檢查。搜尋後有卡片,收藏後有狀態,報名後 會出現在「我的報名」。Agent 之後真的參與其中,人類也不用只盯著聊天紀錄,猜它剛才是不是 偷偷做了什麼。

今天從頭走完以後,搜尋表單、詳情 route、收藏狀態與人類確認都有了可重播的基線。這也接住 昨天留下的問題:我們不只拿得到同一個網站,現在還知道它原本應該怎麼被人使用。

明天先把其中最安全的一小段交給 Playwright:仍然搜尋同一場活動,只把剛才的操作寫成 瀏覽器腳本。等程式開始找欄位、按按鈕,我們就能看見它究竟理解了「搜尋活動」,還是只 記住我今天按過哪一顆按鈕。

讀完了!你覺得這篇如何?

你的回饋會決定下一篇要寫什麼。

還有疑問

Learning path

別再讓 Agent 猜按鈕:30 天打造並實測 Agent-ready 的 WebMCP 活動網站

這篇是系列中的第 3 / 30 篇。可以順著列表補完整脈絡,也可以直接跳到需要的段落。

  1. 01 Day 01|網站真的會被 Agent 使用嗎?我先丟了一句自然語言
  2. 02 Day 02|換到全新資料夾後,網站還能不能跑?
  3. 03 Day 03|先別急著做 Tool,我把活動網站自己走了一遍 目前閱讀
  4. 04 Day 04|按鈕只多包一層,哪種 Playwright Locator 撐得住?
  5. 05 Day 05|只改按鈕四個字,Playwright 為什麼停在 click 以前?
  6. 06 Day 06|Playwright、REST API、MCP 與 WebMCP,各自負責哪一段?
  7. 07 Day 07|Agent 偶爾答對還不夠,我先出二十道測試題
  8. 08 Day 08|WebMCP Tool 該怎麼設計?把「點按鈕」改成「搜尋活動」
  9. 09 Day 09|網站該公開哪些 WebMCP Tool?從操作盤點到五支正式能力
  10. 10 Day 10|Inspector 裝好了,為什麼 Tool 面板還是一片空白?
  11. 11 Day 11|什麼是 Declarative API?讓 HTML 表單成為 WebMCP Tool
  12. 12 Day 12|Tool 註冊完還不算完成:離開 route 後誰把它收回來?
  13. 13 Day 13|第一次按下 Inspector 的 Send,先被 Gemini 429 擋在門外
  14. 14 Day 14|五支 Tool 不再往外長:把產品範圍寫成會亮紅燈的契約
  15. 15 Day 15|讓人類與 Agent 共用同一套活動搜尋規則
  16. 16 Day 16|Agent 怎麼知道「我現在看的活動」是哪一場?
  17. 17 Day 17|Tool 回太少做不完,回太多又把內部資料倒給 Agent
  18. 18 Day 18|活動服務暫時失敗時,Agent 應該重試還是停下來?
  19. 19 Day 19|同一場活動收藏兩次,網站為什麼只能留下同一筆?
  20. 20 Day 20|表單填好了,為什麼這次報名仍然不能算通過?
  21. 21 Day 21|一句「這個我不要了」,Agent 到底敢不敢直接取消?
  22. 22 Day 22|五支 Tool 如何共用同一套規則,串成三條完整流程?
  23. 23 Day 23|在問 Agent 聰不聰明前,先證明網站沒有壞
  24. 24 Day 24|活動摘要叫 Agent 洩漏祕密,它會把這句話當資料還是命令?
  25. 25 Day 25|localhost 成功不算交付:怎麼證明公開網址跑的是同一份程式?
  26. 26 Day 26|把自然語言送進公開站,Agent 真的會自己選對 Tool 嗎?
  27. 27 Day 27|寫入型 Tool 怎麼驗收?把 Trace、Network、UI 與 Server 狀態放在一起看
  28. 28 Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層?
  29. 29 Day 29|把網站交給 Agent 前,我最後會檢查哪十件事?
  30. 30 Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼?

Further reading

Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼? 封面圖 2026-09-30 Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼? Day 29|把網站交給 Agent 前,我最後會檢查哪十件事? 封面圖 2026-09-29 Day 29|把網站交給 Agent 前,我最後會檢查哪十件事? Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層? 封面圖 2026-09-28 Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層?

留言討論

用 GitHub 帳號留言,留言會同步到這個 Blog 的 GitHub Discussions。

閱讀導覽

約 6 分鐘

本文目錄

本篇所在系列 · 第 3 / 30 篇

別再讓 Agent 猜按鈕:30 天打造並實測 Agent-ready 的 WebMCP 活動網站

  1. Day 01|網站真的會被 Agent 使用嗎?我先丟了一句自然語言
  2. Day 02|換到全新資料夾後,網站還能不能跑?
  3. Day 03|先別急著做 Tool,我把活動網站自己走了一遍
  4. Day 04|按鈕只多包一層,哪種 Playwright Locator 撐得住?
  5. Day 05|只改按鈕四個字,Playwright 為什麼停在 click 以前?
  6. Day 06|Playwright、REST API、MCP 與 WebMCP,各自負責哪一段?
  7. Day 07|Agent 偶爾答對還不夠,我先出二十道測試題
  8. Day 08|WebMCP Tool 該怎麼設計?把「點按鈕」改成「搜尋活動」
  9. Day 09|網站該公開哪些 WebMCP Tool?從操作盤點到五支正式能力
  10. Day 10|Inspector 裝好了,為什麼 Tool 面板還是一片空白?
  11. Day 11|什麼是 Declarative API?讓 HTML 表單成為 WebMCP Tool
  12. Day 12|Tool 註冊完還不算完成:離開 route 後誰把它收回來?
  13. Day 13|第一次按下 Inspector 的 Send,先被 Gemini 429 擋在門外
  14. Day 14|五支 Tool 不再往外長:把產品範圍寫成會亮紅燈的契約
  15. Day 15|讓人類與 Agent 共用同一套活動搜尋規則
  16. Day 16|Agent 怎麼知道「我現在看的活動」是哪一場?
  17. Day 17|Tool 回太少做不完,回太多又把內部資料倒給 Agent
  18. Day 18|活動服務暫時失敗時,Agent 應該重試還是停下來?
  19. Day 19|同一場活動收藏兩次,網站為什麼只能留下同一筆?
  20. Day 20|表單填好了,為什麼這次報名仍然不能算通過?
  21. Day 21|一句「這個我不要了」,Agent 到底敢不敢直接取消?
  22. Day 22|五支 Tool 如何共用同一套規則,串成三條完整流程?
  23. Day 23|在問 Agent 聰不聰明前,先證明網站沒有壞
  24. Day 24|活動摘要叫 Agent 洩漏祕密,它會把這句話當資料還是命令?
  25. Day 25|localhost 成功不算交付:怎麼證明公開網址跑的是同一份程式?
  26. Day 26|把自然語言送進公開站,Agent 真的會自己選對 Tool 嗎?
  27. Day 27|寫入型 Tool 怎麼驗收?把 Trace、Network、UI 與 Server 狀態放在一起看
  28. Day 28|Agent 選錯、傳錯或答錯時,怎麼知道問題卡在哪一層?
  29. Day 29|把網站交給 Agent 前,我最後會檢查哪十件事?
  30. Day 30|網站終於會說話:做完五支 Tool 後,我學到什麼?
看完整系列 30 篇