本文目录
  1. MCP 的三个核心角色
  2. Tools、Resources 和 Prompts
  3. Tools
  4. Resources
  5. Prompts
  6. 连接初始化与能力协商
  7. stdio 与 Streamable HTTP
  8. 从只读工具开始
  9. 工具设计原则
  10. 单一职责
  11. 明确副作用
  12. 保证幂等
  13. 限制输出
  14. 超时与取消
  15. 权限必须分层控制
  16. 外部内容都是不可信输入
  17. 一套实用调试顺序
  18. 进程和传输层
  19. 初始化层
  20. 能力发现层
  21. 单次调用层
  22. Host 与模型层
  23. 什么时候不需要 MCP
  24. 上线前检查
  25. 从接通协议走向可靠集成

MCP 全称 Model Context Protocol,是应用连接 AI 模型与外部工具、数据和提示模板的一套开放协议。它解决的是集成边界问题:服务端用统一方式描述能力,客户端建立连接并调用,宿主应用负责用户体验、权限和模型协作。

MCP 不会自动让模型变得更聪明,也不是所有 API 的替代品。它的价值在于减少 AI 应用重复编写专有适配层,让能力发现、参数描述和调用结果更一致。

MCP 的三个核心角色#

  • Host:承载用户、模型和权限策略的应用,例如编辑器或桌面客户端
  • Client:Host 内部与某个 MCP Server 保持协议连接的组件
  • Server:向 Client 暴露 Tools、Resources、Prompts 等能力的程序

一个 Host 可以连接多个 Server,并为连接分别维护 Client。Server 不应默认获得 Host 的全部上下文,也不应绕过权限策略访问其他 Server。

Tools、Resources 和 Prompts#

Tools#

Tools 表示可以执行的动作,例如查询工单、运行测试或创建任务。每个工具应有清晰名称、描述和输入 schema,并返回稳定结果。

工具可能产生副作用,因此 Host 应展示调用意图并按风险请求确认。删除数据、发送消息和部署服务不应与只读查询采用相同权限。

Resources#

Resources 表示可读取的上下文,例如项目文档、数据库 schema 或日志片段。资源通常通过 URI 标识,可以被列出和读取。

资源不是把整个数据源一次性塞给模型。Server 应提供有边界的内容和元数据,让 Host 决定何时读取。

Prompts#

Prompts 是 Server 提供的可复用提示模板,例如“审查当前变更”或“生成事故摘要”。它帮助用户启动标准流程,但不应隐藏具有副作用的操作。

简单判断是:动作使用 Tool,可寻址上下文使用 Resource,可复用交互模板使用 Prompt。

连接初始化与能力协商#

MCP 会话从初始化开始。Client 与 Server 交换协议版本、实现信息和 capabilities,确认兼容后再进入正常操作。

典型过程包括:

  • Client 发送 initialize 请求
  • Server 返回协议版本和 capabilities
  • Client 发送 initialized 通知
  • 双方根据协商结果列出或调用能力
  • 连接关闭时释放进程、网络和订阅资源

不要假设所有 Server 都支持同样能力。Client 应根据协商结果启用功能。

stdio 与 Streamable HTTP#

本地集成常用 stdio:Host 启动 Server 子进程,通过标准输入输出交换协议消息。它部署简单,适合本地文件、开发工具和单用户环境。

远程服务通常使用 Streamable HTTP,适合集中部署和多客户端访问,但需要额外处理 TLS、身份认证、会话、超时、限流和网络故障。

只在本机使用的工具没必要为了“云化”增加攻击面;需要团队共享和统一授权的服务则不适合依赖每台电脑单独启动进程。

从只读工具开始#

第一次实现 MCP Server,可以从“查询构建状态”开始。输入是构建 ID,输出包含状态、分支、提交和完成时间,不执行重跑或取消。

{
  "type": "object",
  "properties": {
    "build_id": {
      "type": "string",
      "description": "要查询的构建 ID"
    }
  },
  "required": ["build_id"],
  "additionalProperties": false
}

Server 收到请求后仍需服务端验证,不能因为 schema 已声明就信任输入。失败时应区分不存在、无权限、上游超时和内部错误,不能返回凭据或完整异常堆栈。

工具设计原则#

单一职责#

“管理项目”过于模糊,应拆成查询项目、创建任务和更新状态等独立工具。

明确副作用#

写操作使用 create、update、delete 等清晰动词,不要把删除藏在 sync 或 process 中。

保证幂等#

网络重试可能导致重复调用。写工具可使用幂等键、目标状态或请求 ID,避免重复扣费、发送或写入。

限制输出#

日志、搜索和列表应设置分页、数量与大小上限。无限输出会消耗上下文并泄露无关数据。

超时与取消#

调用外部服务时设置超时,响应取消,并返回可定位但不泄密的错误。

权限必须分层控制#

安全不能只依赖模型“自觉”。至少需要:

  • Host 向用户展示 Server 来源和请求权限
  • Client 只连接明确允许的 Server
  • Server 对每次调用执行认证和授权
  • Tool 按最小权限访问下游系统
  • 高风险操作要求额外确认
  • 日志记录调用者、工具、状态和耗时

不要把高权限数据库账号、云管理员密钥或整个文件系统交给 Server。即使 Host 有审批界面,Server 端仍必须验证权限。

外部内容都是不可信输入#

Resource、Tool 结果和第三方文本可能包含诱导模型执行操作的内容。应用应区分数据与指令,限制外部内容影响系统权限和工具选择。

  • 对 URL 和文件路径做 allowlist 与规范化
  • 防止目录穿越、SSRF 和命令拼接
  • 不把工具输出直接拼成 shell 或 SQL
  • 对敏感字段脱敏并限制日志
  • 对写操作进行服务端授权和参数验证
  • 为外部文本设置来源和信任级别

MCP 统一了调用方式,但不会自动解决提示注入、凭据管理和业务授权。

一套实用调试顺序#

进程和传输层#

确认 Server 能独立启动,stdio 是否被普通日志污染,HTTP 地址、证书和网络是否可达。stdio 的调试日志应写入 stderr。

初始化层#

检查 initialize 是否完成,协议版本是否兼容,双方 capabilities 是否符合预期。

能力发现层#

确认 tools/list、resources/list 或 prompts/list 返回合法结构,名称与 schema 稳定。

单次调用层#

使用固定输入直接调用一个只读工具,记录请求、响应、耗时和错误分类,先排除模型选择问题。

Host 与模型层#

最后检查工具描述是否清楚、Host 是否展示能力、模型是否在合适场景选择工具。

什么时候不需要 MCP#

如果应用只调用一个内部 API,接口稳定且没有多个 AI 客户端复用需求,普通函数或 SDK 往往更简单。

当需要跨客户端复用工具、动态发现能力、统一资源访问或隔离不同数据源时,MCP 才更有价值。不要为了使用协议而增加没有明确边界的中间层。

上线前检查#

  • Server 来源、版本和维护责任是否明确
  • 每个能力是否有最小权限和稳定 schema
  • 写操作是否展示意图并支持确认
  • 输入、路径、URL 和下游响应是否验证
  • 是否设置超时、限流、分页和输出上限
  • 凭据是否通过安全存储注入
  • 日志是否足以审计且不包含秘密
  • 断线、取消、重试和重复调用是否可控
  • 是否有固定用例验证兼容性和权限边界

从接通协议走向可靠集成#

成功列出一个工具只代表协议链路可用。生产级 MCP 还需要清晰能力、最小权限、稳定错误、可观测调用和可重复评估。

先做只读、低风险、输出有限的能力,验证 Host、Client 和 Server 的完整生命周期,再逐步加入写操作和多步骤流程。协议提供共同语言,工程质量仍由实现者负责。