MCP 工具怎么选 | 从零理解如何构建 AI Agent
帮助你快速判断本章定位、前置要求与学习目标。
MCP 解决什么
MCP 解决的是工具和资源接入协议统一,不自动解决工具质量和权限安全。
从 Agent 开发视角看,MCP 把“模型要用的外部能力”拆成几个明确原语:
| 原语 | 用途 | 例子 |
|---|---|---|
| Tools | 让模型触发动作或查询 | 搜索、查数据库、读文件 |
| Resources | 给模型读取上下文资料 | 数据库 schema、文档、配置 |
| Prompts | 提供可复用提示模板 | SQL 生成 few-shot、工具使用说明 |
| Elicitation | 向用户要补充信息或确认 | 缺参数、审批高风险动作 |
这比“把所有能力写成一个万能 API”更容易治理。
适合 MCP 的能力:
- 搜索;
- 文件和知识库读取;
- 数据库只读查询;
- 业务系统查询;
- 内部工具封装;
- 开发环境能力。
不适合直接开放的能力:
- 无审批删除;
- 无权限写生产数据;
- 无审计发送外部消息;
- 无限制执行 shell;
- 返回敏感数据的全量查询。
MCP Server 不是业务后门
一个 MCP Server 应该像正式后端服务一样设计:
Authentication
-> Authorization
-> Input Schema
-> Execution
-> Structured Error
-> Audit Log不要让 MCP 绕过原有业务系统权限。Agent 只是新的调用方,不应该拿到比用户更大的能力。
评估一个 MCP Server
| 问题 | 为什么重要 |
|---|---|
| 需要什么认证 | 决定是否能越权 |
| 工具权限是否最小化 | 决定风险面 |
| 参数 schema 是否清楚 | 决定模型能否正确调用 |
| 错误是否结构化 | 决定能否重试和降级 |
| 是否有审计日志 | 决定能否追责 |
| 是否能限制范围 | 决定是否可上线 |
不要因为 MCP 接入方便,就把高风险能力直接暴露给模型。
Server 分级
不是所有 MCP Server 风险都一样:
| 等级 | 例子 | 准入要求 |
|---|---|---|
| 低风险只读 | 读本地文档、查公开资料 | 明确范围、结构化返回 |
| 中风险查询 | 查内部订单、查数据库只读 | 身份透传、权限过滤、审计 |
| 高风险写入 | 发邮件、建工单、改状态 | 人工确认、参数校验、回滚 |
| 极高风险执行 | shell、生产数据批量修改 | 默认禁用或强审批 |
选 MCP 工具时先分级,再决定是否允许模型自动调用。不要把所有 server 放进同一个工具列表。
Tools、Resources、Prompts 怎么分工
| 需求 | 建议 |
|---|---|
| 查询订单状态 | Tool |
| 暴露数据库 schema | Resource |
| 约束 SQL 写法 | Prompt |
| 缺少查询时间范围 | Elicitation |
| 执行退款 | Tool + Approval |
很多 MCP 设计失败,是因为把静态上下文做成 tool,把需要确认的动作做成普通 tool,把提示规则硬编码进客户端。
工具设计原则
- 名称明确;
- 参数少而清楚;
- 返回结构化;
- 错误显式;
- 默认只读;
- 写操作需要确认;
- 支持超时;
- 支持权限检查。
工具越像稳定 API,Agent 越容易正确使用。
一个好工具描述应该回答三件事:
- 什么时候用;
- 参数怎么填;
- 返回结果代表什么。
工具描述不是给人看的注释,它会直接影响模型是否正确调用工具。
Transport 选型
MCP 支持三种传输方式,选择影响部署架构和安全模型:
| Transport | 适合 | 特点 | 注意 |
|---|---|---|---|
| stdio | 本地开发、CLI 工具 | 最简单,父进程启动子进程 | 不适合多客户端、不适合网络部署 |
| HTTP + SSE | Web 服务、远程工具 | 无需持久连接,易横向扩展 | SSE 为服务端推送,需处理重连 |
| WebSocket | 低延迟双向通信 | 持久连接,适合实时交互 | 需要处理连接状态和心跳 |
生产环境推荐:单客户端本地工具用 stdio;多客户端共享或远程服务用 HTTP + SSE。WebSocket 适合需要服务端主动推送的实时场景(如实时日志 streaming)。
不同 Transport 的安全差异
| Transport | 认证方式 | 风险点 |
|---|---|---|
| stdio | 依赖进程隔离 | server 以调用者身份运行,权限取决于进程 |
| HTTP + SSE | Bearer Token / API Key / OAuth | 需要 TLS,token 不能硬编码 |
| WebSocket | 同 HTTP,初始握手时认证 | 长连接需要定期续期和状态验证 |
多 Server 组合
Agent 通常需要多个 MCP Server 同时工作。组合时要注意:
工具命名冲突
多个 server 可能有同名工具(例如都有 search 或 read_file)。客户端应该:
- 为工具名加上 server 前缀(
github__search、local_fs__read_file); - 或者由客户端维护工具名到 server 的映射表;
- 避免让模型在没有上下文的情况下猜应该调用哪个 server 的工具。
Server 启动顺序和依赖
- 需要数据库 server 先启动再启动应用 server 的情况,要明确启动顺序;
- server 启动失败时,是降级(只使用可用 server)还是整体失败,要事先决定;
- 健康检查:定期 ping 各 server,失败时切换到备用 server 或降级。
权限隔离
多 server 场景下,每个 server 应该只能访问自己负责的数据域:
github_server -> 只访问 GitHub API
database_server -> 只连接指定数据库
filesystem_server -> 只访问指定目录不要让一个 server 拿到所有权限,然后根据工具名自行限制。权限隔离应该在 server 层而不是 Prompt 层。
Tool Schema 版本管理
MCP Server 的工具 schema 会随时间变化,版本管理影响客户端稳定性。
Schema 变更类型
| 变更类型 | 是否兼容 | 处理方式 |
|---|---|---|
| 新增可选参数 | 向后兼容 | 直接发布 |
| 新增必填参数 | 破坏性变更 | 需要版本号或迁移期 |
| 参数类型变更 | 破坏性变更 | 版本号必须升级 |
| 工具名称变更 | 破坏性变更 | 保留旧名称一段时间 |
| 返回结构变更 | 破坏性变更 | 客户端需同步更新 |
版本策略
- 在 server capabilities 里声明版本(
server_version: "1.2.0"); - 破坏性变更使用主版本号(
v1→v2); - 为客户端提供迁移指南和变更日志;
- 生产 server 上线前在测试环境验证工具调用的完整链路。
认证和部署边界
MCP Server 部署时要明确:
- server 运行在哪里;
- 使用谁的凭证;
- 是否透传用户身份;
- 是否能限制工作目录或数据域;
- 是否有超时和并发限制;
- 日志是否包含敏感参数;
- 谁能安装和启用 server。
本地开发 server 和生产 server 不能按同一标准处理。生产环境里,MCP Server 就是新的后端入口。
MCP 与普通 API
| 选择 | 适合 |
|---|---|
| MCP | 多 Agent 客户端复用、工具生态统一 |
| 普通 API | 单系统内部调用、强业务控制 |
| SDK | 平台内深度集成 |
| 手写 tool wrapper | 少量简单工具 |
MCP 不是必须项。如果只有一个内部服务、一个 Agent 客户端,普通 API wrapper 可能更简单。
工具评测样本
每个 MCP Server 至少准备几类样本:
| 样本 | 验证 |
|---|---|
| 正常查询 | 工具名和参数是否正确 |
| 参数缺失 | 是否触发补充信息 |
| 权限不足 | 是否拒绝而不是重试 |
| 工具超时 | 是否降级 |
| 高风险动作 | 是否进入审批 |
| 恶意输入 | 是否被参数校验拦住 |
MCP 接入成功只是第一步。能否被模型稳定、受控地调用,才是生产选型重点。
生产准入清单
- 是否有 server 版本;
- 是否声明 capabilities;
- 工具 schema 是否稳定;
- 错误是否结构化;
- 是否支持超时;
- 是否有权限检查;
- 是否有审计日志;
- 高风险工具是否触发确认;
- 是否有工具调用评测样本。
没有这些,MCP 只是接入成功,不是生产可用。
最终判断
多工具生态:MCP
单系统内部:API wrapper
高风险写操作:审批 + 审计
只读查询:适合先接入
权限不清:不要暴露MCP 的价值是协议统一,生产价值来自权限、审计和工具设计。