
【随笔】MCP工具注解的信任边界四个提示如何参与调用决策上一篇拆开了MCP协议错误与工具执行错误。接下来还有一个常见问题调用前客户端怎样知道工具会不会修改数据重复调用是否安全是否可能访问外部世界ToolAnnotations提供一组描述行为的提示。它们能帮助应用组织说明和交互但调用许可还需要结合可信来源、实际实现、用户意图与业务范围。读到一个true不能跳过这些核验。本文依据2026年10月7日查阅的MCP规范2026-07-28版本。下方Python3.12示例为应用侧策略模型在Python3.12.14实际运行它不连接MCP服务器也不冒充某个SDK提供的接口。一、注解在工具描述的哪个位置MCP工具描述包含名称、说明、输入模式等信息还可以携带annotations。模型与客户端据此了解工具的用途应用再决定怎样呈现、检查和执行。例如一个工具可以提供如下描述片段这里省略输入模式等其他字段仅观察注解位置{name:lookup_order,annotations:{title:查询订单,readOnlyHint:true,openWorldHint:false}}title是便于展示的名称。它与后面几个Hint字段一样都不会赋予工具权限。完整结构参考MCP工具规范。二、四个Hint分别提示什么字段true所提示的含义省略时的默认值readOnlyHint工具不修改环境falsedestructiveHint工具可能执行破坏性更新trueidempotentHint相同参数重复调用不产生额外效果falseopenWorldHint工具可能与开放的外部世界交互truedestructiveHint与idempotentHint仅在readOnlyHint为false时有意义。前者为false描述的是只做增加性更新仍然可能修改数据。后者提示重复调用的效果不能替代实际实现中的幂等约束。openWorldHintfalse描述封闭域不代表工具离线运行、不访问数据库或已经通过安全检查。字段的适用范围与默认值应以ToolAnnotations官方定义为准。三、把描述放在核验之前服务器提供工具描述也负责实现工具。一个不可信的服务器可以声明readOnlyHinttrue实际执行其他操作。因此注解与执行合同的来源必须分开看。规范明确提醒除非来自可信服务器客户端必须将工具注解视为不可信也不应基于不可信服务器的注解决定是否使用工具。这一要求见工具规范的注解说明与注解结构中的安全提醒。图中的核验关口表示应用自己的决策过程。注解提供描述可信工具清单、实现审查与当前请求范围提供其他判断依据。相同工具名出现在不同服务器上也应分别识别。四、一个应用侧策略示例下面把两件事分开display_hints按默认值整理展示信息decide读取应用维护的已审查记录。模拟工具描述里的Hint不参与权限决策。示例只实现几条教学规则未知工具进入核验超出本次用户意图时拒绝写操作需要对应授权结果不明的重试先核对状态。write_approved表示应用已经记录到的授权可能来自此前明确授权具体交互应与产品场景匹配。生产系统还需要验证身份、参数与数据范围并落实权限执行。这里的intent_allowed等布尔量代表这些检查的输入没有替代真正的鉴权实现。保存为annotation_policy_demo.pyApplication policy example; no MCP SDK or remote tool is invoked.fromdataclassesimportdataclass DEFAULTS{readOnlyHint:False,destructiveHint:True,idempotentHint:False,openWorldHint:True,}defdisplay_hints(annotations):return{name:annotations[name]iftype(annotations.get(name))isboolelsedefaultforname,defaultinDEFAULTS.items()}dataclass(frozenTrue)classReviewedPolicy:read_only:boolretry_contract:bool# These entries represent separately reviewed implementation contracts.REVIEWED{(internal,lookup_order):ReviewedPolicy(True,True),(internal,create_ticket):ReviewedPolicy(False,False),}defdecide(server,tool,intent_allowed,write_approvedFalse,retryFalse,outcome_unknownFalse):policyREVIEWED.get((server,tool))ifpolicyisNone:returnREVIEW_UNKNOWN_TOOLifnotintent_allowed:returnDENY_OUT_OF_SCOPEifnotpolicy.read_onlyandnotwrite_approved:returnNEED_WRITE_APPROVALifretryand(outcome_unknownornotpolicy.retry_contract):returnRECONCILE_BEFORE_RETRYreturnALLOW_BY_REVIEWED_POLICYif__name____main__:print(defaults:,display_hints({}))print(invalid-string:,display_hints({readOnlyHint:false}))print(unknown:,decide(external,claim_read_only,True))print(read:,decide(internal,lookup_order,True))print(out-of-scope:,decide(internal,lookup_order,False))print(write:,decide(internal,create_ticket,True))print(approved-write:,decide(internal,create_ticket,True,write_approvedTrue))print(uncertain-retry:,decide(internal,lookup_order,True,retryTrue,outcome_unknownTrue))执行python annotation_policy_demo.py本次实际输出defaults: {readOnlyHint: False, destructiveHint: True, idempotentHint: False, openWorldHint: True} invalid-string: {readOnlyHint: False, destructiveHint: True, idempotentHint: False, openWorldHint: True} unknown: REVIEW_UNKNOWN_TOOL read: ALLOW_BY_REVIEWED_POLICY out-of-scope: DENY_OUT_OF_SCOPE write: NEED_WRITE_APPROVAL approved-write: ALLOW_BY_REVIEWED_POLICY uncertain-retry: RECONCILE_BEFORE_RETRYfalse是字符串并非JSON布尔值false。示例只接受真实bool并为非法值使用保守默认值这是示例的展示处理方式严格的协议输入校验也可以直接拒绝非法描述。未知工具即便声称只读也进入核验。已审查的查询工具在范围内可以调用写工具只有取得对应授权后才通过。这里的规则来自应用维护的记录工具自己提供的Hint无法修改它们。五、幂等提示与失败重试怎样衔接幂等性需要实现合同。相同参数的效果要由服务实现与业务规则保证。应用可以结合已核实的合同制定重试策略不能只看到idempotentHinttrue就反复提交写请求。遇到超时调用方可能还不知道服务端是否已经执行。先查询任务状态、核对业务幂等键或结果再决定是否重试能减少重复动作。示例对结果不明的场景采用保守处理具体系统可以依据可靠的状态查询与去重机制细化。图中readOnlyHint卡片是待核对的描述。导师猫查看另一份应用记录学习猫等待核验结果这个过程强调描述与可信依据各有来源。给使用者清楚的控制入口。让用户知道可用工具、调用内容与结果并能拒绝或中止相关操作有助于检查模型的工具选择。MCP工具规范建议保留适当的人在回路与确认交互具体交互方式由应用设计注解没有规定一个统一的审批界面。六、落地时的三个检查点先按服务器身份与工具名识别工具检查版本及实际实现。更新描述或实现后原先的审查结论也可能需要重新确认。再核对参数、用户意图与数据范围。读取也可能暴露数据只读属性不等于任何查询都被允许。最后把工具执行结果与业务状态一起检查。注解无法说明这一次调用是否真正完成尤其不能代替写操作之后的状态核对。七、 思维导图MCP工具注解行为提示readOnlyHintdestructiveHintidempotentHintopenWorldHint信任边界描述不保证实现核对服务器身份应用决策已审查工具记录用户意图与参数范围写操作对应授权执行核对幂等需要实现合同结果不明先查状态八、总结总结要点注解描述预期行为。四个Hint有不同的默认值与适用范围能帮助应用呈现工具属性不能自动授予执行权限。可信依据需要独立核验。将服务器身份、工具实现、用户意图与参数范围放进应用决策避免由工具自己的声明决定是否执行。重试还要核对结果。幂等提示无法回答一次超时之后发生了什么。可靠的实现合同与业务状态才能支持下一步动作。下一篇继续看MCP进度通知长任务执行时怎样让客户端知道进展并区分进度提示与最终结果。如果你觉得这篇文章对你有所帮助欢迎点赞、收藏、分享