iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Modern Web

WebMCP:30 天打造 AI Agent 看得懂、也操作得動的網站系列 第 17 篇

Day 17|查資料、加購物車、刪帳號不能同權限:WebMCP Tools 風險分級

  • 分享至 

  • xImage
  •  

本篇重點

如果所有 Tool 都只有「可以呼叫/不可以呼叫」兩種狀態,安全設計很快會失控。search_posts、add_to_cart、delete_account 都是 Tool,但副作用、可逆性、資料敏感度完全不同。

今天做一張 Tool Risk Matrix,把能力分成 Read、Navigation、Reversible Action、Consequential Action,並對應 WebMCP annotations 與後端權限策略。

這四級是本文整理的設計分類,不是 WebMCP 官方定義的權限等級。實際風險還要一起考慮資料敏感度、操作範圍與使用情境。

先把 Tools 列出來

目前系列已經有:

get_page_info
search_content
get_content
navigate_to_section
prepare_contact_message
add_to_favorites
prepare_checkout
confirm_checkout

如果只寫:

這些都是 Agent Tools

資訊太少。

我先用四級分類

Level 1:Read

不修改業務資料,但可能更新畫面上的查詢結果:

search_content
get_content
get_product
get_cart

通常:

annotations: {
  readOnlyHint: true
}

但「read-only」不代表沒有隱私風險。

get_cart 可能透露使用者興趣;get_orders 更可能透露地址、消費紀錄。

所以資料權限仍要檢查。

Level 2:Navigation / UI State

例如:

navigate_to_section
open_filter_panel

對 Server 沒有永久副作用,但會改目前 UI/route。

通常風險低,但要避免釣魚式跨 Origin 導航或意外離開未儲存頁面。

Level 3:Reversible Action

例如:

add_to_favorites
add_to_cart
remove_from_cart
save_draft

會改狀態,但通常可逆。

需要依業務規則考慮:

  • 身分或 Session 辨識,以及資料存取權限。
  • 重複呼叫會造成什麼結果,以及如何避免非預期重複操作。
  • 清楚的 Result 與 UI 狀態同步。
  • 如何撤回,以及撤回的限制。

例如訪客購物車可以使用 Session,不一定要求會員登入。加入收藏可以設計成重複不變,但 add_to_cart 通常會累加數量;「可逆」不等於「冪等」。

Level 4:Consequential Action

例如:

confirm_checkout
delete_account
publish_post
transfer_money
book_flight

會造成真實、重大或難逆轉的結果。

這類 Tool 應考慮:

annotations: {
  readOnlyHint: false,
  consequentialHint: true
}

並配合 Explicit Confirmation。

📸 圖片 1|WebMCP Tools 的四級風險矩陣
https://ithelp.ithome.com.tw/upload/images/20260926/201212963JDLFLZABZ.png

再加一個維度:輸出是否不可信

假設:

search_reviews
get_forum_posts
fetch_external_content

即使它們都是 Read,輸出可能包含 Prompt Injection。

因此可以加:

untrustedContentHint: true

這跟「有沒有副作用」是另一條軸。untrustedContentHint 只標示輸出需要謹慎處理,不會自動清除惡意文字,也不能保證擋下 Prompt Injection。本日 search_reviews 使用固定的模擬評論示範這個標記。

所以 Tool Risk 不是一個單純 Enum,而比較像:

State-changing?
Consequential?
Contains untrusted output?
Contains private data?
Requires authentication?

建一張 Matrix

下面是設計示例,不是所有網站都必須採用的固定政策。Auth 的 Session 表示需要辨識目前購物車的擁有者,不一定是已登入會員;本日 Demo 則選擇用模擬登入展示存取限制。△ 代表依資料來源判斷,不是 annotation 的第三種值。

Tool Read-only 可逆 Consequential Untrusted output Auth
search_products ✅ - ❌ △ ❌
get_cart ✅ - ❌ ❌ Session
add_to_cart ❌ ✅ ❌ ❌ Session
search_reviews ✅ - ❌ ✅ ❌
confirm_checkout ❌ 依取消/退款規則 ✅ ❌ ✅
delete_account ❌ 依復原機制 ✅ ❌ ✅

這張表會直接影響:

要不要確認
要不要登入
要不要記 audit log
Tool 能不能跨 Origin 暴露
Result 能不能包含私人資料

公開搜尋可以直接使用

在本地 Demo 中,Guest 可以呼叫 search_products,傳入 {"keyword":"外套","color":"黑色","maxPrice":2000},取得兩筆公開商品。這個操作不會修改購物車,也不需要登入。

📸 圖片 2|Guest 可直接搜尋公開商品
https://ithelp.ithome.com.tw/upload/images/20260926/20121296RUEzdGP2CE.png

唯讀資料,也可能需要身分檢查

同樣是 Guest,以 {} 呼叫 get_cart,Demo 會回傳 unauthenticated。雖然 get_cart 標記 readOnlyHint: true,購物車仍可能包含私人資訊,因此本例要求先登入。

九個 Tools 在 Guest 狀態下仍然可見;限制是在執行時檢查,而不是靠隱藏 Tool 名稱。

📸 圖片 3|未登入讀取購物車,回傳 unauthenticated
https://ithelp.ithome.com.tw/upload/images/20260926/20121296hgHEsC4sqp.png

修改購物車,要知道改了什麼

按下「模擬登入」後,以 add_to_cart 加入商品 102 的 M 號一件:

{"productId":102,"variationId":"102-M","quantity":1}

成功結果包含尺寸、數量與小計 NT$1,890。這次呼叫確實修改了購物車;若要撤回,可用 remove_from_cart 傳入 {"variationId":"102-M"},移除整個尺寸項目。

再次執行 add_to_cart 會累加數量,因此不能把重試視為沒有副作用。

📸 圖片 4|模擬登入後,add_to_cart 成功加入 M 號外套一件
https://ithelp.ithome.com.tw/upload/images/20260926/20121296UAnhSeJs6M.png

重大操作,確認的是實際後果

購物車有一件商品後,以 {} 呼叫 prepare_checkout,會得到小計 NT$1,890、運費 NT$60、總額 NT$1,950 的預覽。再把回傳的 previewId 交給 confirm_checkout,網站會顯示商品明細與確認按鈕。

這時 Tool 正在等待使用者選擇,尚未建立訂單。按「確認並模擬下單」才會建立模擬訂單;按「取消」則回傳 cancelled。

📸 圖片 5|網站顯示商品與總額,等待使用者確認
https://ithelp.ithome.com.tw/upload/images/20260926/201212961c4LRgeijd.png

這個視窗由網站程式提供,不是 consequentialHint 自動產生的瀏覽器確認介面。Demo 用模擬下單呈現高風險流程,不會實際扣款,也沒有實作刪除帳號。

以上圖片是 Inspector 手動呼叫結果;模擬登入、購物車與訂單都只存在本頁記憶體,不能視為已驗證真正的後端授權。重新整理或模擬登出會清空資料。

annotations 不是 Security Policy Engine

這點一定要重複。

consequentialHint: true

並不等於後端自動安全。

例如在 WordPress 中,後端仍需執行權限檢查:

if (! current_user_can('delete_users')) {
    return new WP_Error('forbidden', 'Not allowed', ['status' => 403]);
}

上面只是管理使用者功能的權限檢查片段,不是「使用者刪除自己帳號」的完整實作。實際操作還要驗證目標帳號、請求來源、確認流程及適用的業務限制。

WebMCP annotations 是給 Agent/Browser 的安全語意,不是 ACL(存取控制清單)。前端的模擬登入旗標和確認按鈕,也不能替代後端的身分與授權檢查。

我會替每個 Tool 寫「權限契約」

例如:

Tool: get_orders

Authentication:
Required

Authorization:
Only current user's orders

Side effect:
None

Sensitive output:
Order history, partial address

Cross-origin exposure:
No

Confirmation:
No

這比只寫一個 Description 更接近 Production Design。

可帶走的重點

  1. Read-only 不等於沒有隱私風險。
  2. 可逆 Action 和高風險 Consequential Action 不應用同一套 UX。
  3. readOnlyHint、consequentialHint、untrustedContentHint 是不同維度。
  4. annotations 不能替代 Server Authentication/Authorization。
  5. 正式導入前建一張 Tool Risk Matrix 很值得。

參考資料


上一篇
Day 16|50 個按鈕做成 50 個 Tools?這是最容易讓 Agent 變笨的設計
下一篇
Day 18|只改一行 Description,AI 就選錯 Tool?實測 Tool Description 的 A/B 方法
系列文
WebMCP:30 天打造 AI Agent 看得懂、也操作得動的網站 共 20 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言