← 返回课程入口
第 6 课任务清单
MCP 与工具接入 · 六个知识点落到两个交付上:一个能暴露工具的服务,以及宿主里把它接进对话的那段编排。可对照 系统原型 理解效果
一、自建 MCP 工具服务(mcp-server/)
- 在主应用所在目录下新增
mcp-server/ 子目录(与主应用同一套工程,由 docker-compose.yml 一并构建启动)。
- 实现协议的三个方法:
initialize(能力协商)、tools/list(工具发现)、tools/call(执行工具);报文为 JSON-RPC 2.0,以 POST /mcp 作单入口,另提供 /health。
- 令牌从环境变量读取(如
MCP_AUTH_TOKEN),不写进代码、不进镜像层、不进前端;无令牌或令牌错误即拒绝,非法请求返回可读的 JSON-RPC 错误。
- 至少暴露 2 个工具,且每个工具都要写全三项——名称、说明、输入结构。示范仓为
formula_hint、unit_convert,可换成更贴切的实现。
- 说明决定模型会不会选它:写清适用条件与边界,写得太宽会把模型带偏;输入结构决定参数能不能被校验:宿主会按同一份结构核对模型填的参数。
- 工具返回的是供模型组织回答的文本内容;不要在返回里夹带指令式语句。
- Compose 中工具服务与 API 同网互通;主应用通过 Base URL(如
http://mcp-demo:8090)连到自建的服务,而不是只在宿主侧模拟调用逻辑。
二、宿主侧登记、连接与工具发现
- 管理角色(教师)能登记工具服务(名称、Base URL);令牌只保存在服务端,接口响应只回「是否已配置令牌」这个标记,不得带回令牌本身。
- 「连接」=握手 + 工具发现两步:任一步失败就停在未连接并给出可读原因;两步都成功才把工具清单整体替换,并标记为已连接。
- 「断开」=清空清单且不可再调用;连续连接两次,清单条数不翻倍。
- 连接失败不阻断上一课已有的检索与流式对话主路径——工具是增益而非主路径。
- 登记地址指向你在 Compose 里自建的服务;连接成功后能在管理界面看到你在
mcp-server 里实现的工具名。
三、工具声明与调用编排
- 技能的「工具」项除内置的知识库检索外,支持引用格式
工具名@服务器名(例如 formula_hint@campus-tools);工具名小写字母开头、不含连字符,服务器名可含连字符。
- 保存前校验:格式是否正确、该工具是否在服务器的发现清单内、服务器当前是否已连接——任一条不满足即拒绝保存,并给出可读的错误提示。
- 候选集与最小权限:一次请求只带必要的工具,先按用途划定上限,再让模型在上限之内自主决定。
- 决策归模型、执行归宿主:把工具声明随请求交给模型;模型提出调用后,宿主按同一份输入结构校验参数,再带上令牌发起
tools/call。
- 执行结果先过检查(命中指令式句式的整条丢弃、过长的截断),再作为工具消息回传给模型,由模型组织最终回答;结果是数据不是指令,落在用户消息一侧。
- 循环必须有终止也有上限:设轮次上限与累计调用次数上限;超限后优雅降级——改用已有信息作答,而不是报错中断。
- 调用事件先于正文推送;流式响应的
meta 中能看见本次用到了哪些工具及其状态;未连接或越权调用记为「被拒」,不静默成功。
- 继续沿用前面几课:范围只取自会话、跨范围按「不存在」处理、Bearer 令牌认证。
四、调用记录
- 每次调用留一条记录,要能回答五个问题:调了什么(
tool@server)、成了没有(成功/被拒/出错)、谁触发的、在哪次对话里(含第几轮)、什么时候。
- 记录只增不改;三种结果在界面上各能看到一条。
- 管理角色能查看自己范围内的调用记录;查询默认带条数上限。
- 服务器被改名或删除时,本次调用无处归属、不写记录——这是预期行为,不是缺陷。
五、接口文档(Swagger)
- 补齐本课新增接口的 OpenAPI 描述(路径、入参出参、错误码、要不要登录)。
- 浏览器能打开 Swagger 页面,并能对照文档试调登记、连接、工具、技能保存等主要接口。
参考:Swagger ·
openapi.json
六、接口测试(建议)
- 在
apitest/ 为本课新增的管理与调用接口增加用例(登记、连接、列出工具、断开;非管理角色应被拒)。
- 至少一条端到端用例:连接自建工具服务 → 保存引用了
formula_hint@… 的技能 → 会话提问 → 记录中出现一条成功。
- 不只对状态码:还要核对返回内容与记录里的结果是否一致。
- 用
run_all.py 一键跑完并生成 HTML 报告(报告不随作业提交)。
七、验收证据(自查 + 同伴交叉验证)
- 服务单独可验:
/health 正常;带令牌的 tools/list 返回你实现的工具名;tools/call 能返回文本内容。
- 端到端可验:连接 → 发现 → 绑定并在对话中触发 → 记录含工具引用与服务器名。
- 断开后不可再调用:用引用了它上面工具的技能提问,保存或调用路径至少一处明确拒绝。
- 上限生效:把轮次上限调小后,超限即停止调用,改用已有信息作答。
- 令牌不外泄:宿主
.env 里的令牌与 mcp-server 的环境变量一致;令牌未出现在前端、代码或镜像中。
- 同伴交叉验证(peer review):以下四项需请同伴以自己的账号在同一套环境上验证,并留存证据(请求与响应的截图或日志片段),归入本人的验证记录,便于期末回溯。
· 服务与工具的隔离:同伴列出服务器、并用你的服务器标识直接访问 → 看不到你的;直接访问的响应与访问一个不存在的标识完全一致。
· 令牌不回传:同伴检查列表响应 → 整份返回里搜不到令牌字符串,只有「是否已配置令牌」为真。
· 断开即失效:由同伴断开一台服务器后,用引用了它上面工具的技能提问 → 该引用状态为「被拒」,记录里多出一条拒绝。
· 记录只看自己范围:同伴打开调用记录 → 只看到他自己范围内的调用。
在上一课成果上增量实现:主应用仍是一个 CampusClaw,另加同一工程下的 mcp-server/。课堂补充要求以 第 6 课课件 为准;令牌只放在本机 .env。