ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

MCP 工具目录变了,Agent 的权限为什么不能跟着自动变?

MCP 工具目录变了,Agent 的权限为什么不能跟着自动变?

Agent 能看见一个工具,不代表它有权调用。目录刷新把query_order换成了带退款参数的新 Schema,如果授权仍只比较工具名,原先的只读许可就可能被悄悄扩大。小团队省掉的那次复核,会变成执行时没人说得清的权限。

先固定审核对象

MCP 2026-07-28 规范发布说明是 7 月资料,不能当成十月新闻。十月接入时仍应按该版本核对客户端、SDK 与工具契约。工具目录是发现机制;业务授权要另有主体、资源、动作和失效条件。官方安全建议也强调作用域收敛和代理授权风险。

我的建议是把审核过的 manifest 保存为不可变快照。摘要至少覆盖工具名、描述、输入输出 Schema、风险标记及实际后端绑定,序列化规则由团队固定。只对原始 JSON 算哈希会把键顺序变化误判成实质变化;反过来,只算名称又漏掉参数含义的改变。摘要不替代鉴权,也不是协议规定的授权字段。

一个本地可运行的拒绝条件

下面只验证“授权绑定已审查版本”的不变量,不实现 MCP 网络层。演示里的摘要直接使用受控结构序列化,实际系统还需处理 Schema 规范化与后端配置。

package main import ("crypto/sha256"; "encoding/hex"; "encoding/json"; "fmt") type Manifest struct { Name string; ReadOnly bool; Backend string } func digest(m Manifest) string { b,err:=json.Marshal(m);if err!=nil {panic(err)};h:=sha256.Sum256(b);return hex.EncodeToString(h[:]) } func allowed(reviewed string, current Manifest, userCanRead bool) bool { return userCanRead && current.ReadOnly && reviewed==digest(current) } func main(){ m:=Manifest{"query_order",true,"orders-v1"};approved:=digest(m) if !allowed(approved,m,true){panic("baseline denied")} changed:=m;changed.Backend="refunds-v2" if allowed(approved,changed,true)||allowed(approved,m,false){panic("permission expanded")} fmt.Println("reviewed accepted; changed and revoked rejected") }

本地 Go 1.26.5 执行go run .,覆盖原版本允许、后端绑定变化拒绝、权限撤销拒绝。这个结果只证明分支行为,不能证明真实凭证撤销传播速度。

缓存可以旧,授权不能靠猜

目录缓存仍展示旧工具时,调用入口应读取当前授权状态:账号禁用、租户边界、资源归属、授权版本任一不匹配就拒绝。复核时记录谁批准了哪份差异,而不是“今天刷新过目录”。对新增的写操作,重新确认业务影响和幂等要求。

发布前再做一项真实集成检查:同时更新目录并撤销凭证,旧客户端不得借缓存继续调用。本文没有连接外部 MCP 服务,不声称完成该实验。

返回列表