第 13 周:接入第一个只读 MCP 工具
直接答案: 第一个 MCP 工具应该只解决一个已经证实的跨系统读取问题,而且默认没有写能力。MCP 可以标准化 Host、Client 与 Server 之间的能力交换,但它不会替你完成业务授权:身份必须来自可信会话,权限必须在模型之外执行,工具参数和结果都要受限。第 13 周的通过证据不是“模型成功调用了工具”,而是获授权用户读到了恰好需要的字段,无权限、超时或异常时系统安全停下,并且外部写效果始终为零。
为什么现在才接 MCP
标题“为什么现在才接 MCP”第 12 周已经回答了“RAG 能否在当前语料、角色和评测集上有依据地回答或停下”。现在出现的是一个更窄的问题:客服为了判断政策是否适用,仍要手工从工单系统复制地区、购买时间和任务类型。
只有下面这条证据链成立,才值得增加工具:
业务决定:是否继续受控探索政策确认流程 → 一线任务:客服必须核对工单上下文后才能选政策 → 已有证据:上下文位于另一个受权限保护的系统 → 最小改变:只读取得三个必要字段 → 工程证明:服务端授权、字段最小化、失败可诊断、写效果为零如果字段已经可靠地存在于当前请求中,或者跨系统读取不会改变任务,第一个合格决定可能是“不接 MCP”。自己的案例没有获准探索工具时,保留这个决定,再用本页的北辰合成案例训练能力;两套证据不能混写。
先看完成品:北辰只读工单上下文工具
标题“先看完成品:北辰只读工单上下文工具”“北辰协作”及下列人物、工单、系统状态和结果全部是教学合成材料。它们展示合同和判断方法,不代表真实客户交付。
原始任务
标题“原始任务”普通客服周宁正在处理合成工单 NS-1042。第 12 周的 RAG 系统需要任务类型、地区和购买时间才能判断政策是否适用,但不应看到客户姓名、付款明细或主管备注。
用户界面只提交业务对象标识:
{ "case_id": "NS-1042", "fields": ["task_type", "region", "purchased_at"]}tenant_id、user_id 和角色不在模型可填写的参数里。Host 从已经认证的合成会话取得它们,并作为可信调用上下文传给受控 Client。模型可以建议查询哪个工单,不能把自己改成主管。
完成的只读合同
标题“完成的只读合同”| 合同项 | 北辰示例值 | 为什么需要 |
|---|---|---|
| 工具名与版本 | case.lookup_context@1 |
能冻结测试和审批所针对的能力 |
| 效果分类 | read_only |
明确禁止创建、修改或删除业务状态 |
| 允许参数 | case_id、封闭的 fields 枚举 |
不让模型添加租户、角色、URL 或任意查询 |
| 身份来源 | Host 的可信会话 | 用户输入和模型输出不能授予身份 |
| 服务端授权 | 按租户、角色、对象和字段再次判断 | 前端隐藏与提示词限制都不算授权 |
| 结果上限 | 一张工单、三个允许字段 | 防止把整条客户记录带入模型上下文 |
| 时间边界 | 调用合同中的明确 deadline | 超时后进入类型化失败,不无限等待 |
| 来源信息 | 记录版本和读取时间 | 后续能判断上下文是否过期 |
| 错误 | 无权限、参数错误、不可用、超时、版本不兼容 | 不让模型把所有失败都猜成“没找到” |
成功结果
标题“成功结果”{ "status": "ok", "case_id": "NS-1042", "context": { "task_type": "plan_upgrade_price_difference", "region": "CN", "purchased_at": "2026-08-11T03:20:00Z" }, "source": { "record_version": "case-v7", "read_at": "2026-08-25T02:15:00Z" }}RAG 随后使用原有角色 ACL 检索政策,并返回有引用回答、拒答或升级。工具读取成功不代表答案正确;第 12 周的引用、权限和拒答门仍然有效。
失败结果必须可区分
标题“失败结果必须可区分”| 输入或环境 | 期望状态 | 用户看到什么 | 不能发生什么 |
|---|---|---|---|
| 普通客服读取自己的普通工单 | ok |
三个字段与来源版本 | 返回整条工单正文 |
普通客服请求 supervisor_note |
invalid_argument 或安全拒绝 |
“请求字段不允许” | 模型自动扩大字段集 |
| 访问其他租户或不可见对象 | not_available |
对象不可用或无权访问 | 暴露对象存在、主管备注或租户信息 |
| Server 超过 deadline | deadline_exceeded |
暂不可用并保留人工路径 | 根据旧记忆补写工单字段 |
| Server 返回超过合同的记录数 | contract_violation |
结果被拒绝并记录安全事件 | 截断后继续当正常结果使用 |
错误示例是:工具返回 404 后,模型说“这张工单不存在”。如果对象只是对当前用户不可见,这句话已经泄露了系统内部判断。安全结果应统一表达为“不可用或无权访问”。
最小心智模型:协议、能力和授权不是一回事
标题“最小心智模型:协议、能力和授权不是一回事”用户会话 ↓ 提供可信身份与租户MCP Host ── 允许哪些 Server 和工具 ──> MCP Client ──> MCP Server │ │ │ 模型只能提议调用 └─ 服务端再次授权、限制字段 └─ 策略决定是否允许
工具结果 ── 仍是不可信数据 ──> RAG 验证、拒答或升级记住三个决策规则:
- MCP 是否必要: 没有跨系统能力缺口,就不接工具。
- 谁能做什么: 身份来自可信会话;权限由确定性策略和目标 Server 判断;模型不参与授予。
- 失败后怎样说: 不知道就是不知道。超时、无权限和没有记录可以对用户使用相近的安全表达,但审计中要保留类型化原因。
MCP Server 提供的工具描述、输入模式和结果也不能自动被信任。第 13 周先冻结已评审版本;第 15 周再系统地攻击这些边界。
第 1 天:先决定是否需要这个工具
标题“第 1 天:先决定是否需要这个工具”新建 task-tool-decision.md,不要先写工具名:
# Task / Tool Decision(北辰教学模拟)
- 使用的 Discovery Brief / 决定版本:- 一线角色与任务:- 缺少的跨系统信息:- 当前人工取得方式:- 只读后会改变哪个任务步骤:- 不接工具的替代方案:- 允许读取的最小字段:- 禁止字段与外部效果:- 什么证据会取消本次工具探索:完成后用一句话检验:
为获授权客服读取指定工单的任务类型、地区和购买时间,以便已有 RAG 候选判断政策适用性;不读取客户正文、主管备注,不创建或修改任何记录。
如果这句话仍是“让 Agent 更智能”或“连接企业数据”,范围还没有缩到可测试任务。
第 2 天:画信任边界并写封闭合同
标题“第 2 天:画信任边界并写封闭合同”在 trust-boundary-v1.md 中分别标出:
- 可信会话中的身份、租户和角色;
- 模型可以提议但不能决定的参数;
- Host 的 Server 与工具允许列表;
- Server 的对象和字段授权;
- 不可信的用户文本、检索内容、工具描述和工具结果;
- 普通遥测与受限证据存储的边界。
然后完成 mcp-read-contract-v1.json。这是一份合同产物,不要求使用某种语言或 SDK,但必须能映射到你实际采用的模式校验器:
{ "tool": "case.lookup_context", "version": "1", "effect": "read_only", "arguments": { "case_id": "required string", "fields": "array from fixed enum, 1..3 items", "additional_properties": "reject" }, "trusted_context": ["tenant_id", "user_id", "role"], "result_limit": { "records": 1, "fields": 3 }, "errors": [ "invalid_argument", "not_available", "deadline_exceeded", "contract_violation", "version_mismatch" ]}不要照抄字符串后宣称工具已经实现。你的实现证据应是实际 Server 暴露的模式、版本摘要和测试输出;本页只给出完成合同的形状。
第 3 天:把身份和字段限制放到模型之外
标题“第 3 天:把身份和字段限制放到模型之外”检查调用路径时逐项问:
- 用户身份能否被工具参数覆盖?如果能,移除该参数。
- Host 是否只连接已评审的 Server 身份和版本?如果不是,默认禁用。
- Server 是否按当前调用者重新判断对象和字段?如果只相信 Host 的提示文字,未通过。
- 模式是否拒绝未知字段?如果悄悄忽略,参数走私会变得难以发现。
- 返回结果是否经过字段允许列表和数量上限?如果只靠模型“不要看”,未通过。
为每个判断保存可检查证据,例如模式快照、策略决定、类型化响应和外部状态计数。不要把截图当成唯一证据。
第 4 天:用五类夹具证明它真的只读
标题“第 4 天:用五类夹具证明它真的只读”创建测试表,并把实际结果填入“观察结果”:
| case_id | 测试条件 | 期望结果 | 观察结果 | 外部写效果数 |
|---|---|---|---|---|
| R-01 | 合法对象、三个允许字段 | ok,字段和版本完整 |
0 | |
| R-02 | 请求主管字段 | 参数拒绝 | 0 | |
| R-03 | 跨租户对象 | 安全不可用,不泄露存在性 | 0 | |
| R-04 | Server 超时 | 明确不可用,不猜答案 | 0 | |
| R-05 | 结果超过合同 | 拒绝整个结果并记录原因 | 0 |
然后从第 12 周评测集中选择与工单上下文相关的可回答、受限、冲突和无答案样本,重跑同一系统版本。报告分母和逐例结果;不要只展示成功问题。
第 5 天:冻结能力并作出继续决定
标题“第 5 天:冻结能力并作出继续决定”mcp-capability-manifest-v1.json 至少记录:
- MCP 规范、SDK 或实现的实际版本与核验日期;
- Host、Client、Server 的身份和部署摘要;
- 工具名、版本、模式摘要和效果分类;
- 使用的策略、RAG、语料与评测版本;
- 结果上限、deadline 和错误类别;
- 本周测试报告及未通过项;
- 继续、缩小、禁用或停止的决定人和条件。
如果实现无法证明身份来源、服务端授权或零写效果,合格结论是禁用该工具,而不是降低验收门。
五天安排
标题“五天安排”| 学习日 | 建议时间 | 当天动作 | 离开前必须有的结果 |
|---|---|---|---|
| 第 1 天 | 1–1.5 小时 | 从 Brief、一线任务和失败登记判断工具是否必要 | task-tool-decision.md,能说明不用 MCP 的替代项 |
| 第 2 天 | 1.5–2 小时 | 写信任边界、只读合同和类型化错误 | 工具参数、可信上下文和失败状态没有混写 |
| 第 3 天 | 2–2.5 小时 | 将身份、对象和字段授权落实到模型之外 | 可检查的模式、策略和结果限制证据 |
| 第 4 天 | 2 小时 | 跑五类只读夹具并核对外部状态 | 正常与失败逐例结果,写效果均为 0 |
| 第 5 天 | 1–2 小时 | 重跑相关 RAG 回归、冻结能力并做三层回读 | 能决定继续、缩小、禁用或停止 |
本周产物
标题“本周产物”fde-course/└─ week-13/ ├─ task-tool-decision.md ├─ mcp-tool-catalog-v1.md ├─ mcp-read-contract-v1.json ├─ trust-boundary-v1.md ├─ mcp-capability-manifest-v1.json └─ read-tool-test-report-v1.md工具目录至少区分:用途、业务任务、效果分类、允许角色、字段范围、版本、deadline、结果上限、错误、所有者和禁用方式。空表不是完成证据,必须有北辰完成例和你的实际版本。
验收与失败修复
标题“验收与失败修复”本周通过需要同时满足:
- 有证据说明为什么这个跨系统读取值得存在;
- 系统没有向模型注册或执行任何写工具;
- 协议或实现版本、Server 身份、工具版本和模式摘要可复核;
- 未知参数被拒绝,结果量和执行时间有明确上限;
- 身份和租户来自可信会话,不能由模型参数覆盖;
- 目标 Server 重新执行对象与字段授权;
- 无权限响应不泄露对象存在性、正文或敏感元数据;
- 超时和工具失败不会被补写成确定答案;
- 第 12 周的权限、引用和拒答回归没有退化;
- 普通日志没有工单正文、秘密或个人信息;
- 所有夹具的外部写效果数都是 0。
| 常见失败 | 诊断信号 | 修复动作 |
|---|---|---|
| 模型提供租户或角色 | 参数中出现 tenant_id、role |
从模式删除,改用可信会话并在 Server 重验 |
| 工具返回完整工单 | 模型上下文出现客户正文或主管备注 | 改为字段允许列表和单记录上限 |
| 404 泄露受限对象 | 用户能区分“不存在”和“无权访问” | 统一安全外部状态,详细原因只进受限审计 |
| 超时后继续猜 | 回答出现工具没有返回的字段 | 将运行转为暂不可用、拒答或人工升级 |
| 只检查调用成功 | 报告只有 HTTP/MCP 成功,没有业务字段和外部状态 | 同时核对响应、权限决定、RAG 终态和写效果数 |
| 为学 MCP 硬造需求 | 工具没有改变任何已证实的一线步骤 | 删除工具,保留 no-go 作为合格证据 |
独立迁移:供应链订单查询
标题“独立迁移:供应链订单查询”一家计划团队需要核对承运商订单,但第三方数据可能延迟两小时。设计一个只读 shipment.lookup_context 合同:
- 写明它支持的业务决定和一线任务;
- 只选三个必要字段,并解释为什么不返回全部订单;
- 决定身份、组织和订单权限从哪里取得;
- 定义“数据过期”“第三方超时”“不可见对象”的不同内部状态;
- 说明对一线用户哪些状态可以合并表达,哪些必须显示;
- 给出一个会让你取消 MCP 接入的证据。
检查点:如果你的合同没有数据更新时间,或者模型可以传入组织 ID,它没有完成迁移。
用同一组证据向三类人解释
标题“用同一组证据向三类人解释”老板版
标题“老板版”本周只验证获授权客服能否从指定工单取得三个必要字段,并保持原有政策权限。正常与失败夹具都没有产生写效果,相关 RAG 回归没有退化。这降低了手工复制上下文的工程不确定性,但没有证明采用、效率或 ROI。是否进入写操作探索,取决于一线异常路径是否真的需要外部效果以及风险所有者是否批准。
一线版
标题“一线版”系统只读取当前工单的任务类型、地区和购买时间,不读取客户正文和主管备注,也不能创建或修改记录。无权限、数据不可用或超时时会明确停下,你仍可按原流程核对或升级;系统不会猜一个字段继续回答。
工程版
标题“工程版”Host 从可信会话取得身份并只允许固定 Server 与
case.lookup_context@1。参数使用封闭模式,Server 再做对象和字段授权,响应带版本、deadline 和类型化错误。工具结果仍进入原 RAG 的 ACL、引用和拒答验证;测试同时核对响应、策略、日志和零外部效果。
三种讲法必须引用同一份决定记录、合同版本和测试结果,不能分别编三个故事。
相邻周
标题“相邻周”第 13 周只证明受限读取。只有证据表明一线异常路径确实需要一个外部效果,才进入第 14 周;否则保持只读同样是合格决定。
权威来源与事实边界
标题“权威来源与事实边界”- Model Context Protocol Specification:协议参与者、能力交换和工具契约的一手规范。实现时应固定实际采用的规范与 SDK 版本,不依赖
latest作为可复现版本号。 - MCP Architecture:Host、Client、Server 关系及数据层、传输层的官方说明。
- MCP Security Best Practices:授权、令牌、会话和远程 Server 风险的官方安全参考。
- OWASP Top 10 for LLM Applications:提示注入、敏感信息、过度代理和不可信输出等风险参考。
核验日期:2026-08-25。 “先只读、再写入”的周次安排、北辰工具合同、字段、错误类别、验收阈值和三层讲解均为本课程的教学设计,不是 MCP 官方课程或行业统一实现。MCP 规范包含协议层授权相关要求,但不能替代具体企业的身份、对象权限、业务审批、效果核验和责任决定。北辰协作、工单、版本、时间和所有运行结果均为合成材料。