用了几个月 MCP(Model Context Protocol),最大的感受是:它把 AI 从「聊天框」变成了「能用工具的同事」。以前我要把日志、表结构、文档一段段复制粘贴进去;现在我只需要说「看看昨天的错误日志里有没有重复的异常」。
一、一句话解释 MCP
MCP 是一套约定:AI 客户端(编辑器、终端里的助手)通过它去调用外部工具——读文件、查数据库、开浏览器、调你的内部接口。工具由一个个 MCP Server 提供,你在客户端配置里声明要加载哪些 Server 就行。
配置通常长这样(具体字段看客户端文档):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
},
"mysql-readonly": {
"command": "npx",
"args": ["-y", "some-mysql-mcp"],
"env": { "MYSQL_URL": "mysql://readonly@127.0.0.1:3306/app" }
}
}
}
二、我实际接了哪些,用来干什么
- 文件系统(限定目录):让它直接读项目里的代码、配置、日志,而不是我一段段贴。最常用的说法是「读一下 deploy 目录下的 nginx 配置,说说 location 的匹配顺序」。
- 数据库(只读账号):查表结构、看几条样本数据、核对字段类型。写 SQL 的时候它自己会去查表结构,比我口述字段名准确得多。
- 浏览器:抓一个页面的渲染结果,确认「改完的页面到底长什么样」——尤其是我这种前端半吊子,这一步能省掉很多来回。
- 搜索:让它查最新的库版本、API 变更,然后让它把来源链接一并给出,我自己点开确认。
三、三个每天都用得上的场景
- 排查线上问题:把日志目录接进去,「找出最近一小时里 5xx 的请求路径和次数,按次数排序」——它读文件、聚合、给结论,我只需要验证结论。
- 写迁移脚本前的核对:「对比这两个库的表结构差异,列出缺的列」——比手写 SQL 对比快得多,而且不会看漏。
- 把文档喂进去再提问:把内部文档目录接进来,问「我们的发布流程里,回滚这一步具体怎么做」——答案带着文件出处,能核对。
四、安全边界(这部分比功能更重要)
- 数据库只用只读账号,物理上不给写权限;生产库的连接串不放进 MCP 配置,要查就查从库或脱敏数据;
- 文件系统限定目录,绝不给整个家目录或项目根的上一级;
- 不接任何「能触发部署、能发消息、能改线上配置」的工具——这类操作必须由我自己执行;
- 密钥不进对话:需要密钥时让它写「读取环境变量」的代码,而不是把密钥贴进去;贴进去过一次,就等于把密钥写进了对话历史。
五、踩过的坑
- 大结果撑爆上下文。 让它不加限制地查一张大表,几万行结果直接进了上下文,后面的对话全是噪音。对策很土但有效:要求它先计数,再限制只取 20 行。
- 工具描述不清导致乱调。 一个自定义 Server 的工具描述写得含糊,它会反复调用同一个工具试探。把工具描述写得像给人看的说明(什么时候用、输入是什么、返回什么),调用准确率立刻上来。
- 以为它「记得」接了什么。 新开对话后它并不知道你的 Server 列表细节,该说清楚的时候还是要说清楚。
六、值不值得折腾
如果你只做「写代码、改代码」,MCP 的边际收益一般;但只要你经常需要在 AI 和「你自己的系统」之间来回搬数据(日志、表结构、文档、接口),它就非常值——省掉的是最烦的那部分复制粘贴,而且减少了「贴错内容」这种低级失误。
一个提醒:接进来的能力越多,越要把权限收紧。 我给自己定的原则是——读可以放开,写(尤其是能影响线上和删除数据的)一律不给。