
最近好几个技术社群里都在吵同一个话题MCP是不是要凉了。起因也不难理解Agent Skills、更原生的Function Calling、各家框架自己封的插件协议看起来都比MCP更轻、更贴近模型能力于是“删掉薄封装”成功变成新一轮的技术叙事标题越起越狠连“退出历史舞台”都出来了。作为一个从MCP刚起步就把它接进内部工具链的开发者我想先泼盆冷水这个话题一半是技术争论另一半是流量密码。MCPModel Context Protocol本意是把AI Agent和外部工具之间的连接方式标准化它实实在在地解决了多客户端、多工具、跨语言的集成痛点但它也确确实实有设计边界。本文我打算把“薄封装”到底指什么、MCP在Agent连接架构里的真实位置、什么时候该保留它、什么时候该换成原生方案以及我在真实项目中遇到的坑和排查方法一次性讲透。适合正在做AI Agent集成、手里同时维护多套客户端工具的同学参考也适合被“MCP已死”言论整到犹豫要不要继续投入的人。1. 唱衰MCP的三类噪音背后薄封装到底是什么1.1 为什么“删掉薄封装”会成为热搜话题MCP被唱衰过去一年我至少听过三类叙事。第一类是“协议过剩论”。很多项目实际只需要让模型调用三五个工具比如查库存、发邮件、算价格。这种情况下直接把工具列表放进Prompt用模型自带的Function Calling就完事了根本不需要引入一套独立的协议层。MCP的Server、Client、Tool、Resource、Transport这些概念对一个小项目来说确实是负担这就是“薄封装”被吐槽“多余”的直接来源。第二类是“控制权回归论”。模型厂商和框架方都在推自己的Agent原生生态比如Anthropic的Agent Skills、OpenAI的Function Calling进阶用法。这些方案和模型内部能力贴合得更紧能吃到模型厂商的功能更新比如新的结构化输出、并行调用、内置上下文缓存。相比之下MCP作为一套独立协议更新节奏完全跟不上模型能力迭代自然给人一种“落后半代”的观感。第三类是“工程债论”。随着MCP生态膨胀工具数量爆发问题也开始暴露鉴权不统一、流式传输支持参差不齐、长连接容易断、跨平台配置混乱。这些吐槽我大部分是认同的但这不等于“协议本身该消失”。那“薄封装”究竟是指什么说穿了MCP做的事情就是把“模型需要调用工具”这件事拆成固定的消息格式和传输约定客户端发一个tools/call请求服务器返回content和isError中间再加个initialize握手。官方SDK写起来代码量极少给人感觉就是薄薄一层壳。问题在于把它往真实业务里一放你就得处理鉴权、超时、重连、流式、幂等、多租户隔离……真正麻烦的不是协议本身而是协议之外那层胶水。1.2 技术噪音之外的几句实话我对MCP的真实态度是确有弱点但罪不至此。先说不该被忽略的优点。MCP最大的价值是“一处接入、多处可用”。我维护过一套内部运维工具集包了日志查询、配置变更、发布状态这些能力。换成MCP之后同一个Server可以被Claude Desktop、Codex、Dify、自研Web客户端连接不用为每个端写一套适配层。这个收益在客户端数量大于等于三个时是非常显著的尤其是团队里不同人用不同工具统一协议能省掉大量重复劳动。再说确确实实存在的短板。MCP对“流式工具调用”的支持一直不够理想。传统HTTP/SSE传输下服务器向客户端推流是单向的做那种“边生成边写文件”的场景你得自己加回调机制。另外MCP官方规范里工具描述是JSON Schema但很多模型对Schema的遵循质量不稳工具一多就容易乱选。这些都是真实痛点也是“连接架构重选”话题的正确答案来源只要稍微抬杠一下就能得出“删掉MCP”的结论。我觉得更合适的类比是HTTP协议本身。HTTP也是一层薄封装没人会天天喊“删掉HTTP”原因是大家清楚它只负责最基础的请求响应剩下的路由、鉴权、缓存都是上层自己叠的。MCP现在的问题是被一部分人当成了“AI连接万能解决方案”当期望撑不住时骂声自然就来了。等情绪退潮它会回归成一个基础连接层该用的地方继续用不适合的地方换成更合适的方案。这跟“退出历史舞台”绝对扯不上关系。2. MCP在Agent连接架构里的真实位置2.1 MCP的能力拆解不只是工具调用很多被“薄封装”言论带跑偏的人以为MCP就是个工具调用协议。其实MCP规范里有四个核心能力只有把四个都理解透才能做好架构判断。第一是tools这个大家最熟悉。模型向服务器发请求服务器执行并返回结构化结果。适合查询、计算、操作类动作对应的是“Action”这一层。第二是resources。这是用来给模型提供上下文内容的比如项目文档、代码文件、日志片段、上报数据从机制上更接近一个只读文件系统。模型侧不需要主动调用客户端可以把Resource内容自动注入到上下文里。项目里把rules、wiki、接口文档暴露成Resource效果比硬塞Prompt稳定得多。第三是prompts。本质是预置的提示词模板服务器端定义客户端侧选择并填充参数后使用。多客户端统一模板时很省事避免每个端各维护一套提示词逻辑。第四是sampling这是最容易被忽略的能力。它允许服务器反过来向模型发起生成请求也就是模型—工具之间的双向协作。典型场景是Agent要动态决定要不要让LLM再生成一段文本当中间步骤服务器侧也能参与采样策略。只看tools的话MCP确实薄。但如果把resources、prompts、sampling放进视野它就是一套完整的上下文传输与交互规范价值和厚度完全不同。2.2 传输层选型stdio、HTTP/SSE与Streamable HTTP怎么选MCP的传输层直接影响使用体验和架构设计这块是很多“MCP已死”论据的来源。早期MCP最常用的是stdio传输。客户端以子进程方式启动Server通过标准输入输出通信。优点是本地命令型工具接入极快配置也简单Claude Desktop这类桌面应用天然适合。缺点也很明显跨网络不可用、生命周期跟客户端绑死、不方便在远端使用多租户服务。后来是HTTPSSE传输。服务器暴露一个HTTP端点客户端通过SSE接收事件。稍微复杂一点但摆脱了进程限制可以部署到服务器多个客户端同时连。缺点在于SSE是单向的客户端要向服务器连续POST事件才能真正实现双向流式会话状态管理也因此变得别扭。最近MCP在推Streamable HTTP核心变化是支持双向流式通信客户端和服务器都能主动发消息。对实时性要求高的工具比如让Agent边推理边看到日志输出、流式写文件、持续反馈执行进度这种传输模式明显更顺。实际选型时我一般画一个简单象限表传输方式跨网络流式支持多客户端典型场景stdio否一般弱本地调试、桌面客户端、临时脚本HTTPSSE是弱中单方向推送、早期服务化部署Streamable HTTP是强强服务化Agent、实时输出、多端共享我自己的经验是本地工具和调试场景用stdio凡是准备长期跑的服务尽量直接上Streamable HTTP。省得后面为了流式需求再重构传输层。2.3 MCP不是唯一的连接方式和Function Calling、插件协议的边界在哪要判断“删掉MCP”先得搞清楚它和其他连接方案的边界。原生Function Calling是模型厂商直接支持的能力定义函数列表、让模型选函数、回传参数整个流程发生在模型推理内部延迟低、贴合紧。如果整个系统只有一个模型供应商、两三个内部工具用Function Calling完全没有问题加MCP只是徒增层数。插件协议比如IDE里的插件机制、Agent框架自带的Action插件优势在于贴近宿主环境能吃到宿主本身的能力比如文件访问、编辑器上下文、生命周期事件。适合单宿主深度集成可移植性通常较差。MCP的位置在于“标准化中间层”。它不跟模型绑定也不跟宿主绑定给的工具形态是一致的。当一个生态里同时存在Claude Desktop、Codex、Dify、自研Web端大家要共用同一套工具时MCP的价值是其他方案替代不了的。选择逻辑很简单模型层能力够用且不多端共享用Function Calling深度绑定单一宿主用插件协议多端复用、跨语言、要做统一权限审计选MCP。这三者不是互斥关系一个复杂系统里经常叠加使用比如MCP Server内部继续调用原生Function Calling接口去驱动模型。3. 连接架构重选的判断与落地路径3.1 什么时候保留MCP、什么时候换成轻量方案前面把概念边界理清了现在聊实操判断维度。我做架构重选时基本看五个维度。第一客户端数量。只有单客户端、单场景MCP优势不明显。三端以上共享工具收益立刻拉满。第二工具数量与更新频率。工具少且稳定手工维护列表也行。工具几十上百、天天有人加参数MCP Server把工具注册集中管理优势非常明显。第三跨语言与团队构成。团队后端是Go、前端是TS、还有一个专门写脚本的Python小子如果每端各写各的函数调用封装光对齐Schema就要流失大量时间。MCP统一成一份Schema各端只要有个Client SDK就能接。第四审计与权限需求。MCP的工具调用天然走统一入口日志、黑白名单、配额都方便集中控制。这对安全合规很关键后面我会专门展开。第五维护成本预期。MCP Server本身也要维护不能只看接入方便。如果一段时间内只有两个人维护、工具量又在爆炸MCP是给自己的治理成本减负不是加码。我自己见过最典型的反面案例一个团队只有两个工具、一个客户端、用单一模型硬是上了MCP结果光调试配置就花了两天。这种场景我真的支持“删掉薄封装”原生Function Calling半个小时搞定。但反过来的案例更多内部工具平台接十几个服务、四五个客户端没有MCP之前每个端一套自定义适配每换一次模型就要全部返工。MCP在这里不是多一层是把原先混乱的N层变成统一的一层。3.2 重选架构时的五步落地法如果你正在纠结要不要换掉MCP或者准备把零散连接改成MCP我的建议按下面五步走。第一步盘点集成面。把所有需要给Agent暴露的能力列出来标出哪些是工具型调用哪些是上下文型读取哪些只是模板复用。这一步会直接决定要用MCP的四个能力里的哪些避免全部堆上去。第二步定义Schema边界。给每个工具写清楚参数、返回值、错误码。这里最容易犯的错是把内部接口原样暴露让Agent拿着复杂系统DSL当参数。更好的做法是设计“面向任务”的窄接口每个工具只做一件事参数尽量扁平。第三步选择传输层。本地工具直接stdio线上服务直接Streamable HTTP。早期图方便全用stdio后面挪服务器时十有八九返工。第四步设计鉴权与审计。MCP Server内部要接好服务端认证每次调用必须能追溯到发起方。工具级权限要能细到“谁能调谁不能调”别让所有客户端都一样权限。第五步做并发和幂等兜底。Agent很爱并发调工具尤其是并行调用工具的场景一个Server扛不住就要做限流。写文件、发消息这类动作必须幂等否则Agent重试一次就重复下单。这套流程跑下来你会发现连接架构重选最后大概率不是“删掉MCP”或“保留MCP”的二选一而是“哪些服务暴露成MCP工具、哪些直接用原生能力、哪些干脆手动直连”的混合方案。3.3 从“薄封装”到“厚治理”架构讨论不该停在协议层关于“删掉薄封装”我想再提一个自己的理解如果有问题不是在“薄”上而是在“治理薄”上。MCP给Agent的工具调用提供了一个标准化入口这是好事但入口标准化不等于权限、配额、监控、幂等自动就有了。很多实际事故比如Agent循环调用写坏数据、高并发打垮DB、越权读到其他租户数据背后不是MCP协议错了而是没人给这层做治理。我的经验是把MCP Server当一个真正的后端服务来治理而不是一个仅供本地调试的小工具服务端做超时控制避免长尾工具调用拖垮整体响应对每个工具定义限流阈值按客户端维度独立计数所有调用请求和返回值统一结构化日志方便复盘模型“为什么做了这个决策”关键操作设置人工审批Agent只能发起请求人确认后才真正执行敏感资源用独立的Resource路径暴露只授权给有需要的客户端做到这些之后“MCP很薄”这种说法基本就不成立了。它本质上已经从“多出来的一层封装”变成“集中治理的一层厚底座”。唱衰MCP的人如果看到的是没有治理的裸协议那确实该骂稍微叠点设计和运维它立刻变成Agent架构里最稳的一段主动脉。4. 实操实录从工具接入到流式输出再到调试排坑4.1 跑通一个最小可用的MCP Server理论讲太多容易飘先看一个最小可用的例子。用Python官方SDK写一个本地计算器工具走stdio传输。这段代码我实际跑过可以直接拿去做连接验证。from mcp.server.fastmcp import FastMCP mcp FastMCP(demo-server) mcp.tool() def add(a: int, b: int) - int: 两数相加 return a b if __name__ __main__: mcp.run(transportstdio)然后在Claude Desktop这类客户端的配置里加一行启动命令就能把工具暴露给模型调用。注意Windows和macOS下路径写法不同配置里要把python解释器路径写全这一点是新手的最大坑。等这个例子跑通再往Server里叠各种工具就顺畅了。我自己的经验最小验证时千万别一上来就接生产数据库先用一个无副作用工具把链路打通再逐步加真实依赖否则排查时很难分清是协议问题、SDK问题还是上游接口问题。4.2 流式输出内容到文件一次真实的工程改造有朋友问过“使用MCP工具流式输出内容到文件”怎么实现这个场景我正好在CherryStudio里折腾过。需求本身很简单模型生成内容的同时由MCP工具把内容增量写入本地文件。问题在于流式调用和一次性返回的差异很大。先说工具侧。正常的MCP工具调用是模型先生成参数、客户端发请求、工具一次性返回全文。要实现“边生成边写”就得让工具承担“增量状态累积”的职责。我的做法是在工具函数里实现一个可追加的Buffer并对文件句柄做全局管理避免多次调用互相覆盖。代码形态大致是这样import json from pathlib import Path _write_buffer [] mcp.tool() def write_output_chunk(text: str, task_id: str) - dict: 向指定任务的输出文件追加内容重复调用会持续累加 global _write_buffer _write_buffer.append(text) current_text .join(_write_buffer) Path(foutput_{task_id}.md).write_text(current_text, encodingutf-8) return {status: ok, total_chars: len(current_text)}关键点有两个第一写文件必须走同一个文件路径否则每次调用单独写一个文件第二写入时用文本追加语义而不是“覆盖写入”不然Client重试一次整段内容就废了。客户端侧也有讲究。在CherryStudio这类工具里配置MCP Server后要让模型理解“分批调用这个工具”提示词里就要写明你是要分多次调用write_output_chunk每次生成一小段内容后立刻写入而不是一轮生成完再一次写入。否则模型通常还是会选择一次性返回全部内容。踩过的坑提醒大批量流式输出时文件写频繁会导致锁竞争尤其同一个文件被多个会话同时写时。我后来加了按task_id隔离文件再把写盘动作做成异步队列才彻底解决阻塞问题。还有一个隐藏坑是编码Windows下要显式传encodingutf-8否则默认GBK会打出乱码。4.3 IDE与逆向场景的MCP插件Codex接Figma、蓝湖以及IDA/x32dbg的MCP跟工具链相关的热搜词里有很大一块是IDE和调试场景。Codex接Figma MCP、接蓝湖MCP说到底就是让命令行Agent能拿到设计稿的上下文。Codex接入Figma的MCP时最常见的翻车点是授权。Figma MCP要走OAuth流程会弹浏览器、交换授权码、然后回写到本地配置。我遇过的问题包括回调地址被系统防火墙拦截、scope权限不足导致读不到文件、本地端口被占用导致回调失败。排查思路很简单先看MCP Server日志里有没有收到回调参数再检查配置文件里的access token是否过期。蓝湖MCP的思路类似但它更偏“设计稿标注信息”的拉取工具往往只有“读取标注”和“读取页面列表”几个动作比较窄但很好用。接这类MCP时我建议先通过Resource方式暴露上下文而不是当作工具调用因为模型多数情况下只需要被动读取设计稿信息没必要主动“调工具”。再聊一个更有意思的场景IDA MCP和x32dbg的MCP插件。这是安全分析圈里越来越火的方向。调试器通过MCP Server把自己的状态暴露给Agent模型可以直接读取寄存器、反汇编结果、栈回溯甚至下断点。好处是以前要自己写脚本批量分析反汇编输出现在可以让Agent直接基于调试器实时数据做推理。但这里一定要补一句安全提醒调试器MCP很强大也极度危险。一旦Agent被投毒或系统被入侵它能操作的东西远超普通工具。我只在隔离虚拟机里启用调试型MCP且配置成只读模式至少不开放断点和内存写入能力。这里没有例外。4.4 Dify浏览器MCP与Agent安全的边界浏览器MCP是一个转变Agent能力边界的工具。它让模型能直接驱动浏览器打开网页、点击按钮、填写表单、抓取页面数据。结合Dify这类低代码Agent平台可以实现“Agent自动填报系统、自动抓取页面结果、自动做巡检”的完整流程。实际落地时我的经验是把浏览器MCP的动作控制在一个很窄的范围内。每个Agent绑定一个专门的配置文件指定它可以访问的域名白名单比如只允许操作内部测试站点。对外的生产环境一律不允许Agent直接点击要做成套“只读巡查人工确认”模式。还要关注两个坑一个是浏览器MCP操作太快页面元素还没渲染完就提交容易把表单填错。解决办法是在动作之间加固定等待或者工具里内置“元素可见性检测”。另一个是并发窗口多个Agent同时操作同一浏览器会话会互相干扰我一般给每个任务起独立的浏览器上下文用完销毁。Agent安全不是MCP独有的问题但MCP把所有工具调用聚合成了一层清晰接口反而方便做身份认证、操作审计、人审回调。真正危险的做法是把MCP Server当透明隧道直接用不做任何权限拦截。把不该开放的API暴露给Agent量再大也撑不住。反过来在Server入口统一加“允许/拒绝/需审批”三级策略Agent越权问题就会好控制很多。5. 常见问题与排查技巧速查5.1 高频故障Codex找不到MCP、授权失效、工具不显示把我在社区和实际项目中见到的典型问题整理成一张速查表排查时按图索骥即可。问题现象可能原因排查步骤Codex提示找不到MCP Server配置文件路径未生效、Server进程启动失败、端口被占用用npx或python手动启动Server看报错检查客户端加载的是不是你改的那份配置确认stdio模式的启动命令完整Figma/蓝湖MCP授权失败OAuth回调地址被拦截、scope权限不足、access token过期查看MCP Server日志是否有回调参数检查OAuth应用配置里的重定向地址重新授权前先刷新tokenMCP工具在客户端工具列表里不显示Schema解析失败、工具函数未注册、SDK版本过旧用MCP inspector单独连接Server验证工具列表看返回值是否合法JSON升级SDK到最新版流式输出到文件后内容乱码文件编码不是UTF-8、Windows默认GBK写文件时显式传encodingutf-8检查客户端输入流是否也按UTF-8解析同一个文件被多个会话覆盖没有按会话/任务隔离文件路径文件名插入task_id或session_id写路径权限控制好别共享MCP Server偶发断连长连接超时、心跳没配、反推机制缺失使用Streamable HTTP时配置心跳进程本身做重启守护多个客户端使用同一MCP Server时权限越界客户端等级没有做身份区分在Server入口对客户端来源做认证不用只看transport是否通这些问题的共性是“链路没透过”。我强烈建议先配上MCP Inspector这一类的调试工具能看到完整的请求/响应消息流比在客户端里瞎猜高效得多。5.2 Agent并发怎么扛MCP Server只是协议适配不是业务执行者“AI Agent怎么扛并发”这个问题几乎每周都有人问。核心答案MCP Server本身不应该扛并发它只是一个协议适配层。现在很多人的做法是把业务逻辑直接写进MCP工具函数里一个Server进程内同步计算完再返回。小流量可以但Agent喜欢并行调多个工具一旦并发量上来Server进程就成了瓶颈。我的实际改造方案一是把工具函数变成“提交任务”和“查询结果”两个独立工具。Agent先调用submit_task拿到一个任务ID再轮询get_task_result获取结果。Server里压入消息队列后端Worker慢慢消费本质上把同步调用变成了异步。二是所有写操作都做幂等比如写入日志时带request_id同一请求重试不影响数据。三是在服务端做限流按客户端维度并发控制超额直接返回“请稍后再试”不要无限排队。Alan这层改完之后MCP Server就从瓶颈变成了稳定入口。我见过最夸张的场景是一个团队用MCP Server接了十几个浏览器伪装头同时跑几十个抓取任务Server只有4个副本照样稳得很。关键就在于后端执行器和协议适配彻底分离。5.3 调试与避坑心得日志先行Schema严格校验最后分享几条我用血泪换来的调试经验。第一日志必须在最初就铺好别等到问题发生再补。每次工具调用记录哪个客户端、传了什么参数、返回值是什么、耗时多少。Agent推理是个黑盒你只有靠调用侧日志才能复原它当时的行动路径。第二工具Schema做严格校验。不校验的话模型一旦传错类型工具侧拿到NaN、None、异常对象行为就会难以预测。我一般用Pydantic这类库的schema自动验证再把错误类型明确抛回给模型让它知道要修正参数而不是硬着头皮重试。第三尽量让每个工具保持无状态或低状态。MCP Server重启后之前挂在Buffer里的数据全都丢了。凡是需要存的数据尽早落盘或转给后端存储。我在早期写流式输出工具时Buffer全在内存Server一重启所有输出全得重来。第四升级MCP规范时谨慎。Streamable HTTP是好事但老客户端可能还在用SSE服务端平滑兼容比一锤子切换更稳。配置里做好版本协商至少同事的旧工具不会一夜之间全挂。第五生产环境的MCP Server全部走独立进程管理比如systemd或容器调度配上重启策略。stdio模式下它真的会随客户端退出而退出线上服务不能用这种方式。写在最后的个人体会我从MCP早期就开始接各种内部工具也一度把它吹成“Agent连接层的万能钥匙”后来被现实教育过几次才慢慢找到合理的姿态。现在我的判断很简单MCP不会因为一句“删掉薄封装”就退出历史舞台真正应该被删掉的是那种“不管场景对不对先套一个协议再说”的偷懒思维。它的价值从来不在厚薄而在它能把多端、多语言、多工具的连接成本压缩到可以维护的程度。如果你正在被“MCP已死”的讨论带得摇摆我的建议是拿自己的真实场景做一次对照测试把MCP接入时间和直接用原生Function Calling的时间比一比把后续再接入一个新客户端的时间也记录下来。数据会告诉你答案。另外再分享一个我最终踩过坑后固定下来的习惯所有MCP Server上线前先跑一遍无副作用的冒烟用例确认工具列表能完整列出、参数校验能命中、错误能正确回传再放Agent进去。这个习惯帮我挡掉了后面至少三分之二的线上故障希望对你也有用。