NextPDF Connect HITL 風險層級
每個工具都會宣告四個風險等級之一。最高等級「需核准」(approval-required)在第一次呼叫時不會直接執行;ConfirmationGate 會改為回傳一次性挑戰權杖,AI Agent(代理)必須將這個權杖轉交給人類,由人類授權後再重新呼叫。
composer require nextpdf/server概念總覽
標題為「概念總覽」的區段這個風險模型只有四個依序排列的等級:
| 等級 | 值 | 意義 | 效果 |
|---|---|---|---|
| safe(安全) | 0 | 唯讀,沒有副作用 | 自動執行 |
| caution(注意) | 1 | 建立或修改記憶體內的狀態 | 自動執行,並寫入稽核紀錄 |
| review(審查) | 2 | 產生可能被濫用的輸出 | 自動執行,並寫入稽核紀錄 |
| approval_required(需核准) | 3 | 具破壞性、涉及法律或攸關隱私 | 需要人類確認 |
一個工具的風險等級只會來自兩個地方:工具本身的宣告,以及選用的維運者組態覆寫。沒有第三個來源。這個模型帶有版本號,而 MCP 的 initialize 回應會公開這個版本號,讓用戶端能偵測不相容的變更。稽核紀錄會套用在 caution 以上等級。
將自動化動作擱置到人類授權後才繼續,正好把控制點放在自動化引入風險的位置。這正是 IEC 31010 為控制由人類行為所引入的風險而指出的位置:就在風險引入點或其附近(IEC 31010:2019)。
API 介面
標題為「API 介面」的區段ConfirmationGate(確認關卡)
標題為「ConfirmationGate(確認關卡)」的區段當一個 approval_required 工具在沒有有效權杖的情況下被呼叫時,這道 gate 會發出一個挑戰。這項檢查會回傳下列兩種結構之一。
{ "allowed": true }或是
{ "allowed": false, "challenge": "<human-readable text>", "token": "confirm_<nonce>" }挑戰文字會點出該操作及其說明,並在目標檔案會被覆寫時提出警告。它會指示呼叫端將 _confirmation_token 參數設為所發出的權杖,並重新呼叫同一個工具。這個權杖會在 300 秒後過期。
權杖的綁定方式是刻意設計的:權杖會綁定工具名稱、一個隨機 nonce,以及 TTL ——而非綁定引數。重試時,MCP 用戶端可能以不同的鍵排序或正規化方式重新序列化引數;因此,若對引數做雜湊,反而會破壞合法的確認流程。這個權杖是一次性的;在重新呼叫時消耗它,正好只允許該呼叫執行一次。
各傳輸層的呈現方式
標題為「各傳輸層的呈現方式」的區段凡是會驅動工具的傳輸層,都會強制執行這道 gate:
- **MCP:**挑戰會以成功的 JSON-RPC 回應在頻道內回傳,內容就是挑戰文字。呼叫端會重新呼叫
tools/call,並帶上arguments._confirmation_token。 - **REST 與 gRPC:**同一道 gate 會在共用的工具執行器中,於
approval_required操作之前執行。挑戰會出現在操作回應中;呼叫端再帶著權杖重複該操作。
內建的降級保護
標題為「內建的降級保護」的區段組態覆寫可以提高工具的風險等級,但永遠不能調降原本就設計為 approval_required 的工具。組態載入器會強制套用一組固定的鍵集合;如果覆寫試圖降級,就會在載入時拋出例外。伺服器寧可拒絕啟動,也不會在 gate 被削弱的狀態下執行。
程式碼範例 —— 快速上手
標題為「程式碼範例 —— 快速上手」的區段用 output_pdf 寫入檔案以觸發一次挑戰:
./vendor/bin/nextpdf-mcp <<'EOF'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"c","version":"1.0.0"}}}{"jsonrpc":"2.0","method":"notifications/initialized"}{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"output_pdf","arguments":{"document_id":"<id>","file_path":"/var/lib/nextpdf/tmp/out.pdf"}}}EOF回應會是該挑戰,而不是檔案。請帶著所發出的權杖重新呼叫:
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"output_pdf","arguments":{"document_id":"<id>","file_path":"/var/lib/nextpdf/tmp/out.pdf","_confirmation_token":"confirm_<nonce>"}}}程式碼範例 —— 正式環境
標題為「程式碼範例 —— 正式環境」的區段若要強化部署,請將一個原本是 caution 的工具提高為 approval-required:
nextpdf_mcp: risk_level_overrides: add_image: 3 # require human confirmation for image insertion降級會在載入時遭到拒絕,伺服器也不會啟動。舉例來說,把 output_pdf 設成低於 3 就是一種降級。
邊緣案例與陷阱
標題為「邊緣案例與陷阱」的區段-
**
output_pdf在 base64 模式下不會觸發 gate。**寫入磁碟屬於 approval-required;將 PDF 以 base64 回傳(不帶file_path)會被視為較低風險,不需要確認即可執行。 -
**這個權杖不是憑證。**它不會驗證呼叫端的身分,也不會在連網的傳輸層上取代 API 金鑰。它只會在 300 秒內放行一次受 gate 管控的特定呼叫。
-
**每次都是新的挑戰。**如果沒有轉交權杖,或讓權杖過期,並不會永久封鎖該工具;下一次呼叫會發出一個全新的挑戰。權杖會存放在一次性權杖儲存區中,並會定期進行垃圾回收。
-
**不論結果如何都會稽核。**發出挑戰、成功執行,以及 caution 以上等級的失敗執行,都會連同工具名稱與風險等級一起寫入稽核紀錄。
這道 gate 會增加一次權杖儲存區查詢,並在發出挑戰時額外產生一次隨機權杖。相較於受 gate 管控操作本身的成本,這項開銷微不足道,而且只會對 approval_required 工具執行。
安全性說明
標題為「安全性說明」的區段這道 gate 是一種圍堵控制,而不是身分驗證控制。即使工具由自主代理(agent)驅動,它也能確保具破壞性、涉及法律或攸關隱私的動作必須由人類授權。對這些操作,伺服器並未宣稱可在沒有人類監督的情況下運作,而且組態也無法削弱這道 gate。在連網的傳輸層上,請將它與 API 金鑰模型結合,並透過 enabled_tools 控制最小權限範圍。請參閱 /connect/security-and-operations/。
符合性
標題為「符合性」的區段| 聲明 | 來源 | reference_id |
|---|---|---|
| 在(人類)引入風險的那一點控制風險 | IEC 31010:2019 |
風險模型版本會帶在 MCP 的 initialize 回應中,讓用戶端能偵測不相容的變更。其線路格式記載於 /transports/mcp/。
商業情境
標題為「商業情境」的區段Premium 工具會使用同一套四級模型宣告自己的風險等級。具破壞性的 Premium 操作(例如塗黑遮蔽)會由完全相同的機制把關。這道 gate 是伺服器的一部分,而不是 Premium 套件的一部分。
另請參閱
標題為「另請參閱」的區段- /connect/tool-catalog/ —— 每個已驗證核心工具的風險等級
- /connect/configuration/ —— 只能提高的風險覆寫
- /connect/security-and-operations/ —— 這道 gate 如何契合威脅模型
- /transports/mcp/ —— 頻道內挑戰的線路格式
- /connect/overview/ —— 這道 gate 在架構中的位置