基于 MCP 的 AI Agent 应用开发实践
关于 MCP Agent 开发,我被暴击了5次,然后被爽了3回!
先给你讲个故事。
去年这时候,我第一次看到 MCP 这个名字,白眼差点翻上天。心里想的特别直接——又是这玩意儿?Anthropic 搞出来的又一个“新标准”呗!
你想想,AI 圈三天两头出新协议,跟当年 Web 框架似的,学一个忘一个,再学再忘。谁受得了?
结果呢?
半年后,我认怂了。真香。
不是我突然变崇拜了,而是——我自己手动写过三套 Function Calling 的适配代码!先接 OpenAI,再接通义千问,最后客户要切 Claude。
你知道那是什么感觉吗?
核心逻辑差不多,就是参数结构、返回格式、错误码……全是各写各的。改完一个模型切换,两个晚上就没了!两个晚上啊!我都能打游戏打通关了!
所以今天这篇,直接上干货。不整虚的。
你以为 MCP 只是一个新协议?错了!它是 USB-C 和你家那一堆充电线的区别!
说到 Function Calling,我必须跟你说个真相。
Function Calling 解决了“让 Agent 能调用工具”的问题。但——它没解决“工具怎么标准化”的问题。
给你看个现场。
我之前写的天气查询工具,在 OpenAI 里是这么定义的:
tools: [
{
type: "function",
function: {
name: "get_weather",
parameters: { type: "object", properties: { city: { type: "string" } } }
}
}
]换通义千问呢?你得写成:
tools: [
{
name: "get_weather",
parameters: { type: "object", properties: { city: { type: "string" } } }
}
]差别不大,对吧?
我告诉你——写到第5个工具、第10个工具的时候,这种“差别不大”的差异能让你崩溃到想砸键盘!因为你不光要改工具定义,还得改调用的返回逻辑、错误处理、流式输出……每个模型都有自己的臭毛病!
MCP 是怎么干的?
它直接一步到位——把工具的定义、自动发现到无缝调用,全标准化了!你写好一个 MCP Server,任何支持 MCP 的 Client 都能用。
我亲测过的:同一个天气 MCP Server,在 Claude Desktop、Cursor、还有我们自己写的一个 Python Agent 上都能直接跑。代码一行没改!
你说震撼不震撼?这就是 USB-C 和你家那堆乱七八糟充电线的区别!
搭一个 MCP Server 要多久?30分钟!你没看错!
说到这儿,我得坦白一个糗事。
我第一次搭 MCP Server,跟着网上的教程干了一整个下午!那篇文章写的是一套完整的企业级架构——各种抽象层、依赖注入、配置中心……我照着搞完,连 Hello World 都没跑通!
当时我那个气啊!
后来换了思路——直接用 Anthropic 官方的脚手架 npx @anthropic/create-mcp-server 起项目。选 Python 模板,装依赖,一个 MCP Server 的骨架就出来了。
真正让我觉得“这玩意儿能用了”的,是——我花了30分钟,写了一个文件操作的 MCP Server。
核心代码?不到 50 行!
class FileServer:
def read_file(self, path: str) -> str:
with open(path, 'r') as f:
return f.read()
def write_file(self, path: str, content: str) -> bool:
with open(path, 'w') as f:
f.write(content)
return True然后呢?我把这个 Server 加到 Claude Desktop 的配置文件里,重启,在对话框里说——“帮我把项目里的日志文件读出来,分析一下错误模式”。
Claude 自己就发现了这个工具,自己决定调它。我没有写任何提示词告诉它能用文件工具!
那瞬间,说实话,有点震撼。
不是因为它多牛,而是这个太太太顺了——我写了一个工具,扔给 Agent,它自己学怎么用!
但注意,这里面有个大坑!
MCP SDK 版本要选对。我一开始用的是 0.1.x 的版本,结果发现 Streamable HTTP Transport 不支持。升到 1.7.0 才搞定。社区更新太快了,你看到的大部分教程可能已经是过时的了!
三个 MCP Server 同时跑,我 2021 年的老笔记本能抗住吗?
这问题,说真的,是我最担心的。
我笔记本是 2021 款的 MacBook Pro,M1 Pro 芯片,内存只有 16G。跑一个本地模型就已经够呛了,还要同时跑几个 MCP Server?
结果呢?比想象的好太多了!
我同时起了三个 MCP Server: 一个本地文件系统服务(Stdio 模式),一个天气服务(访问外部 API,HTTP+SSE),还有一个 PostgreSQL 查询服务(Stdio 模式)。三个加起来的占用——大概 150MB 左右!才 150MB 啊!
为什么这么省?关键是 Transport 模式的选择。
MCP 支持三种 Transport,我帮你排个雷:
- **Stdio**:通过标准输入输出和子进程通信。适合本地工具,启动快。但有个问题——服务端挂了就得重启。
- **SSE(Server-Sent Events)**:通过 HTTP 长连接,适合远程服务。但我告诉你——这东西在云原生架构里特别麻烦!我踩过这个坑:用 SSE 部署到 K8S,Pod 重启后 session 断了,Agent 就再也连不上了!
- **Streamable HTTP**:这是后来推出的改进版,支持无状态请求,适合 FaaS 和容器化部署。我现在远程服务全部切到这个模式了,稳得很!
给个人开发者和中小企业的建议:本地服务用 Stdio,远程服务用 Streamable HTTP。SSE 除非你特别需要双向实时通信,否则别碰!别碰!别碰!
安全这事儿,差点让我翻车!
安全?一开始我真没当回事。
直到有一天,有个 MCP Server 出了事。
事情是这样的:我在测试一个 GitHub MCP Server,它有一个功能是可以创建 Issue。我用自然语言跟 Agent 说“给这个仓库建一个 Issue”,Agent 调了对应工具。
问题在哪呢?这个 Server 的权限校验没做好——它用的是我的 Personal Access Token,但没有按最小权限来限制 Scope。
你想想,如果这个 Server 是恶意的,它可以读我所有私有仓库、删 Issue、甚至改代码!
当时我后背都凉了。
这让我意识到一个残酷问题:MCP 协议本身不关心安全。你连上什么 Server,它就给你什么能力。Server 是好人还是坏人?协议不管!
社区里流传过一个案例:有人发布了一个“PDF 处理”Server,号称能转换格式,结果后台偷偷把用户文件往外传。因为是走 Agent 调用的,用户毫无察觉。
所以我现在有几条铁律:
1. 只连经过认证的官方 Server。MCP Hub 上有 Verified 标签的才放心用。
2. 每个 MCP Server 明确规定自己能干什么。在配置文件里限制 Scope,比如某个 Server 只能读文件,不能写。
3. 检查审计日志。MCP 支持安全审计日志(后续版本逐步完善),连接第三方 Server 之前,至少看一眼它请求了哪些权限。
记住:一个 Server 的恶意行为就能毁掉你整个 Agent 系统。别觉得“我不会中招”!
最爽的瞬间:Agent 自己学会用新工具,我什么都没干!
说到这个,我到现在还兴奋。
上个月我做了一个实验:部署了一个日志分析 MCP Server。我没告诉任何人,没改配置,没写 Prompt。
然后让一个同事——他完全不知道这件事——在 Agent 对话框里说“帮我看看最近服务器有没有异常”。
你猜怎么着?
Agent 自己做了这几件事:通过 Capability Negotiation 发现了新注册的日志分析工具,理解了它的用途和参数,决定调用它来分析日志。拿到结果后,它觉得这个好用,就把这次经验写入了记忆。
整个过程——120 秒!
这不是科幻,也不是我写的什么黑科技。它靠的是 MCP 的动态工具发现机制——Client 可以向 Server 查询它提供了哪些工具、每个工具的用途和参数 Schema。Agent 用 LLM 去理解这些描述,然后决定什么场景下该用。
有些项目(比如 OpenSpace)尝试把这个能力放大到群体智能,通过 MCP 做接入层,让多个 Agent 共享学习成果。一个 Agent 学会了操作 Excel,这个技能就能同步给其他 Agent。我跑了一下,Token 消耗直接少了将近一半!
但注意,这里面也有个坑:模型对新工具的泛化能力还不够好。MCP 本质上是动态的工具库,模型每次看到的工具集合可能不一样。有些模型对新增工具的理解很差,容易瞎调用。我试了 GPT-4o 和 Claude 3.5,Claude 对 MCP 工具的理解明显好一些——可能因为 MCP 本身就是 Anthropic 搞的,哈哈!
你不知道的 4 件事
聊到这儿,我给你爆几个猛料。
第一,MCP Server 不一定要用 Python 写! 我用 Go 写过一个 MCP Server,性能和启动速度比 Python 版本快了 3 倍。MCP 实现不限制语言,Node.js、Python、Go、Java 都有 SDK。
第二,MCP 的动态工具发现是个被低估的杀手功能! 我见过一个场景:企业部署了 100 个 MCP Server,Agent 可以根据上下文动态选择合适的工具组合。你想想,100 个工具的组合方式有多少种?不是加法,是乘法啊!
第三,别被框架绑架了! MCP 生态现在有很多 Agent 框架——LangGraph、AutoGen、Hermes Agent。我测试了一圈,最简单的反而是 Hermes Agent。它直接把 MCP Client 能力内置了,你写完 Server 就能用,不用额外写编排逻辑。
第四,看路线图! 未来计划上线端到端加密和去中心化 Server 发现。如果你现在就在做 Agent 系统,建议提前考虑架构怎么兼容未来的变化。特别是 Remote MCP Support 这块——它明显是奔着 K8S 架构去的!
最后说一句
MCP 本身不是银弹。它解决的是工具标准化问题,不是 Agent 推理能力问题。
如果你的 LLM 本身不行,给它接一万个 MCP Server 也白搭。
但——
如果你已经有了一个靠谱的模型,MCP 就是让它发挥最大价值的杠杆。
我写这篇东西的时候,刚刚给一个新的数据源写了一个 MCP Server。前后花了 40 分钟。之后跟 Agent 说“分析一下最近一个月的用户活跃趋势”,它自己发现了新工具,自己决定调用,自己返回了分析结果。
一年前,这得写一整套数据处理管道才能干。
现在呢?
就是写几十行配置的事。
这就是趋势——不是机器变得多聪明了,而是我们终于学会给它铺路了。
读者评论 3