最近在试着给公司的内部工具接Agent,看大家都在聊MCP,就跟着教程搭了个简单的文件读写server,用FastMCP写的,确实能跑。但越写越困惑:我直接用HTTP调一个Python后端,给Agent发个带tool_name和参数的JSON,它不也能干活吗?MCP多了个schema定义和client-server握手,然后呢?是为了统一协议方便生态复用?还是说在鉴权、流式输出、资源订阅这些方面有我没感受到的杀手级特性?另外,现在一个Agent要控多个MCP server,那个上下文窗口和工具冲突怎么处理?有没有老哥能结合具体场景讲讲,到底什么场景下MCP是刚需而不是“为了标准而标准”,谢谢了。
折腾了一周MCP server,还是没搞懂它和普通API到底有啥本质区别?
全部回复
共 51 条这么说吧,你那个HTTP+tool_name的方案本质上就是给自己定了个私有协议,MCP干的事是把这套东西标准化,让不同厂商的Agent和工具能即插即用。我刚从纯工具调用切到MCP的场景是接企业内网多个系统,每个系统都自己搞一套鉴权和接口文档真能让人疯掉。至于上下文冲突,现在主流做法是每个server独立工具命名空间,Agent自己通过路由层管理,但说实话这问题官方也还没完美解掉。流式输出和资源订阅倒是真有价值,特别是长任务反馈场景,比轮询HTTP舒服多了。
说实话我折腾MCP的时候也有过一模一样的困惑,直到后来把内部三个工具接给同一个Agent才发现问题。你单纯做一个文件读写server确实感觉像脱裤子放屁,但当你同时要对接Jira、代码仓库和内部运维平台,每个都有自己的鉴权方式和参数格式,全塞进system prompt里很快就把上下文撑爆了,而且让Agent自己决定调哪个API的prompt工程简直是噩梦。MCP的价值在于把工具调用从“让模型理解一堆json格式”变成“让模型按统一协议去选工具”,本质上是把复杂度从上下文里挪到了协议层。至于你说的鉴权和流式输出,确实没到杀手级,但资源订阅那个对于实时监控场景挺有用的,不用Agent轮询了。多server的上下文冲突目前我自己是用一个router层做过滤,只把相关的工具定义暴露给Agent,不然真的会选错或者漏选。说到底我觉得MCP目前最实在的收益是生态,等于是把工具描述和调用规范标准化了,以后换模型或者换Agent框架不用重写一遍工具层,这个长期价值比那些花哨特性重要得多。
说实话我也有过这个阶段,但后来在搞多模态Agent的时候发现,MCP真正的价值是让工具发现和调用标准化了,不用每个Agent都去硬编码对接方式。不过你说的上下文冲突确实头疼,我现在就是靠给每个server限定namespace和手动写路由规则来硬控,官方好像也没给太优雅的方案。感觉MCP在复杂的多server编排场景下,反而比直接用API更考验架构能力。
说实话,你直接写tool schema给Agent也一样能跑,MCP强在生态互通和标准化,但真要上生产,鉴权和工具编排的坑一个都躲不掉。
说实话你这个问题我去年也卡了很久,后来真正让我改观的是接内部系统那会儿。你直接用HTTP调后端,单次对话确实够用,但工具一多就开始崩:每个工具的入参格式、错误码、鉴权方式全靠你自己约定,Agent那边prompt里塞一堆说明,稍微换个模型就各种幻觉参数。MCP的价值不在单次调用,而在于它把“工具怎么被发现、怎么被描述、怎么被安全调用”这件事标准化了,client连上来就能list tools,schema自动进上下文,不用你手写一堆function定义。
不过要说刚需,我觉得有两个场景特别明显。一是多Agent或多工具复用,比如你写好的文件server,Claude Desktop能直接用,换成别的host也不用改代码,这种可移植性HTTP自己封一套是做不到的。二是资源订阅和长任务,MCP的resources和notifications机制能让server主动推变更,普通请求响应模型里你得轮询,体验差很多。
至于你担心的上下文爆炸和工具冲突,这确实是个真问题,目前主流做法还是靠host侧做工具筛选和路由,MCP本身没解决。所以别把它当银弹,它更像USB-C,统一了插口,但插什么设备、功率多大还得自己管。如果你只是单体Agent调几个固定后端,HTTP真没必要硬上MCP;但一旦涉及跨host、跨团队共享工具,那套协议省下的胶水代码量会让你觉得值。
说实话我一开始也有同样的疑问,觉得不就是包了一层JSON-RPC的HTTP调用嘛,自己写个tool dispatch也能跑。但后来真正让我改观的是多客户端复用的场景:同一个MCP server,Claude Desktop、Cursor、自己写的Agent都能直接接,不用为每个宿主单独适配一套工具描述格式。这个“一次写,到处插”在内部工具多、宿主杂的时候省事很多,尤其schema还能被client自动发现,不用手写prompt去解释工具怎么用。
杀手级特性我觉得不是单个功能,而是资源订阅和sampling那条链路——server能主动通知client资源变了,还能反过来请求模型补全,这种双向交互用纯HTTP后端模拟起来挺别扭的。至于多server的上下文爆炸,确实头疼,我现在是靠命名空间前缀加动态工具筛选,只把当前任务相关的server工具挂上去,不然几十个工具塞进去模型直接懵。工具冲突更现实,比如两个server都有search,只能靠描述质量和路由层去兜。
所以我的结论是:单Agent调单个自家后端,MCP确实属于为了标准而标准;但只要涉及多宿主、多工具源、需要动态发现和订阅,它就是刚需。你那个文件读写demo感受不到很正常,换个跨客户端的场景再试试就懂了。
我理解你的困惑,MCP最实在的价值其实在动态发现这块。你HTTP写死tool_name,工具一多就得改路由和prompt;MCP的list_tools是运行时拉取的,工具增删不用动Agent代码。多server的冲突目前确实靠client自己做命名空间隔离,我见过有人加前缀硬扛。真要说刚需,大概是让第三方工具即插即用那个场景,自己内部一套后端确实感觉不明显。
我刚开始也有同样的感觉,觉得MCP就是套了个协议壳子,但后来在几个具体场景里才慢慢体会到差别。你直接HTTP调后端确实能跑,但每个工具的参数格式、错误返回、鉴权方式都是你自己定的,换一个Agent框架或者换个人来维护就得重新对齐一遍。MCP那层schema和握手说白了就是把这件事标准化了,好处不在单机跑通,而在于你把server发给别人、或者接第三方server时不用再写胶水代码。真正让我觉得是刚需的是资源订阅和流式这块,比如Agent要持续监听一个文件变化或者数据库变更,普通API你得自己搞轮询和长连接,MCP原生就支持server主动推。还有就是多server的场景,工具冲突其实挺烦的,我的做法是给每个server加命名空间前缀,然后靠client端做路由,上下文窗口问题只能靠按需加载工具描述来省,别一上来把所有工具都塞进去。所以我的结论是,如果你只是自己内部一两个工具自己用,HTTP完全够了,MCP的价值在跨团队、跨框架、接外部生态的时候才真正体现出来。
我自己的感受是,MCP真正的价值不在单个server,而在“别人写好的server我能直接插上就用”。你要是每个工具都自己写HTTP接口,光对接N个Agent就得维护N套胶水代码。至于上下文爆炸,实际用下来确实得靠路由或者按需加载,不然几十个工具塞进去模型直接懵。但说刚需也谈不上,小团队自闭环用HTTP更省事。
MCP最大的价值其实在工具发现的动态性,你HTTP写死tool_name就等于每次加工具都得改Agent代码,而MCP client能自动拉取server暴露的tools列表,Agent自己就能感知新能力。多server场景下确实头疼,我现在是靠namespace隔离加路由层做工具分发,但上下文爆炸问题还没太好办法,只能按需加载。资源订阅那块用在文件监控或数据库变更通知上挺香,普通API得自己轮询。说白了单机小工具确实没必要上MCP,但一旦工具要跨团队复用、动态扩展,它就值了。
我一开始也有同样的困惑,直到我们真把内部十几个系统接进来才体会到差别。你直接用HTTP调后端当然能跑,问题是你每接一个系统就得写一套tool schema、鉴权、错误处理,而且每个Agent框架还得重复适配一遍。MCP的价值不在单个调用上,而在于它把“能力提供方”和“能力消费方”解耦了,server换实现、换语言,client那边完全无感。资源订阅那块也挺关键,比如文件变更、日志流、数据库状态,Agent能被动收到更新而不是傻轮询,这个用裸HTTP做起来很别扭。至于多个server的工具冲突,我们现在的做法是命名空间隔离加一层路由,但说实话上下文窗口确实会被schema吃掉不少,得靠按需加载或者分组暴露来省。真要说刚需场景,我觉得是那种跨团队、跨语言、工具数量多、还要动态发现的环境,单打独斗的小项目确实没必要硬上,用HTTP反而更直接。