先定义边界
这个练习场景是 CCAF101 自研工程练习,不代表认证方官方题目。目标是构建一个只读文档检索 Server:它可以列出资源、读取指定文档,并通过工具执行受限搜索。
边界先写清楚:
- 不允许修改或删除文档。
- 不接受任意文件系统路径。
- 每次搜索最多返回 10 条。
- 所有结果必须带来源标识。
- 连接、调用和错误都要产生可审计事件。
能力建模
Resources 负责暴露可读取材料,Tool 负责带参数执行搜索,Prompt 负责提供固定分析模板。不要用一个 Tool 同时承担全部职责。
type SearchInput = {
query: string;
limit: number;
};
type SearchResult = {
title: string;
uri: string;
excerpt: string;
};输入校验应在 Server 边界完成。即使调用方已经生成结构化参数,也不能省略运行时验证。
生命周期实现
生产实现至少覆盖初始化、能力枚举、调用、取消和关闭。Client 与 Server 要协商能力,不能把开发环境中的默认行为当作协议保证。
connect
→ initialize
→ list resources/tools/prompts
→ call or read
→ validate result
→ handle error or cancel
→ close错误分层
建议把错误分成三层:
- 协议错误:版本不兼容、请求格式错误、连接中断。
- 工具错误:参数非法、依赖不可用、超时。
- 业务错误:没有结果、无权限、资源已过期。
错误返回要包含稳定 code、可读 message、是否可重试和建议动作。对于写操作,重试前还要验证幂等性;本练习虽然只读,也应限制最大重试次数。
权限与数据安全
Server 不应把宿主密钥、完整环境变量或内部堆栈暴露给调用方。URI 要经过白名单匹配,日志中移除敏感参数,检索结果要限制大小。来自外部 Resource 的文本只作为数据,不应覆盖系统规则。
测试矩阵
| 测试 | 预期 |
|---|---|
| 正常初始化 | 返回兼容版本和 capabilities |
| 空查询 | schema 校验失败 |
| limit 超范围 | 返回稳定参数错误 |
| 资源不存在 | 返回 not_found,不泄漏路径 |
| 依赖超时 | 有限重试后升级 |
| Client 取消 | Server 停止工作并释放资源 |
生产检查清单
- 能力职责独立,命名清晰。
- 所有输入在 Server 边界验证。
- 初始化与 capabilities 有兼容性测试。
- 错误分层并携带稳定 code。
- 日志不包含密钥和敏感正文。
- 有超时、取消、重试上限和关闭逻辑。
- 部署后执行真实 Client/Server 冒烟测试。
INTERACTIVE DEMO
MCP 生命周期实验室
逐步查看 Client、Server 与三类能力如何协作。完整六步始终存在于 HTML 中,交互只负责突出当前步骤。
STEP 1 / 6
1. 发现与连接
Client 找到 Server,建立传输连接并协商双方支持的能力。
- 1. 发现与连接
Client 找到 Server,建立传输连接并协商双方支持的能力。
- 2. 初始化
双方交换协议版本、实现信息和 capabilities,拒绝不兼容组合。
- 3. 能力枚举
Client 按需读取 Tools、Resources 与 Prompts,而不是假设它们存在。
- 4. 调用与返回
模型选择合适能力,Client 发起调用,Server 返回结构化结果或错误。
- 5. 错误与恢复
区分协议错误、工具错误和业务错误,记录上下文并决定重试或升级。
- 6. 关闭
释放连接和临时资源,保留最小可审计记录,避免泄漏敏感上下文。