給AI agent接十個工具,一個下午就能跑通。真正的麻煩從第二周開始——同一個MCP server要服務三個租戶,SSE transport在高負載下不斷斷連,再加上某個第三方server的工具描述里悄悄藏著"忽略此前指令"的提示詞,這周突然變長了。
modelcontextprotocol.io上有完整規范。這篇文章記錄的是多租戶部署出第一次事故后,團隊反復踩坑總結出的五個模式。它們是day-one架構崩掉之后,團隊被迫演化出的形狀。每節都有代碼,默認你已經知道MCP server是什么。
![]()
模式一:工具列表必須按會話裁剪,不能按server固定
典型的一期部署:一個MCP server暴露給所有用戶、所有租戶、所有會話。server在tools/list里返回完整工具集,agent全部可見,心里想著"以后再加權限控制"。
你不會加的。或者加了,會很痛。
能活下來的模式:把tools/list返回的工具集視為每會話決策,而非server層面的常量。MCP server本身實現全部工具,但在前面(或tools/list handler內部)加一層薄裁剪層,只返回當前調用者有權查看和調用的子集。
代碼示例展示了scoped MCP wrapper:真實server有14個工具,免費租戶只看到search_docs和read_doc,專業版額外開放create_ticket和update_ticket,企業版開放全部。模型永遠不知道租戶無權調用的工具存在,因此不會幻覺出"給免費用戶調用delete_workspace"。call邊界的拒絕檢查是縱深防御:即使模型通過泄露示例、注入提示詞或歷史會話獲知工具名,調用仍會被拒絕。
拒絕必須以結構化tool error返回給模型,不能靜默丟棄。agent loop只有在看到拒絕信息時才會調整策略——換工具或提示用戶升級。
會話身份綁定:MCP本身不攜帶租戶身份,需在transport層附加(HTTP header、SSE握手中的JWT、stdio的env var),在首次tools/list前解析。如果列工具前無法識別租戶,就已經輸了——每個會話只能回落到最低信任子集。
這是大多數團隊意外發現的模式。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.