RSS

第 12 章 / 共 12 章

实战:把笔记库服务做完并自评

约 6 分钟 更新于

12.1 一张完整的任务卡

前面十一章是拆开讲的。这一章把它们合成一件事:独立做完一个可以交付的 MCP Server。

下面这张任务卡就是验收标准。不要一次做完,按四轮推进,每一轮都跑一次 Inspector 确认没坏。

任务:笔记库服务 v1.0

为本地 Markdown 笔记目录提供一个 MCP Server,让 AI 助手能在对话中自主搜索、读取和追加笔记,并且不会访问笔记目录之外的任何文件。

第一轮:能跑(对应第 2、4 章)

要做的验收
search_notes 工具Inspector 里能调用并返回命中行
read_note 工具能按文件名返回全文
notes://index 资源资源标签页能读到目录清单
用 logging 而不是 print全局搜索 print( 结果为零

第二轮:调用得准(对应第 5、6 章)

要做的验收
三个能力的描述都回答了「搜什么/返回什么/何时用」拿描述给一个不了解项目的人看,他能说出什么时候该用
参数约束写进 Annotated[..., Field(...)]tools/list 的 schema 里能看到 minimum/maximum/enum
只读工具标了 read_only_hint=Truetools/list 里有 readOnlyHint: true
返回类型是 Pydantic 模型返回里有结构化内容,不是被包了一层的裸字符串
结果超过上限时截断并给引导造一个高频词,确认返回里带「建议换更具体的词」
错误用 ToolError 抛出读一个不存在的文件,模型端能看到完整提示

第三轮:不会崩、有状态(对应第 7 章)

要做的验收
lifespan 里建索引,工具走索引stderr 里「building index」只出现一次
笔记目录从环境变量读,带默认值不设变量也能启动
加 reload_index 工具改一篇笔记后调用它,搜索能搜到新内容

第四轮:别人敢装(对应第 9、11 章)

要做的验收
路径边界校验传 ../../../etc/passwd 被拒绝
append_note 做成两步(先预览再执行)预览不写文件,执行需要带上预览返回的 id
接进 Claude Code,--scope project/mcp 显示已连接,.mcp.json 里没有硬编码的绝对路径
README 四要素齐全给别人看,他能回答「敢不敢装」
过一遍 11.5 的清单每一项都有明确的是或否
第12章:实战:把笔记库服务做完并自评
图 12.1:四轮推进不是四个阶段,是一个可以反复走的循环。每加一个新能力,都要重新绕一圈。

12.2 自评量表

每一项按「做到了 / 部分做到 / 没做」三档打分。低于 12 分的,先别发布。

维度2 分1 分0 分
能跑换一台机器 clone 下来照 README 就能跑起来自己机器上能跑要口头解释才能跑起来
原语选对每个能力都能说出为什么是这个原语大致合理全做成了工具,没想过
描述质量别人只读描述就知道何时该用说清了做什么,没说何时用一句话带过
参数设计约束在 schema 里,名字无歧义名字还行,约束在函数体里q、n、data
错误设计分清了给模型看的和给自己看的都能返回错误,但信息笼统直接崩
返回设计有截断、有引导、结构化会截断全量返回
状态管理准备工作在 lifespan,跨调用用 handle有 lifespan每次调用重建
可调试性日志够定位问题,故障能在五分钟内查到有日志靠猜
安全边界过了 11.5 全部清单做了路径校验没想过
文档README 四要素齐全,说清了数据访问范围有安装说明只有代码

12.3 常见的三种「差一点」

改到这一步的 server,通常卡在三个地方,各自的症状很好认。

第一种:能调用,但模型从不主动调用。 症状是你必须点名工具它才用。这不是连接问题,是第 5 章的问题——描述里缺少「什么时候该用」的触发线索。回去改描述,改完用 9.5 的第三步验证(不点名工具,只描述需求)。

第二种:调用了,但上下文很快就满。 症状是聊几轮之后模型开始变笨、忘事。这是第 6 章的问题——返回体没有节制。加截断、加详略开关、把返回里模型用不上的字段删掉。

第三种:自己用没问题,给别人就崩。 症状永远是路径和环境。这是第 9 章的问题——绝对路径、显式环境变量、能自己找到依赖的启动命令,三件事漏了一件。

12.4 接下来学什么

做完这个 server,有三条自然的延伸路径,按投入产出排序:

第一条,把它做深。 给现有的 server 加提示词原语,把你反复输入的那段整理指令固化下来;给工具加进度上报,让长任务在宿主里有反馈;把索引换成真正的全文检索。这条路不需要新知识,只需要把前十一章的东西用得更熟。

第二条,把它做远。 按第 10 章走一遍 Streamable HTTP 部署,加上认证,让同事能用。这条路会逼你真正搞懂授权那一块,也是最能体现「从玩具到服务」差别的一段。

第三条,换个方向:从写 server 到写 client。 你现在理解协议的两端了,写一个自己的 MCP client(或者用 Agent SDK 把 agent 装进自己的程序)是很自然的下一步。回头看第 3 章那些 JSON,你会发现另一半其实并不神秘。

不管走哪条,有一件事请保持:每次动手前,用官方文档核对一遍版本相关的东西。 这份教程里的每个版本号、每条命令、每个字段名,都是 2026 年 9 月核实的。协议还在快速演进——你已经在第 2 章和第 3 章亲眼见过一次破坏性变更长什么样了。教程会过期,但「先核对再动手」这个习惯不会。

12.5 最后一个检查点

不看教程,回答这五个问题。答不上来的,回对应章节再读一遍:

  1. 一个能力该做成工具还是资源,判断依据是什么?(第 4 章)
  2. 模型决定「要不要调用你的工具」时,读到的是哪几个字段?(第 5 章)
  3. 你在工具里抛一个普通异常,模型会收到什么?想让它收到你写的提示,该怎么做?(第 6 章)
  4. 2026-07-28 之后,需要跨调用保持的状态应该放在哪里?(第 3、7 章)
  5. 工具标注能提供什么,不能提供什么?(第 11 章)

五个都答得上来,你已经不需要这份教程了。去写你自己的那个 server 吧。