MCP ToolAnnotations 上线前怎么核对:四个 Hint 的实测与拦截
来源:17golang原创
时间:2026-08-16 15:52:18 195浏览 收藏
一个 MCP 服务把「删除测试数据」和「查询订单」能力都开放给大模型调用后,真正要校验的核心不是工具名称,而是调用端能否准确识别这些工具的行为边界。MCP 的 ToolAnnotations 提供了 readOnlyHint、destructiveHint、idempotentHint 和 openWorldHint,但官方规范同时明确说明:这些字段仅作行为提示,不代表工具实际运行时一定会严格符合声明的特性。
- readOnlyHint=true 仅表示工具设计目标是不修改运行环境,绝对不能直接替代服务端鉴权和操作审计流程。
- destructiveHint 只有在工具不满足只读属性时才具备参考意义,不能靠单一的“安全”标签掩盖工具的删除类操作能力。
- idempotentHint 用于标注重复调用是否会产生额外副作用,重试策略必须以真实业务运行结果为判定依据。
- 来自不可信 MCP 服务端的注解内容,不能作为调用端自动放行、跳过人工确认或降低审批等级的判断依据。
先把“工具描述”与“权限控制”拆开
ToolAnnotations 解决的是「调用端如何准确理解工具行为特征」的问题,完全不等同于「谁有权限调用这个工具」的规则定义。一个工具可以对外正确声明自己会修改环境状态,但最终能否执行文件删除操作,仍然要由服务端身份校验、参数合法性校验和业务授权规则共同决定。反过来,哪怕工具标注了只读属性,调用端也不能因此跳过对应的风险确认步骤。
安全验收环节首先要整理两份清单:一份是工具注册时对外公示的注解配置,另一份是服务端实际执行逻辑对应的真实行为路径。测试人员要主动排查两份清单存在不一致的场景,大模型和调用端能看到的只有第一份清单,而最终会对业务系统造成实际影响的是第二份清单对应的逻辑。

readOnlyHint:只读声明要用副作用测试证明
官方 Schema Reference 对 readOnlyHint 的定义是:值为 true 时,工具不会修改其运行环境。验收流程不能只核验返回的 JSON 里有没有配置这个字段,需要构造一组调用前后的状态对比校验逻辑:数据库关键表行数、指定文件哈希值、队列堆积长度、关联外部系统的状态都要保持完全一致。
常见的认知误区是把“写入审计日志”当成完全无副作用。审计类日志属于可预期的内部埋点动作,但如果工具调用会触发计费扣费、发送业务消息、刷新全局缓存或者创建后台远端任务,就不能将其归类为严格意义上的只读工具。注解内容必须和真实业务影响保持匹配,描述存在模糊空间的时候,宁可不要标注只读属性。
只读工具的验收表
| 检查项 | 测试动作 | 通过标准 |
|---|---|---|
| 数据状态 | 调用前后比对核心业务记录 | 不存在新增、删除和更新操作 |
| 外部动作 | 观测消息推送、计费和远端任务生成情况 | 没有触发额外业务类动作 |
| 注解一致性 | 核对 tools/list 接口返回值 | readOnlyHint 字段和实测结果完全匹配 |
| 失败路径 | 传入无效参数后重复发起调用 | 错误场景下不会留下任何半成品状态 |
destructiveHint:删除、覆盖和不可逆动作要单独拦截
规范把 destructiveHint 定义为工具可能对环境执行破坏性更新;值为 false 时,工具只会做追加类更新,而且这个属性只有在 readOnlyHint=false 的场景下才具备参考意义。调用端的审批流程可以借助这个字段提升风险提醒等级,但绝对不能只凭这个字段的取值决定是否直接放行调用。
例如「创建草稿内容」通常属于可追加的低风险动作,「覆盖生产配置项」「删除业务对象」「发送正式通知」这类操作就要进入高风险管控分支。测试环节要覆盖空参数、边界参数和重复参数场景,验证服务端仍然可以正常拦截所有越权访问的目标。工具注解写得越偏向安全,越需要用真实调用验证它不存在未声明的隐藏执行路径。

idempotentHint:幂等不是“失败了就能随便重试”
idempotentHint 为 true 时,规范想要表达的含义是:使用完全相同的参数重复调用工具,不会对环境产生任何额外的影响。它和 HTTP 状态码、调用端重试次数没有直接绑定关系。创建订单操作如果第二次调用会生成全新的订单记录,就不能标注为幂等;设置同一个配置值、按唯一键写入同一个资源这类操作,才符合幂等语义的要求。
验收过程中要记录第一次和第二次调用后的资源变化情况,不能只比对两次调用返回的文本内容。对接外部系统的场景还要校验请求流水号、唯一约束和补偿动作逻辑;如果服务端本身无法识别重复请求,调用端就必须保留人工确认环节或者配置更严格的重试策略。
openWorldHint:开放世界意味着更高的不确定性
openWorldHint 表示工具可能和外部实体或者开放环境发生交互。官方示例把网页搜索归类为开放世界交互工具,把封闭可控范围内的记忆工具归类为非开放世界交互工具。这个字段不是「网络访问许可」的标识,但可以帮助调用端判断是否需要更谨慎地展示调用目标、来源信息和审批提示。
如果一个工具同时需要访问外部 API 和修改本地业务数据,建议把两类能力拆分成独立的不同工具,不要依赖四个布尔字段去解释混合在一起的复杂风险。工具粒度拆分得越清晰,后续的授权、审计和用户确认流程越不容易出问题。
不可信注解不能替代客户端确认
MCP 官方规范明确提醒,调用端不应该根据来自不可信服务端的 ToolAnnotations 内容自动做工具调用决策。落地过程中至少要搭建三道防线:服务端完成身份和参数授权校验,调用端清晰展示工具名称、操作目标和风险等级,平台侧对高风险动作保留人工确认或者策略拦截能力。
上线前可以特意部署一个「声明为只读、实际会写入数据」的测试工具,验证调用端不会因为 readOnlyHint=true 就直接自动放行。这个测试的价值很高,它能验证整个系统面对错误的声明配置时,默认的安全姿态仍然是偏保守的。
常见问题
readOnlyHint=true 后,客户端可以跳过权限检查吗?
不可以。它只是一个行为提示字段,权限校验仍然要由服务端鉴权、参数校验和业务规则共同决定。
destructiveHint=false 是否代表工具绝对安全?
不代表。规范把它定义为仅做追加式更新的提示,调用端仍然需要考虑操作目标范围、关联外部系统特性和服务端的真实执行逻辑。
idempotentHint=true 就可以无限重试吗?
不可以。它仅描述相同参数重复调用不会产生额外的环境影响,限流规则、超时机制、下游依赖系统状态和业务成本仍然要单独评估处理。
为什么要把一个复杂 MCP 工具拆成多个工具?
拆分后每个工具的操作目标、权限范围、副作用特征和审批条件都会更清晰,调用端也不需要用一个模糊的注解去解释查询、写入和外部调用混合在一起的风险。
用“声明—实测—拦截”完成上线验收
最终验收不要停留在 schema 差异比对层面:先核查所有注解的声明内容,再用全量状态快照验证真实的副作用表现,最后模拟不可信服务端返回和传入高风险参数,确认调用端和服务端的管控逻辑仍然可以正常拦截违规操作。MCP 注解可以提升工具的可理解性,但真正的安全边界始终落在授权、参数校验、用户确认和审计链路这些基础能力里。
-
346 收藏
-
443 收藏
-
251 收藏
-
144 收藏
-
413 收藏
-
320 收藏
-
426 收藏
-
407 收藏
-
452 收藏
-
312 收藏
-
433 收藏
-
科技周边 · 人工智能 | 6小时前 | go · 人工智能 · Gemini API · 函数调用 · 多轮对话 · Go 函数调用 工具链 Gemini 3 thoughtSignature Interactions API202 收藏
-
科技周边 · 人工智能 | 8小时前 | openai · Responses API · AI应用开发 · OpenAI Responses API 上下文压缩 compaction conversation state428 收藏
-
217 收藏
-
216 收藏
-
科技周边 · 人工智能 | 1星期前 | go · Context · 流式处理 · 人工智能 · openai api · sse · 重试 · OpenAI Go context 流式输出 SSE Responses API 断线重试236 收藏
-
303 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习