MCP 已死的说法,从我这边看,已经吵了大半年。一边是各路自研Agent框架越做越重,什么编排层、记忆层、工具层全都要自己造;另一边是MCP协议还在不停迭代,版本之间甚至有不兼容的情况。说实话我一度也觉得,这玩意儿可能会像早几年的标准化尝试一样,被各家生态直接肢解掉。直到最近,我在一个带真实业务压力的项目里,把整套工具链切到 Pi 1.0 上跑起来,才对这件事有了新的判断。
这轮迁移最关键的一点在于,Pi 1.0 发布时直接原生支持 MCP,不是加个适配层那种敷衍做法,是真的把协议栈做进了运行时里。这让我重新开始评估:MCP 到底是协议没救了,还是单纯缺一个能把它管好、跑好、约束好的运行时。这篇文章会用我在迁移过程中的真实记录,聊清楚三件事:MCP 为什么会被人唱衰、Pi 1.0 的原生支持到底意味着什么,以及真正把一套存量工具链迁过去要注意哪些坑。
如果你正在做 Agent 开发、工具调用编排,或者团队正在纠结要不要押注 MCP,这篇文章应该能省你不少试错时间。
1. “MCP 已死”的论调是怎么起来的?
任何争议都不是空穴来风。要判断 MCP 是不是真的没有未来,得先搞清楚大家唱衰它的具体理由是什么,而这些问题是不是真的无解。
1.1 MCP 要解决的那个问题,确实存在
先把 MCP 是什么说清楚。全称是 Model Context Protocol,模型上下文协议。它想解决的是 AI 应用接入外部工具、外部数据源时接口五花八门的问题。没有这套协议的时候,每接一个工具,大家都在写胶水代码:远程调用的要封装 HTTP 请求,本地执行的要走子进程,还要处理参数校验、错误返回、上下文塞给模型时的 token 开销。每做一次集成就是一次重复劳动,对接工具的数量一多,整个 Agent 的代码就变成了意大利面。
MCP 的思路是做一个类似 USB-C 的标准化接口。工具方按照统一格式暴露能力,AI 应用按照统一格式调用能力。一个工具接入过一次,理论上就能被所有支持 MCP 的客户端复用。这个愿景本身没毛病,甚至可以说是当前 Agent 生态最刚需的基础设施之一。
问题出在理想和现实之间的缝隙。
1.2 为什么业内会有这么大的质疑声
我听过很多一线开发者的吐槽,归纳下来主要集中在四个层面:
第一是协议碎片化。MCP 规范本身还在快速发展,不同平台对同一个规范的理解和实现有偏差。有的实现里工具参数用 JSON Schema 严格校验,有的却做了很宽松的隐式转换。结果就是一个工具在这个客户端上跑得好好的,换到另一个客户端就报参数错误。协议做标准化最怕的就是这种“伪标准化”,表面统一,底层实现还是各玩各的。
第二是上下文管理失控。MCP 把工具暴露给模型之后,模型怎么决定调哪个工具、工具返回的结果怎么塞进上下文,这些问题协议本身并不过问。实际跑起来就是上下文越积越长,token 消耗越来越大,最后模型开始犯迷糊,Agent 的准确率直线下降。很多人用了一段时间 MCP 之后就扔掉,很大程度是被上下文管理折磨怕了。
第三是运维和管控缺失。MCP 的调用链路上,工具是跑在本地进程还是远程服务,鉴权怎么做,沙箱怎么设,审计日志怎么记录,协议本身只给了一个很薄的框架。企业内部用起来就是:协议是通了,但安全边界没人管,权限模型得自己造轮子。这对于很多团队来说,等于把一个半成品拿回来还得自己二次开发。
第四是生态分化。各家云厂商、模型平台都在推自己的 agent 协议、插件协议,虽然不少已经和 MCP 做了兼容,但整体的生态主导权之争并没有结束。你押注了 MCP,结果行业最终没形成合力,这种担忧在采购决策和技术选型会议上非常现实。
这些质疑单独拿出来,每一条都能让技术负责人摇摆一下。但关键问题是:大家骂的是 MCP 这套协议,还是骂的是缺少一个能让协议落地的完整运行时?我之前的想法停留在前者,直到我把 Pi 1.0 部署起来,才发现后者才是更准确的答案。
2. Pi 1.0 原生支持 MCP,到底“原生”在哪?
现在市面上很多中间件产品都喜欢说“支持 MCP”,但真要拆开看,绝大多数是做了个适配层,把 MCP 当成一种工具协议转换器来用。Pi 1.0 的定位不一样,它把 MCP 作为运行时的第一等公民来对待,从协议握手开始就内建支持,而不是在外面套一层壳。
2.1 原生支持与“适配层方案”的本质区别
先说适配层方案是什么样。典型做法是在你的 Agent 框架里装一个 SDK,SDK 内部实现了 MCP 客户端,把 MCP 工具转换成框架自己的 function calling 格式。好处是能快速支持,坏处是 MCP 协议里那些原本很有价值的能力,比如资源发现、提示词暴露、上下文元数据同步,到了适配层就被直接丢弃了。你只是借了 MCP 的通道传参数,并没有获得协议层的完整语义。
Pi 1.0 的原生支持则是另一套逻辑。它的运行时内核直接实现了 MCP 协议栈,initialize 握手、工具发现、调用路由、上下文段管理,全部在运行时内部完成。这意味着 MCP 在 Pi 1.0 里不是一个插件,而是运行时的骨骼结构之一。你在 Pi 1.0 里用 MCP 工具,和在其他框架里调一个内部函数,体验是同一层的,不会有任何“桥接”带来的语义损耗。
2.2 几个让我觉得“这是真支持”的设计细节
判断原生支持不是看官网文案,而是看具体的设计取舍。我梳理了几个在迁移过程中实际感受到差异的地方。
首先是工具发现阶段。Pi 1.0 的 MCP 工具发现走的是 tools/list 标准流程,但返回的工具元数据会被运行时做一层结构化缓存,并动态映射到内部函数调用机制。这个映射不是简单把参数倒一遍,而是能识别 inputSchema 里哪些字段是必需的、哪些是可选的,自动生成运行时校验规则。我自己试过故意在 schema 里埋一个类型错误,Pi 1.0 在调用前就拦截了,根本不会把坏参数发给模型。
其次是 MCP 上下文窗口管理。MCP 工具调用中,工具描述、参数、返回结果都往模型上下文里放,放多了模型就糊涂。Pi 1.0 的做法是把上下文切成多个会话段,每个会话段维护自己的 token 预算,工具返回结果默认走截断和摘要逻辑,只有必要的内容才完整保留。这个能力不是适配层能给的,它需要运行时对模型上下文的精细感知,属于原生支持才做得了的事情。
再次是传输层的完整兼容。Pi 1.0 同时支持 MCP 的 stdio 和 HTTP/SSE 两种传输模式。本地小工具用 stdio,远程服务用 HTTP,同一个运行时里可以混合调度,模型层完全无感。我之前见过一些只支持 HTTP 传输的 MCP 网关,本地工具硬要起一个 HTTP server 才能对接,非常别扭。Pi 1.0 这种混用能力其实是协议层原生支持的自然结果。
2.3 安全与可观测性上的补齐
MCP 协议本身对安全边界和可观测性着墨不多,这也是一线团队对 MCP 最大的顾虑。Pi 1.0 在这块做了我认为很重要的补位。
每个 MCP 工具在 Pi 1.0 中都可以声明运行沙箱,比如指定文件系统只读、网络访问只允许特定域名、环境变量白名单。工具调用时候,Pi 1.0 的进程级隔离会真正把权限限制住,而不是只在配置里写一行字。审计日志默认开启,谁在什么时间调了哪个 MCP 工具、传了什么参数,都会落到结构化日志里。对于有合规要求的场景,这个能力比协议本身重要得多。
可观测性方面,Pi 1.0 给每个 MCP 调用生成全链路 Trace ID,从模型发起调用,到运行时路由,再到工具执行,整个链路在日志里是能串联起来的。我在调试阶段就靠这个把很多隐蔽问题定位到了具体环节,这在适配层方案里基本是奢望,因为你中间隔了一层代理,很多信息在转换过程中就丢了。
所以回到“MCP 已死”这个问题上,Pi 1.0 给我的直观感受是:MCP 缺的从来不是协议定义,而是一个能把它上升到完整运行时能力的承载者。原生支持不是一句宣传口号,它直接改变了你作为使用者能得到的控制粒度。
3. 实操记录:把现有工具链迁移到 Pi 1.0
前面讲了设计上的理解,这章进入实操。我会按我迁移一个真实项目的过程展开,这里面涉及一个内网文档检索工具、一个数据库查询工具、一个外部天气 API,以及若干个以后端工程师身份维护的内部脚本服务。整个过程大概花了一个月,但这里面大部分时间是在梳理老的代码边界,真正切到 Pi 1.0 上的动作其实非常快。
3.1 迁移前的准备与边界梳理
动手之前,我先做了一个工具清单盘点。这一步非常关键,很多团队迁移失败就是因为没有理清楚当前有哪些工具需要通过 MCP 暴露给模型,哪些其实不应该暴露。
我的盘点维度有三项:工具属性(同步调用还是异步任务)、数据敏感度(是否可以进入模型上下文)、调用频率(高频工具和低频工具应该配置不同的超时与并发策略)。等这些信息列清楚,再开始选第一批迁移对象。强烈建议第一批只迁两个不重要的小工具,跑通全链路,再逐步扩大范围。
3.2 配置文件与核心参数解析
Pi 1.0 的配置方式是声明式 YAML。以下是我迁移文档检索工具时用到的配置,我故意精简掉了内部信息,只保留核心结构:
services: doc-search: transport: stdio command: /usr/local/bin/mcp-doc-search enabled: true context_strategy: summarized context_budget: 2048 timeout_seconds: 30 sandbox: network: allowed_domains: ["docs.internal.local"] fs: read_only: ["/data/corpus"] permissions: scopes: ["search:read"] audit: true tools: compact_schema: true concurrency: 4逐个讲一下关键参数为什么这么配。
transport 用的 stdio,因为 doc-search 是一个本地进程,没有远程服务端,stdio 开销最小,也最安全。context_strategy 设成 summarized,意思是当文档检索返回的结果比较长时,运行时先把内容做摘要再进模型上下文,只保留最终答案和关键引用。context_budget 设成 2048 token,这是给这个 MCP 工具预留的单次上下文上限,防止一次检索结果把整个 Agent 的上下文撑爆。
timeout_seconds 设成 30 秒,主要考虑到文档检索可能涉及跨服务调用,太短的超时容易误杀正常慢请求,太长会影响模型层的整体响应体验。等正式上线后,我还会基于 P95 延迟再收紧这个值。
sandbox 里的配置比较重要。allowed_domains 字段限制了该 MCP 工具只能访问内网文档服务的域名,防止工具被诱导执行了任意网络请求。fs.read_only 让工具只能读 /data/corpus 下的语料文件,从根本上防止工具写入或篡改本地数据。permissions.scopes 则是运行时内的权限模型,后面接 API 网关鉴权时可以直接映射成 OAuth 的 scope。
tools.compact_schema 是一个很容易被忽略的细节。MCP 工具暴露的 JSON Schema 如果写得很大,工具描述和字段说明加起来可能就是上千 token,每次模型决策时这些都要被消耗。compact_schema 开启后,Pi 1.0 会裁剪掉描述性的注释字段,只保留 name、type、required 等核心信息,对复杂工具来说这个配置能省下不少 token。concurrency 设成 4,表示这个工具最多支持 4 个并发调用,避免多个请求同时触发检索导致后端服务被压垮。
数据库查询工具的配置略有不同,多认了一个远程传输模式:
services: db-query: transport: http url: https://sql-gateway.internal.local/mcp headers: X-API-Key: "${DB_QUERY_API_KEY}" context_strategy: minimal context_budget: 1024 timeout_seconds: 10 permissions: scopes: ["db:read"] audit: truedb-query 走 HTTP 传输,因为数据库网关是独立部署的远程服务。context_strategy 设成 minimal,因为数据库查询结果往往是结构化数据,模型只需要提取部分字段,全量塞进上下文浪费严重。minimal 策略下,Pi 1.0 会尝试只保留与用户问题最相关的查询结果行。timeout_seconds 设成 10 秒,数据库查询超过 10 秒通常意味着 SQL 有性能问题,与其让模型傻等,不如直接失败,把错误信息返回给用户重新组织问题。
3.3 分阶段迁移与灰度验证
配置只是第一步,真正上线要分阶段走。我采用的策略是先本地、后内网、再灰度。
第一阶段,在本地开发环境起 Pi 1.0 运行时,把两个工具全部注册进去,用命令行客户端直接调 MCP 工具验证返回结果。这一步主要确认工具本身能响,协议握手正常,参数校验符合预期。本地验证通过后,我会把协议栈的 debug 日志打开,逐个字段检查调用链上的数据流,确保没有字段丢失。
第二阶段,部署到内网测试环境,接入真实模型,验证模型能否根据用户自然语言正确选择工具并填入参数。这一阶段最容易发现的问题是工具描述写得不够清楚,模型不知道该在什么场景下调它。比如我的文档检索工具,最初描述写的是“搜索内部文档”,太模糊。后来改成“当用户询问公司内部的制度、流程、合同条款等内容时,使用此工具检索文档库,支持Keywords与语义检索”,模型选工具的准确率立刻上了一个台阶。
第三阶段,灰度流量迁移。我在业务入口做一个开关,先让 5% 的请求走 Pi 1.0 的新链路,其余走老链路。对比指标包括:平均响应时间、token 消耗、任务成功率、日志中的错误率。灰度跑了大约三天,确认各项指标平稳之后才逐步放量到 100%。
这一步的核心经验是:不要一把梭。哪怕你对自己的配置很有信心,也要让流量自己说话。模型调用工具的行为有随机性,只有真实流量才能暴露那些小概率的异常场景。
4. 迁移过程中踩过的坑与排查速查表
这段写我实际遇到的坑。任何一个项目迁移都不可能顺利到底,Pi 1.0 比他之前的适配层方案好很多,但该踩的协议坑、配置坑一个没少。
4.1 我实际遇到的几个典型问题
第一个问题出在 MCP 协议版本不匹配。我一开始在工具端用的是最近发布的 MCP SDK 版本,而 Pi 1.0 内部实现当前支持的版本协议语义略有差别。现象是握手能够完成,但是 tools/list 返回的 schema 里,部分新版关键字没有被识别,直接导致工具在模型侧显示为一个没有参数的空壳子。排查了半天,最后看协议握手日志才发现版本差异。解决方案有两个:要么给工具端 SDK 降级,要么把 Pi 1.0 运行时的协议兼容选项打开。我最终选择降级工具端 SDK,因为 Pi 1.0 的兼容模式会牺牲掉一部分新特性,没必要为了迁就工具牺牲运行时功能。
第二个问题是 tools/list 返回的大 Schema 把上下文预算打爆了。有一个内部工具因为历史原因,定义了八十多个参数,光工具描述的 token 消耗就接近两千。模型每次做决策之前都要读一遍这个庞大的 schema,高频调用场景下上下文消耗非常夸张。后面我给这个工具开启了 compact_schema,运行时自动裁剪了部分描述信息,token 消耗立刻降了一个量级。
第三个问题是并发调用时的上下文串扰。数据库查询工具被配成允许高并发之后,我观察到两个并发请求的查询条件偶尔会互相串。具体原因是一个公共的上下文缓冲变量没有按会话隔离,后一个请求覆盖了前一个请求的参数占位。Pi 1.0 对这个场景的处理方式是提供 session 级别的变量隔离,但前提是每个调用必须正确传递会话 ID。我原先的代码在调用链中丢掉了 session 字段,补上之后问题消失。
第四个问题是沙箱配置导致工具不可用。我在给文档检索工具配沙箱时,把 allowed_domains 设置得过于严格,只允许了 docs.internal.local,但工具本身还需要连一个外部的 OCR 服务来做 PDF 里的文字识别。结果检索 PDF 文件时,请求在沙箱层被直接拦截,工具报网络错误。这个算我自己配置理解不到位。沙箱是隔离工具动作的,不是限制工具必须只用一份资源的。后面我在配置里加了 OCR 服务的地址,问题解决。
4.2 排查方法论与速查表
这段时间排查下来,我总结了一套比较有效的排查顺序,不一定每次都严格按这个来,但它能覆盖 90% 以上的问题。
第一步先看协议日志。Pi 1.0 的协议日志会记录每次 MCP 握手、工具发现、调用的完整报文,如果问题出在协议本身,日志里一定有线索。第二步看运行时日志,确认调用是否到达了工具执行阶段。第三步看工具端日志,确认工具本身是否有异常。最后才看模型侧日志,因为模型侧的响应延迟往往是结果,不是原因。
我把典型问题整理成一张速查表:
| 现象 | 可能原因 | 排查方法 | 解决方式 |
|---|---|---|---|
| 工具在模型侧为空壳 | MCP 版本不匹配或 Schema 解析失败 | 检查握手日志中的 protocolVersion 字段 | 对齐工具端 SDK 版本,或开启兼容模式 |
| 上下文消耗异常高 | 工具 Schema 过大或返回结果未做摘要 | 查看上下文预算报表 | 开启 compact_schema 或调整 context_strategy |
| 并发调用参数互相串扰 | 会话 ID 未传递,变量未隔离 | 查看运行时调用链 Trace ID | 补全 session 字段,启用会话隔离 |
| 工具报网络错误 | 沙箱网络规则限制 | 查看沙箱拦截日志 | 调整 allowed_domains 配置 |
| 模型频繁误选工具 | 工具描述模糊或 schema 缺少示例 | 回看模型决策日志 | 重写工具描述,补充 use_case 字段 |
4.3 避坑心得
最后分享几个我在实操里的经验,这些话很难从官方文档里看到,但非常实用。
第一,调试 MCP 工具链时,一定要把协议日志打开,别只盯着业务日志看。业务日志告诉你的是工具的业务逻辑有没有执行成功,而协议日志告诉你的是传输链路有没有问题。这两者之间的差异,往往就是排查耗时数小时和数分钟的分水岭。
第二,每次修改工具的 inputSchema 之后,记得重新发布版本并清理运行时的 schema 缓存。我有一次改了个参数名,但缓存的旧 schema 还是老版本,模型按新参数名传参,工具端怎么都拿不到值,来回查了快一小时才想到是缓存问题。
第三,别急着把所有工具一次性接进来。每接入一个工具,都要单独跑一遍模型决策测试,确认它在真实对话中能被正确唤起。工具有一百个但模型不知道怎么选,比工具少一半但每个都准,效果差得太远了。
第四,MCP 工具的超时设置分两层。Pi 1.0 运行时有自己的 timeout_seconds,工具本身也可能有内部超时。两层超时之间至少要留出余量,比如运行时 30 秒,工具内部 10 秒,否则工具内部超时之后运行时还在傻等,白白浪费一个并发额度。
5. 实测结果与我对“MCP 已死”的最终看法
看到这里的读者,应该已经开始有自己的判断了。我再补一些真实迁移后的数据变化和最终结论。
5.1 迁移前后的效果对比
我把迁移前后的数据做了一个简单对比,虽然不同项目之间差异很大,但趋势可以供大家参考。
对比对象是同一个 Agent 应用,之前用的是我自己写的工具适配层记录,迁到 Pi 1.0 之后的指标记录。同样是执行一组模拟用户任务,包括检索内部文档、查数据库、查天气信息并汇总。
接入成本:原来每接一个新工具,要写约三百到五百行胶水代码,包括参数解析、错误处理、结果格式化。迁到 Pi 1.0 后,新增一个 MCP 工具只需要写一个 YAML 段,工具端用统一 SDK 暴露,代码量能降一个数量级。
上下文 token 消耗:原来因为工具描述和返回结果缺乏管理,平均一个任务消耗的上下文折算 token 数是偏高的。Pi 1.0 开启上下文管理策略后,整体 token 消耗大约下降了三成左右,在需要高频工具调用的场景里感知更明显。
维护效率:迁移前排查一次工具调用问题平均要半小时以上,因为链路里自己写的胶水代码逻辑复杂,问题可能出在任何一环。迁移后由于链路级别的 Trace ID 完整,定位问题基本能压缩到十分钟以内。
5.2 对“MCP 已死”这件事的回应
综合这次完整的迁移体验,我对这个争议话题有了非常明确的立场:MCP 没死,真正快死的是那种“把 MCP 当协议适配层”的偷懒用法。
过去很多唱衰 MCP 的声音,本质上是在吐槽一个不完整的实现,协议本身只是定了一个数据格式和调用流程,没有规定上下文怎么管理、安全怎么保障、可观测性怎么做。这些缺失,过去只能靠开发者自己填。自己填就是成本,成本攒多了,大家自然就想弃坑。
Pi 1.0 原生支持 MCP 的意义在于,它把这些全栈能力做进了运行时层,协议不再是需要你二次开发的半成品,而是和运行时天然集成的基础设施。这种模式一旦跑通,MCP 的价值就能真正释放出来。当一个工具写完一次,能在任意支持 MCP 的运行时里获得一致的调用体验、一致的安全管控、一致的上下文优化时,这个生态才有持续壮大的基础。
5.3 下一步可以怎么扩展
这次迁移做完之后,我顺手做了两件后续扩展,目前已经收益,这里也分享给大家。
一是我把 MCP 工具链接进了现有的 CI/CD 流程。每次工具端代码更新,跑一遍协议层的自动测试,重点检查 Schema 是否合法、是否有破坏性变更、工具能否正常握手。这套自动测试帮我们拦截过两次因为 Schema 格式错误导致的线上事故,非常值。
二是我给 Pi 1.0 配置了模型决策的回归测试集。说白了就是把典型的用户问题固化成一堆测试用例,每次升级模型或调整工具配置之后,跑一遍回归测试,看模型选工具、填参数的准确率有没有波动。这个机制特别适合团队持续迭代工具的阶段,能帮你快速发现模型行为漂移或者工具描述退化的问题。
我自己的体会是,技术选型这件事,最难的不是判断哪个方向有潜力,而是既要看到方向的潜力,也要判断它当前缺什么。MCP 过去缺的是一个能把它承载好的运行时,这类问题有些团队产品已经在补,Pi 1.0 就是其中一个尝试。如果你也在纠结要不要让团队押注 MCP,不妨找一个像这样原生支持协议的运行时,先把一两个小工具跑起来,用真实数据来校准你的判断,而不是停在评论区里跟着喊“已死”。