场景与最佳实践
实战场景
场景 1:让 AI 查数据库
暴露一个 query 工具,AI 就能"看懂表结构 → 写 SQL → 查数据 → 回答":
server.tool(
'query',
{ sql: { type: 'string', description: '只读 SQL 语句' } },
async ({ sql }) => {
const rows = await db.query(sql);
return { content: [{ type: 'text', text: JSON.stringify(rows) }] };
},
);
// 还可以把表结构暴露成 Resource,AI 先读结构再写 SQL
server.resource('schema://orders', async () => ({
contents: [{ uri: 'schema://orders', text: 'CREATE TABLE orders(...)' }],
}));
场景 2:文件系统 / 项目工具
暴露"读文件、搜索、git 操作"等工具,让 AI 在本地项目里干活(Claude Code 这类工具本身就内置了大量文件/git 工具,你也可以自建团队专用版)。
场景 3:内部系统对接
把内部 API(工单、审批、指标查询)包成 MCP Server,团队内所有 AI 客户端一次性接入——这是"公司级 MCP 生态"的典型用法,一次开发、处处复用。
场景 4:第三方 MCP 市场
官方 registry / 社区有大量现成 Server(GitHub、浏览器、搜索引擎、Slack 等),npx 一条命令即可接入,不用自己写。
安全:MCP 最大的坑
MCP 的本质是给 AI 开工具权限,等于给不可信的模型开 API——必须当安全边界对待:
| 风险 | 对策 |
|---|---|
| 工具被滥调(删库、发邮件) | 最小权限:Server 只暴露必要的工具;写操作显式确认 |
| 远程 Server 无鉴权 | 远程必须 OAuth;本地 stdio 无鉴权但只限本机 |
| prompt injection(模型被数据里的指令带偏) | 对工具输入做白名单/参数校验;不执行未确认的破坏性操作 |
| 数据泄露 | Resources 只暴露需要的数据,别把整库塞给 AI |
铁律:给模型的能力 = 给最恶意用户的能力——凡是不能交给陌生人执行的操作,就别暴露成 MCP 工具。
最佳实践
- 工具要"小而语义化":一个工具干一件事,名称和描述写清楚(描述会被模型当提示词读);
- 输入用 JSON Schema 严格校验:类型、必填、取值范围都写上,别让模型传错参数;
- 返回结构化内容:
content: [{ type: 'text', ... }]之外,善用structuredContent让模型拿到机器可读结果; - 错误处理:工具失败要返回明确错误信息,模型才能自我纠正(比如"表不存在,可用表有…");
- 幂等与重试友好:写操作幂等,避免模型重试时重复执行;
- 本地 stdio / 远程 Streamable HTTP 二选一:本地用 stdio,要给别人用就上 HTTP + 鉴权;
- 跟紧协议版本:MCP 演进快,用最新 SDK、关注 spec 的 changelog 和废弃项。
一句话总结
MCP 是"AI 应用的 USB 接口"——一套开放协议把 N×M 的集成问题变成 N+M:Host 里的 Client 通过 stdio(本地)或 Streamable HTTP(远程)连到 Server,Server 只暴露三种原语(Tools 动手、Resources 读数据、Prompts 给模板)。入门三步:装 SDK → 写一个
server.tool()→ 配进客户端(Claude Code / Claude Desktop 的mcpServers)就能用。唯一必须当回事的是安全——你暴露给模型的能力,等于暴露给最恶意的用户。