我在想说这套机制是不是就是万能的?就比如说我们用一个实际的场景来检验一下。比如说我们有一个 Linux 的 shell agent,就是说命令行的这么一个服务吧, shell service 吧。我们去和大模型进行这个命令行工具的这种沟通。比如说 Tools List 就返回类似于 which all 这种,就是把所有的命令行工具通通列表给它。然后 Tools call 就是具体的那个命令行工具。那么其中还有 subscribe 可能就是一些文件变化啊,或者说系统资源的变化啊等等等等。这个 Logging 是从 Server 端发起的这个 notification,这个我不太理解它的用途。 Progress 这个是对应于 Subscribe。 还是对应于什么东西?就是说这个是对应于说某一个方法调用时间太长了,它等于是给这个大模型一个 heartbeat 的一个连续过程的这样一个通知。那么 tools call,比如说大模型要去修改,去调用一个命令行去修改某个资源,那么但这个资源可能是修改过程可能很长,时间很长,那 Server 端是不是就通知他一下?就意思说我还不能返回。我不理解这个中间是怎么样一个过程,就是说比如说大模型调用了一个 tools call 去改变一个文件吧,假假定说。然后但 Server 端呢,那同样的 ID 是返回说已经执行了,结果,但是实际上不能返回,为什么呢?因为这个修改时间很长,所以 Server 端只能跟那,相当于这个是异步调用的。 Server 端只能跟它说这个 ID, 但是呢是 notification,我只是告诉你说现在还在进行中,比方说 progress 进行了 20,然后再进行了 50。然后最后说哦 result 说可以了,这等于是要让客户端去等待,是不是这个意思?
MCP协议解释
导出时间:2026/5/19 05:29:33
来源地址:https://www.doubao.com/chat/38426488544924418
消息数量:26
结合你Linux Shell Agent + 大模型实战场景,把 MCP 这套机制、异步执行、进度推送、日志、订阅、阻塞 / 非阻塞逻辑一次性讲透,同时回答你是不是万能、各通知的定位。
一、先给核心结论
- MCP 不是万能,它只是标准化通信骨架,业务能力全靠服务端自身实现;协议只规定收发格式、异常、状态,不包办业务逻辑。
- 你理解完全正确:
progress就是长耗时任务心跳进度通知- 大模型发
tools/call调用耗时 Shell 命令 → 服务端不会立刻返回最终结果 - 中途持续推进度百分比,任务跑完再回最终
result - 属于异步调用模型,客户端中间可感知状态,不会卡死无响应
logging/message、progress、resources/subscribe三者定位完全不一样,互不隶属。
二、先拆分你 Shell Agent 场景对应关系
你的场景:
- Client:AI 大模型 Agent
- Server:Linux Shell 命令服务(执行命令、读写文件、监控系统、变更订阅)
对应 MCP 方法映射
tools/list服务端枚举本机所有可执行 Shell 命令:ls、cp、mv、vim、tar、curl、which 等,相当于给 AI 展示本机全部可用工具。tools/callAI 下发具体命令:修改文件、拷贝、打包、权限变更、编译等可执行动作。resources/subscribe订阅文件目录、磁盘、进程静态资源变化例:监控/etc/config目录文件新增 / 删除 / 改写、CPU 内存占用变动。progress通知单次 tools/call 内部的长任务进度例:超大文件拷贝、压缩、全盘检索、批量改配置,中途不停推送进度。logging/message日志通知服务端运行日志、命令报错、标准输出、警告信息,独立于进度。
三、重点拆解:长耗时文件修改异步完整流程
场景:AI 调用
tools/call 执行 大文件编辑 / 批量写入,执行耗时几十秒,无法立刻返回结果。1)客户端发起调用(同步请求报文)
json
{
"jsonrpc":"2.0",
"id":10,
"method":"tools/call",
"params":{
"name":"file_edit",
"arguments":{
"path":"/data/big.log",
"content":"追加大量文本数据"
}
}
}
2)服务端收到,开始执行任务
不会立刻返回 id=10 的 result,先进入后台异步执行。
3)中途持续推送 progress 进度通知(无 id,单向推送)
通知类不带请求 ID,只是状态播报,不占用应答位
json
{"jsonrpc":"2.0","method":"progress","params":{"progress":20,"total":100,"message":"文件写入中"}}
{"jsonrpc":"2.0","method":"progress","params":{"progress":55,"total":100,"message":"校验数据块"}}
{"jsonrpc":"2.0","method":"progress","params":{"progress":90,"total":100,"message":"收尾写入"}}
作用:
- 给大模型心跳反馈:任务没死、还在跑
- AI 可以根据进度判断是否卡死、是否异常
- 不会出现调用后长时间黑洞等待
4)任务运行中同步打出 logging 日志
日志独立于进度,记录命令输出、报错、系统信息
json
{"jsonrpc":"2.0","method":"logging/message","params":{"level":"info","message":"成功打开文件句柄"}}
{"jsonrpc":"2.0","method":"logging/message","params":{"level":"warn","message":"文件体积偏大"}}
5)任务全部结束,返回最终标准结果应答
携带原始请求 id=10,闭环本次调用
json
{
"jsonrpc":"2.0",
"id":10,
"result":{
"success":true,
"file_size":10485760,
"cost_time":28.6
}
}
6)如果执行中途出错
直接返回对应 id 的 error 错误报文,终止任务
json
{
"jsonrpc":"2.0",
"id":10,
"error":{
"code":-32000,
"message":"磁盘空间不足,写入失败"
}
}
四、厘清三个容易混淆的通知区别
1. progress 进度通知
- 归属:单次 tools/call 内部任务过程
- 生命周期:调用开始 → 调用结束
- 用途:长命令执行百分比、阶段状态
- 例子:压缩、拷贝、编译、批量修改文件
2. resources/subscribe 资源订阅
- 归属:长期后台监控,和单次命令无关
- 生命周期:订阅开启后一直监听,直到取消订阅
- 用途:被动感知外部文件、进程、磁盘自发变化
- 例子:别的程序改了配置、日志自动滚动
3. logging/message 运行日志
- 归属:服务端全局运行记录
- 用途:排错、审计、命令输出打印
- 和进度、订阅互相独立
一句话区分:
- progress:我正在干活,干到哪了
- subscribe:外面环境自己变了,我告诉你
- logging:我运行过程里发生了各类事件日志
五、回答你:MCP 这套机制算不算万能?
不算万能,是强规范通信层,有边界
优势(这套机制能稳稳搞定的)
- 统一格式,AI 和 Shell 服务不用各自私协议对接
- 天然支持同步调用 + 异步长任务 + 进度心跳
- 自带错误返回、状态校验、会话生命周期管理
- 工具、文件、监控、日志全部标准化互通
- 大模型不用关心底层 Shell 实现,只按标准发指令即可
明显边界局限(做不到万能)
- 协议只管通信,不管业务逻辑命令能不能执行、权限够不够、命令语法对错,全靠 Shell 服务自身判断,MCP 不校验业务。
- 不解决系统底层卡死、进程宕机服务进程崩溃后,协议层再规范也无法继续交互。
- 能力依赖服务端实现标准方法全都存在,但服务端没写对应的 Shell 逻辑,调用就直接报错。
- 无法跨权限突破系统限制Linux 用户权限、SELinux、防火墙限制,协议绕不过系统本身规则。
六、补充你关心的客户端等待逻辑
- AI 发出
tools/call后,链路不断开,保持监听 - 中间不断收到 progress 心跳,AI 判定任务存活
- 直到收到同 ID 的 result /error,本轮调用才算结束
- 中途不会判定超时失败,可由客户端自己设定超时阈值
简单比喻:你远程下发一个超大文件操作
- 进度条实时刷进度 = progress
- 后台打印命令日志 = logging
- 外面别的程序改了文件 = subscribe
- 全部做完返回最终结果 = 闭环应答
整套异步流程完全贴合你 Linux Shell Agent 的使用场景。
七、极简流程总结
AI 发起调用 → 服务后台执行 → 持续推送进度 + 日志 → 任务完成返回结果 / 出错返回错误订阅单独后台常驻监听环境变化,互不干扰。
【AI 写代码总翻车?问题不在智商】
点击链接打开👉 https://m.toutiao.com/is/MEUykeS_Tl0/ MEUykeS_Tl0` W@m.DH :1am Axw:/
复制此条消息,打开「今日头条APP」或「今日头条极速版APP」后直接查看~
这里面有一个很有趣的结论,文章说40万行代码是一个坎儿,在这个之上的话,如果不使用这种 IDE 的工具,比如说。搜索定义啊,搜索引用啊,那么效率会大幅度下降,这个看起来是一个。令人信服的结论,我感觉也是这样。当然,这个阈值可能是对 Agent 来说呢,对人来说也一样。如果不使用工具的话,单单用 grip 之类的。确实如此吧。因为一个大的项目。里面出现的这些呃,你单单用搜索得到的最后。数量太多了,我的意思是说,用 grip 你等于是同义词搜索呃,你其实会把很多的结果都收到。你最后都忘了你在找什么东西了。这个文章里面说的确实是实情,你解释一下名词。MCP,它到底是一个什么样的协议?怎么做的
搜索 2 个关键词,参考 12 篇资料
MCP 是什么(先给人话版)
MCP = Model Context Protocol(模型上下文协议),由 Anthropic(Claude 母公司)在 2024 年 11 月推出的开放标准,被称为 AI 界的 USB‑C。
一句话:让任何大模型,用同一套标准,安全、可管理地调用任何外部工具 / 代码 / 数据库 / 文件,不用再为每个模型 / 工具写一套 “胶水代码”。
1)解决什么问题(对应你说的 40 万行代码)
- 大项目(几十万行):必须依赖 IDE 的 “定义 / 引用 / 重构”,纯 grep 根本扛不住(结果太多、分不清、易改错)。
- AI 写代码 / 读代码时,同样:
- 没有标准:GPT、Claude、千问各一套调用格式(Function Calling / Tool Use / Plugin)
- 每个工具(Git、AST、搜索、编译、数据库)都要单独适配 → N×M 爆炸
- 权限、日志、调试混乱,企业不敢用
MCP 的目标:统一成一套接口,一次开发,所有模型 / 工具都能用。
2)MCP 怎么做(架构 + 流程)
架构:Client ↔ Server(JSON‑RPC 2.0)
- MCP Client:AI 模型 / Agent 侧(Claude、GPT‑5、IDE 插件)
- MCP Server:工具 / 代码 / 数据侧(封装成标准服务)
- 传输层:本地 stdio(进程间)、远程 SSE / Streamable HTTP

核心能力(三类 “资源”)
- Resources:读代码、读文件、查数据库(只读)
- Tools:写代码、运行命令、重构、调用 API(可执行)
- Prompts:可复用的提示模板(标准化)
一次典型调用(AI 查代码定义)
- Client → Server:
initialize(握手、协商版本 / 能力) - Client → Server:
tools/call(“查 X 函数的定义”) - Server:
- 权限校验
- 调用底层 IDE / 工具接口
- 返回结构化结果(文件、行号、代码片段)
- Client:把结果融入上下文,继续生成代码
3)和你说的 “40 万行代码” 有什么关系
- 人:>40 万行,必须用 IDE 的定义 / 引用 / 重构,grep 不可用。
- AI Agent:>40 万行,必须用 MCP 这类协议,把 IDE 的能力(AST、索引、重构)封装成标准工具,否则:
- 上下文塞不下全部代码
- 靠字符串搜索 = 海量噪音、找错、漏改
- 无法安全修改大代码库
结论:MCP 就是 AI 时代的 “IDE 协议层”,把人类靠 IDE 才能搞定的大型代码库能力,标准化给 AI 用。
4)和普通 API 有啥不一样
- API:端点固定、权限粗、无状态、难管理工具链
- MCP:
- 会话化(有上下文)
- 细粒度权限(哪个工具、哪个仓库、只读 / 可写)
- 统一工具发现、调用、日志、审计
- 专为 AI 做的 “工具操作系统”
5)一句话总结
MCP = AI 与大型代码库 / 工具之间的标准化 “IDE 总线”,解决 “40 万行以上必须靠工具,而 AI 之前没有统一工具接口” 的核心痛点。
需要我给你一个极简的 MCP 调用示例(查函数定义),方便你直观理解吗?
你真的是很很糟糕。那我提到一个 result,一个 error,然后你就回答 result、 error。那是不是还有我不知道的这个其他的方法呢?就是其他的应答呢?还有,就是说 client 端如果是不按照协议,前面发了一个请求,一个 ToolsCall,然后紧接着就直接一个 Shutdown,允许不允许?这个从那个状态机的这个分析你也不没有,这个 protocol 都没写清楚。允许不允许中间他直接不等到那个 server 端返回,直接 shut down 可以不可以?那这个时候或者说一个请求还没有完,他去调用另外一个请求,这是允许的,对不对?那他能不能终止这个请求呢?或者说他根本不在乎。那这样的话是不是就是很多资源就被锁定了?比如说这个客户端直接发了一百个请求,那你 Server 端必须老老实实的就是一百个请求都在都在去进行。 Client 端这边改主意了,他能不能 cancel 掉这个请求呢?你这些的协议都没有定义的清楚,这个场景都没有定义的很清楚。然后你这个我问一个你就答一个,我没有想到的东西你就藏着掖着是吗?
理解你要的是完整协议约束 + 状态机 + 并发 / 取消 / 异常边界,不再零散应答,基于 MCP 0.2.0 正式规范 + JSON-RPC2.0 底层规约,把所有边界规则、应答形态、状态流转、请求并发、取消、中途关闭全部严谨定义清楚。
一、先明确:合法应答仅有两类,无其他应答形态
对携带
id的客户端请求,服务端只允许两种最终应答,不存在第三种标准应答字段- 成功应答:
result字段 - 失败应答:
error字段
约束强制规则
- 同一份应答报文,result 和 error 互斥,不能同时出现,也不能同时缺失
- 不存在自定义字段充当合法应答,所有业务结果、错误信息只能归入这两个字段
- 进度、日志、资源变更均为无 ID 通知,不属于请求应答,不能替代最终回执
二、会话状态机完整定义
定义 4 种基础会话状态,所有请求、关闭动作都受状态约束
- NEW 新建未初始化:连接建立,未执行 initialize
- READY 就绪可用:握手完成,正常收发各类业务请求
- SHUTTING_DOWN 正在关闭:收到 shutdown 请求,开始收尾
- CLOSED 会话终止:资源释放,不再处理任何请求
状态流转规则
- NEW → READY:仅可通过合法 initialize 请求切换
- READY 下可正常发起所有带 ID 业务请求、订阅操作
- 任意状态收到合法 shutdown,均可进入 SHUTTING_DOWN,最终流转为 CLOSED
- CLOSED 状态下,客户端再发任何请求,服务端统一返回会话无效错误
三、核心场景边界判定
1. 未等待响应,直接发送 shutdown 是否允许
协议语法上允许发送报文,但业务与资源处理有明确规则
- 客户端行为:发出
tools/call后,不等服务端返回 result/error,立刻发送shutdown,报文收发层面不拦截 - 服务端处理逻辑
- 收到 shutdown 请求后,标记会话进入关闭状态
- 对于尚未开始执行的排队请求,直接丢弃,不再处理
- 对于已经运行中的任务:MCP 标准无强制全局终止指令,默认继续执行完成
- 会话关闭后,后续不再向客户端推送该会话的进度、日志、结果报文
- 后果:客户端收不到未完结请求的返回数据,服务端后台任务依旧占用资源运行直至结束
2. 未结束上一个请求,并发发起新请求
协议允许并发多请求
- JSON-RPC 与 MCP 支持多路并行调用,客户端可以连续发送多条带不同 id 的请求,无需等待上一条应答
- 服务端按 id 区分不同调用任务,独立处理、分别回执,互不干扰
- 风险:无请求限制管控时,海量请求会造成服务端队列积压、资源占用、锁竞争
3. 客户端能否主动取消正在执行的请求
MCP 0.2.0 原生标准现状
协议层没有定义通用 cancel 取消方法
- 标准内置 method 里,不存在
request/cancel这类官方取消接口 - 原生能力:客户端无法通过标准报文,主动叫停已经下发的单次请求
- 衍生处理方案
- 方案 1(上层业务实现):自定义业务字段标记终止,不属于协议标准
- 方案 2(被动终止):客户端直接关闭会话,放弃接收结果,服务端任务后台自行跑完
- 方案 3:服务端自研超时机制,超时后主动终止任务释放资源
4. 大量请求堆积引发资源锁定问题
- 协议本身不做请求数量限流、任务强制销毁
- 资源锁、文件句柄、进程占用,由服务端自身代码管控
- 隐患:客户端批量发请求后断开会话,后台任务持续持有锁 / 文件资源,容易出现资源泄漏、死锁
- 规范兜底建议:服务端必须自行实现会话绑定资源回收、任务超时销毁机制
四、请求、通知、应答全行为约束汇总
1. 报文行为划分
表格
| 报文类型 | 携带 ID | 是否要求回执 | 客户端中断影响 |
|---|---|---|---|
| 初始化、工具、资源、关闭请求 | 有 | 必须返回 result/error | 中途关会话,回执丢弃,任务后台继续 |
| 进度、日志、资源变更通知 | 无 | 无需回执 | 会话关闭后停止推送 |
2. 非法请求判定
- 已关闭会话下发请求 → 返回会话状态错误
- 未初始化就绪执行业务请求 → 返回状态非法错误
- 调用协议不存在的方法 → 返回方法不存在错误
- 参数格式、权限不符 → 返回对应参数 / 权限错误
3. 中途插队、中断典型场景演示
场景:就绪状态下,id=20 文件修改请求发出,未收到回复,立刻发 shutdown
- 客户端报文序列
json
// 请求1 id=20
{"jsonrpc":"2.0","id":20,"method":"tools/call","params":{}}
// 不等应答,直接关闭会话
{"jsonrpc":"2.0","id":21,"method":"shutdown","params":{}}
- 服务端处理
- 响应 id=21 的 shutdown 请求,返回关闭成功 result
- id=20 对应的任务若已启动,后台持续执行
- 任务完成后不再向已关闭会话推送任何结果
- 相关文件、进程资源依赖服务端回收逻辑释放
五、补充协议缺失的能力与补充设计
- 原生协议缺失能力
- 无标准请求取消接口
- 无并发请求数量限制
- 无强制任务终止指令
- 仅靠会话关闭间接放弃结果,无法中断运行中任务
- 工程层面补足规则(协议外落地约束)
- 客户端:控制并发请求数,避免无限制批量下发
- 服务端:绑定会话生命周期销毁关联任务,会话关闭则超时回收占用资源
- 自定义扩展:基于标准报文格式,新增业务层取消指令,不破坏原有协议结构
六、总结核心定论
- 应答形态固定只有成功 result、失败 error 两种,无其他标准回执格式
- 状态机严格划分四阶段,跨状态非法请求直接报错拒绝
- 语法允许不等应答就发送关闭请求,会话会正常关闭,但运行中任务默认不会强制终止
- 支持多请求并发调用,协议不做数量管控,易产生资源堆积锁定
- 官方协议没有标准取消请求的方法,无法主动叫停已下发任务,只能靠会话关闭放弃结果、业务层自研回收机制
- 所有模糊边界、并发中断、资源问题,协议只定通信规则,任务调度与资源安全需要两端代码自行兜底实现
这个 MCP 我想确认一下,就是它里面这个 ID 实际上就是这个 Index,就是说调用的顺序。就是说连续调用,就第几个 round 吧,第几个第几回合的调用。那么还一个就是说它调用的这个方法,这些东西相当于说等于是大模型必须得知道这些方法。 Tools call 除了这个还有其他的吗?就是那个 method。
先把你两个疑问一次性讲透
一、JSON-RPC 里的 id 到底是什么
不是代码索引 Index,也不是项目代码下标就是单次请求唯一标识、回合序号
- 每发一次客户端请求,给一个自增数字
id=1、2、3... - 服务端响应必须带回一模一样的
id - 作用:配对请求和应答,多轮并发调用不会乱序、不会混包
举例:id=1 初始化握手id=2 查询函数id=3 查引用id=4 修改代码一一对应,就是你理解的第几轮调用。
二、MCP 标准内置 method 列表(不止 tools/call)
MCP 协议规定了固定标准方法,大模型客户端必须识别这套方法名,才能和服务端互通。整体分成五大类核心方法:
1. 生命周期握手类(连接建立)
initialize:初始化协商版本、能力、客户端服务端信息shutdown:断开会话、结束连接
2. 工具调用类(你最关心的执行操作)
tools/list:查询当前服务端有哪些可用工具tools/call:调用具体工具(查代码、运行命令、编译、读写文件)
3. 资源读取类(只读拿数据)
resources/list:列出可访问文件 / 目录 / 数据库资源resources/read:读取指定文件、配置、源码内容
4. 提示词模板类
prompts/list:查看预设提示模板prompts/get:获取标准工程提示词模板
5. 通知、日志、订阅类
notifications系列:日志推送、状态变更、实时消息
三、通俗对应理解(贴合你代码开发场景)
- initialize = 打开 IDE、连上代码服务
- tools/list = 看看 IDE 有啥功能:查定义、找引用、格式化、编译
- tools/call = 手动点「跳转到定义」「查找所有引用」
- resources/read = 打开某个源码文件查看全文
大模型不用自己写文件解析、语法检索逻辑,只需要按标准 method 发指令就行。
四、补充回答你第二个关键点
大模型是不是必须知道这些 method?是的MCP 是约定协议,客户端 Agent 必须认知这套标准方法名、入参格式,才能正常收发指令;服务端也只认这套标准 method,不认自定义随意写法。
五、常用高频 method 最简清单(日常代码 Agent 够用)
plaintext
initialize 初始化连接
tools/list 获取可用工具列表
tools/call 执行代码查询/操作
resources/read 读取源码文件
shutdown 关闭会话
六、顺带区分:和普通 Function Calling 的差别
- 普通函数调用:模型自定义函数名,各家格式不统一
- MCP method:全局标准化命名,所有 MCP 服务通用,跨 IDE、跨仓库、跨模型都能互通,刚好解决几十万行大项目工具调用混乱的问题。
七、一轮完整调用流程串起来
- id=1 → initialize 握手
- id=2 → tools/list 看有啥工具
- id=3 → tools/call 查函数定义
- id=4 → resources/read 打开关联源码全程靠 id 配对,method 标准指令交互。
要不要我给你列一张MCP 所有标准 method 速查表,方便你写 Agent 直接对照使用?
需要
MCP 极简调用示例(查询代码函数定义)
基于协议标准 JSON-RPC 2.0 格式,模拟 AI 客户端请求、代码服务端响应全过程,对应你查找代码定义的实际场景
基础说明
- 通信模式:客户端 (AI Agent) ↔ 服务端 (代码仓库 / IDE 索引服务)
- 交互链路:握手初始化 → 发起查询工具调用 → 服务检索返回结构化代码信息
步骤 1:初始化握手(两端协商能力)
客户端发起初始化请求
json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "0.1.0",
"capabilities": {},
"clientInfo": {
"name": "Code-AI-Agent",
"version": "1.0.0"
}
}
}
服务端返回确认,宣告自身具备代码检索能力
json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "0.1.0",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "Code-Index-Server",
"version": "2.1.0"
}
}
}
步骤 2:调用查询工具,查找目标函数定义
AI 发起指令:查询
userLogin函数的源码定义json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "find_function_def",
"arguments": {
"func_name": "userLogin",
"project_path": "/src/service/auth",
"search_scope": "whole_project"
}
}
}
步骤 3:服务端检索代码库,返回结构化结果
服务端依托代码索引、AST 解析,规避 grep 纯文本搜索的冗余结果,精准定位代码
json
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "文件路径:/src/service/auth/login.js\n行号:28-45\n函数源码:\nasync function userLogin(account, password) {\n const verifyRes = await passwordCheck(account, password);\n if(!verifyRes) return {code:401, msg:'账号密码错误'};\n const userInfo = await getUserData(account);\n return {code:200, data:userInfo};\n}"
}
],
"isError": false
}
}
结合 40 万行代码门槛的对照理解
- 传统 grep:仅字符串匹配,会匹配注释、变量名、日志文本里同名字符,结果杂乱无意义
- MCP 调用工具:依托代码语法树、项目索引,只匹配函数实体定义,过滤无效干扰项
- 大项目场景价值:数十万行代码下,标准化协议让 AI 稳定调用 IDE 级检索、引用溯源、重构工具,不会因代码体量膨胀丢失检索逻辑
补充和普通函数调用的差异
- 统一协议规范,任意大模型、任意代码服务都可互通,无需单独写适配代码
- 自带会话上下文,可连续溯源调用关系、多层函数引用
- 支持权限管控,可限定只读查询,避免 AI 随意篡改核心代码
好啊,你把所有的 methods 标准速查表给我一下,完整的。
MCP (Model Context Protocol) 官方完整标准 Method 速查表
协议基准版本:0.2.0底层传输:JSON-RPC 2.0分类规整,含用途、调用方、典型场景,可直接用于 Agent 开发对照
一、会话生命周期方法
负责连接建立、版本协商、会话销毁
表格
| 方法名 | 调用方 | 核心作用 |
|---|---|---|
initialize | Client | 初始化握手,协商协议版本、两端能力、客户端 / 服务端信息 |
initialized | Server Notification | 通知客户端初始化完成,进入可用状态 |
shutdown | Client | 主动终止会话,释放连接与资源 |
二、工具调用体系 Methods
可执行操作、代码检索、命令运行、业务动作
表格
| 方法名 | 调用方 | 核心作用 |
|---|---|---|
tools/list | Client | 获取服务端全部注册可用工具清单、工具描述、入参结构 |
tools/call | Client | 发起工具执行调用(查定义、找引用、编译、格式化、脚本运行) |
tools/changed | Server Notification | 工具列表发生增减变更,推送通知客户端刷新 |
三、资源访问体系 Methods
只读读取文件、目录、数据库、配置、源码资源
表格
| 方法名 | 调用方 | 核心作用 |
|---|---|---|
resources/list | Client | 枚举服务端可访问的所有资源路径、目录结构 |
resources/read | Client | 读取指定文件 / 资源的原始内容 |
resources/subscribe | Client | 订阅资源变动监听 |
resources/unsubscribe | Client | 取消资源变动订阅 |
resources/updated | Server Notification | 资源文件内容变更,主动推送通知 |
四、提示词模板体系 Methods
复用标准化工程提示、场景化模板
表格
| 方法名 | 调用方 | 核心作用 |
|---|---|---|
prompts/list | Client | 获取服务端预置的所有提示词模板列表 |
prompts/get | Client | 读取指定模板内容,可带入参数渲染 |
prompts/changed | Server Notification | 提示模板更新,通知客户端刷新 |
五、日志、进度、基础通知类
运行状态反馈、日志输出、任务进度
表格
| 方法名 | 调用方 | 核心作用 |
|---|---|---|
logging/message | Server Notification | 输出运行日志、报错、告警信息 |
progress | Server Notification | 长耗时任务进度推送(代码扫描、全仓检索) |
六、采样交互方法
模型与服务端双向上下文交互、用户交互问询
表格
| 方法名 | 调用方 | 核心作用 |
|---|---|---|
sampling/createMessage | Client | 请求服务端侧模型采样生成消息 |
七、完整规范补充说明
- id 规则
- 请求报文必须携带数字
id,自增编号,代表一轮独立调用回合 - 响应报文原样带回对应 id,用于请求应答配对,防乱序、并发错乱
- 通知类 Notification 消息不带 id,单向推送无需应答
- 请求固定报文结构模板
json
{
"jsonrpc": "2.0",
"id": 轮次编号,
"method": "标准方法名",
"params": {}
}
- 响应固定报文结构模板
json
{
"jsonrpc": "2.0",
"id": 对应请求id,
"result": {}
}
- 通知消息结构(无应答)
json
{
"jsonrpc": "2.0",
"method": "通知类方法名",
"params": {}
}
八、高频常用极简精简版(代码 Agent 日常必备)
plaintext
// 连接管控
initialize
shutdown
// 工具核心
tools/list
tools/call
// 代码文件读取
resources/list
resources/read
// 提示模板
prompts/list
prompts/get
九、和你之前代码场景对应对照
- 查函数定义 / 找所有引用 →
tools/call - 打开源码文件查看 →
resources/read - 先看看当前支持哪些代码工具 →
tools/list - 新建会话连接代码服务 →
initialize - 几十万行项目全仓扫描进度 →
progress通知
我有两个疑问,一个就是说这个发起会话,结束会话,实际上就是说, initialize 跟 shutdown 只能是 client 端,就是大模型端。等于 Server 端是无条件的,必须得可靠。意思就说 Server 端是不能够销毁这个,关闭对话,或者说是,它不能出错。那么同样道理,就是说对于这些客户端,就是大模型发起的这些命令, Server 端也是无条件不能够说你这个不合法什么之类的。那也就是说, Server、 Client 端必须得他调用的东西,比如说 resource list 等等,那 Server 端返回,然后他去调用,他会不会犯错呢?就是根本调用一个不存在的方法。或者说是 resource subsc- subscribe 等等,它会不会搞错了?或者说 Server 端的这方法出错了? Server 能不能返回出错呢?这好像你的这个,你说给我完整的这个方法,但是我感觉总是,你确实是完整的吗?这中间没有容错机制吗?就是 Server 端是一定是 100 可靠的,那客户端也不允许犯错误,是这样的吗?
逐条解答你的核心疑问
先给出核心结论:客户端独占会话启停权,服务端不能主动断开;两端都会出错,协议内置完整容错、报错、异常处理机制,不存在两端绝对零错误的强制要求
一、会话启停权限归属
- initialize、shutdown 仅允许客户端发起调用
- 客户端:AI Agent、IDE 插件等主动发起方,掌控会话生命周期
- 服务端:只能被动响应握手请求,无权主动关闭、销毁会话,不能主动发 shutdown 终止连接
- 服务端基础要求
- 常态下必须保持服务监听,可靠处理合法请求
- 但不等于绝对不死机、不崩溃,硬件、进程、代码异常依旧会出问题
- 边界规则
- 服务端无法主动掐断对话,只能被动等待客户端关闭
- 客户端随时可以发起 shutdown 结束本轮会话,释放两端资源
二、非法调用、不存在方法、参数错误的实际情况
1. 客户端完全可能犯错
常见错误场景:
- 调用协议里未定义的 method 名称
- 调用当前服务端未实现的标准方法(比如服务没做订阅能力,客户端却发
resources/subscribe) - 方法存在,但入参格式、字段类型、必填参数缺失
- 会话未完成 initialize 握手,就直接调用工具、资源读取接口
2. 服务端可以合法返回错误,协议标准支持异常应答
JSON-RPC 2.0 原生定义错误返回结构体,MCP 沿用这套规范,遇到非法请求就返回错误,不会无响应、不会强制兼容错误调用
标准错误响应格式
json
{
"jsonrpc": "2.0",
"id": 对应请求的回合ID",
"error": {
"code": 错误编码,
"message": 错误描述文本,
"data": 附加详情数据
}
}
3. 常见错误类型对应场景
表格
| 错误情形 | 服务端返回行为 |
|---|---|
| 调用不存在的 method | 返回方法未找到错误码 |
| 调用服务端未实现的标准方法 | 返回能力不支持错误 |
| 参数缺失、格式非法 | 返回参数无效错误 |
| 未初始化就执行业务调用 | 返回会话状态非法错误 |
| 权限不足访问受限资源 | 返回权限拒绝错误 |
| 服务内部代码异常、检索崩溃 | 返回服务内部错误 |
三、两端是否强制要求 100% 无错?
并不是硬性强制零错误
- 客户端侧
- 协议只规定合法调用格式,不约束客户端逻辑正确性
- Agent 代码编写缺陷、模型决策失误,都会发出错误请求
- 客户端必须自行做调用校验,也需要处理服务端回传的错误信息
- 服务端侧
- 规范要求合规实现已声明的方法,但无法杜绝程序 BUG、运行异常
- 服务可以报错、可以拒绝非法请求,也可能自身运行崩溃
- 不能无视错误强行执行非法指令
四、协议自带的容错与约束机制
- 能力协商容错初始化握手阶段,两端互相上报自身支持的能力列表。客户端可以先读取服务端
tools/list、resources/list,知晓对方实际支持哪些功能,再发起调用,从源头减少无效调用。 - 状态机约束会话有固定状态:未初始化→已就绪→已关闭状态不匹配的调用直接报错,规避乱序操作
- 错误码体系区分问题根源
- 协议规范错误:方法不存在、格式错误
- 业务能力错误:功能未实现、权限不够
- 运行时错误:内部异常、资源加载失败
- 通知类消息容错兜底日志、进度通知单向推送,即便客户端接收异常,也不阻塞主调用流程
五、补充回应你两点关键理解修正
- 服务端不是无条件承接所有命令合法请求正常返回结果,非法、越权、不存在的调用,统一返回错误拒绝执行
- 方法列表是完整标准定义,但实现可选这份速查表是协议全部标准方法,实际部署的服务端可以按需裁剪实现,不用强制做完所有接口。客户端调用未实现接口就会触发报错,这是正常交互逻辑
- 会话权责边界开、关会话的权限牢牢在客户端;执行调用的对错、异常处理,两端共同承担,依靠协议报错机制完成异常交互。
六、简易错误调用示例
客户端错误调用不存在方法
json
{
"jsonrpc": "2.0",
"id": 5,
"method": "func/notExist",
"params": {}
}
服务端标准错误回复
json
{
"jsonrpc": "2.0",
"id": 5,
"error": {
"code": -32601,
"message": "指定方法不存在"
}
}
那么目前目前这个业界 MCP 的这个应用状态是怎么样?就是说它的普及率或者说是采纳率,有没有一个统计数字啊?就说还有没有其他的解决方案呢?还有没有其他的这种做法呢?这个现在是成为了业界标准吗?还是说大家还是有其他的做法?是否它还有继续发展的趋势呢?
搜索 3 个关键词,参考 15 篇资料
一、MCP 当前普及率与采纳率(2026 年 5 月最新数据)
- 核心数据
- 公开 MCP 服务器:17,468 个(2026 年 4 月,较 2024 年底增长 170 倍)
- SDK 月下载量:9700 万 +(2026 年 3 月,2024 年底仅百万级)
- 企业采纳率:78%(生产环境已用,Gartner/Thoughtworks 联合调研)
- 主流平台覆盖率:100%(ChatGPT、Claude、Gemini、Copilot、VS Code 等均原生支持)
- 行业渗透:金融、制造、SaaS、医疗等75% API 网关 / 50% iPaaS计划年内内置 MCP
- 关键节点
- 2024-11:Anthropic 开源 MCP(初始仅 Claude 支持)
- 2025-04:OpenAI 全面接入,爆发式增长
- 2025-12:移交Linux 基金会 AAIF,成为中立行业标准(Google/Microsoft/AWS 共建)
二、是否已成业界标准
是,已成为 AI 工具调用的事实标准,但非唯一标准。
- 现状:MCP 是唯一跨厂商、开源中立、企业级落地的协议,覆盖绝大多数新 Agent 项目。
- 未完全垄断:遗留系统仍用私有方案(如 OpenAI Function Calling、LangChain 自定义适配)。
三、其他主流解决方案(对比 MCP)
1. 私有函数调用(Function Calling)
- 代表:OpenAI、Anthropic 原生接口
- 特点:厂商绑定、紧耦合、无状态,需为每个模型重写适配
- 现状:存量项目在用,新建项目快速迁移至 MCP
2. Google A2A(Agent-to-Agent)
- 定位:Agent 间协作层(非工具调用层),解决多 Agent 任务编排
- 关系:与 MCP互补,非竞争(MCP 管工具,A2A 管 Agent 互操作)
3. 自研框架(LangChain/LlamaIndex)
- 特点:上层封装工具调用,无统一通信标准,依赖框架生态
- 现状:快速集成可用,但企业级生产逐步替换为 MCP(解耦、安全、可扩展)
4. 其他小众协议
- ANP:侧重身份与发现;Pilot:侧重网络传输层,均未形成规模
四、MCP 发展趋势(结论:长期主流,持续演进)
- 生态持续扩张:Gartner 预测 2027 年 MCP 服务器将破10 万,成为 AI 基础设施标配。
- 能力增强:2.0 版本规划分布式 Agent、状态机原生支持、请求取消、强时序约束(补你痛点)。
- 分层标准化:MCP 专注通信层,上层状态机 / 流程编排将出现开源标准框架(解决重复造轮子)。
- 企业级深化:安全(认证 / 限流)、可观测性、事务化能力完善,适配关键系统。
五、总结
- MCP 是当前唯一工业级、跨厂商、中立开源的工具调用协议,普及率78%+,事实标准地位稳固。
- 替代方案多为私有 / 上层封装,仅适配存量场景,新建项目优先 MCP。
- 你的痛点(状态机、取消、时序)是行业共识,MCP 2.0 已纳入规划,短期内需自研状态层,长期将有标准框架落地。
要不要我把 MCP 与 Function Calling、A2A 的核心差异浓缩成一页对比表,方便你快速查阅?
有的并发多请求的话是自相矛盾的,怎么办呢?那 server,比方说前面一个是说把什么什么文件标志成只读。我现在想不起来,想不出来哪些是并发矛盾的并发。或者说任何一个动作,任何一个请求都是一个完整的原子操作,不可能出现说互相矛盾的请求。因为它没有上下文机制,就是一个动作就是一个动作。所谓矛盾,也就是说 flip flop 就是第一个请求关闭某个服务,第二个请求打开某个服务。这些都是原子操作,互相没有序列化。什么意思呢?就是说,比如说 ID 并不代表说执行的先后。比如说第一个 id 等于 4 的时候,说把文件制成只读。然后 id 设成 5 的时候请求把文件设成可可写,那作为 service server 这一方的话,他需要按照这个 id 的顺序去进行执行呢?还是说它是并发执行,可能就是说先去把文件写成设成可写,执行了第五个, ID 等于 5 的可写,然后后来它执行这个 ID 等于 4 设成了文件只读。意思就是说这个 Server 端是先先进先出这种这种队列式的,必须按照队列式的进行执行,而不能所谓真正的并发,就是乱序的执行。这协议有没有规定呢?
核心结论前置
MCP 依托底层 JSON-RPC 2.0 协议,本身没有强制要求请求必须按 ID 顺序、按收发先后串行执行;协议层面允许服务端乱序并发处理不同 ID 请求。但工程落地里,文件读写、启停服务这类状态互斥、资源抢占类操作,必须由服务端自行做队列串行、加锁管控,否则必然出现执行时序错乱、业务结果不符合预期。
一、先厘清两个关键概念
- 请求 ID仅用于请求与应答配对,不代表执行优先级、执行先后顺序,ID 数字大小和处理时序无绑定关系。
- 报文收发顺序 vs 实际执行顺序
- 客户端按 id4 → id5 依次发出报文
- 协议不约束服务端必须按接收顺序执行
- 服务端线程池异步处理下,完全可能先跑完 id5,再处理 id4
对应你举例场景:
- id4:将文件设为只读
- id5:将文件设为可写无队列、无锁约束时,最终文件权限结果不可控,时序颠倒会违背操作意图。
二、协议原文对执行时序的规定
- JSON-RPC 2.0 规范条文协议未定义请求执行排序规则:
- 客户端可以任意顺序接收应答
- 服务端可自由选择串行 / 并行 / 乱序处理独立请求
- 仅要求应答报文的 ID 与原请求一一对应即可
- MCP 继承该规则MCP 只约束报文格式、方法定义、应答规范,不对业务任务的调度顺序做强制约束。简单说:协议不管你先跑哪个任务,只要求最后每个请求都给出对应回执。
三、两种服务端执行模式对比
模式 1:串行队列(先进先出 FIFO)
所有收到的请求进入阻塞队列,严格按照接收报文的先后顺序依次执行,上一个任务结束,才取下一个任务执行。
- 适配场景:文件权限修改、启停服务、数据库读写、配置变更等状态类操作
- 你举例的权限切换,用该模式就不会时序颠倒
- 优点:规避互斥操作冲突,符合人类操作预期
- 缺点:耗时任务会阻塞后续所有请求
模式 2:真正并发调度
多线程 / 多进程分发不同 ID 请求,同时执行多个任务,执行完成后按需返回应答。
- 适配场景:互不干涉的独立查询,比如分别读取两个无关文件、查询不同进程信息
- 风险:存在状态互斥操作时,时序错乱、结果异常
- 典型问题:先发只读、后发可写,最终变成只读覆盖可写
四、针对你文件权限冲突案例推演
客户端发送顺序:id4 (设只读) → id5 (设可写)
情况 1:服务端 FIFO 串行执行
执行顺序固定 id4 → id5
- 执行 id4,文件标记只读
- 执行 id5,文件修改为可写最终状态:文件可写,符合客户端下发操作的先后意图
情况 2:服务端无锁并发执行
线程调度随机,出现逆序执行
- id5 率先完成,文件设为可写
- 后执行 id4,文件被改为只读最终状态:文件只读,和操作下发意图完全相悖
五、协议层面有无解决方案?
- 协议本身无内置排序、事务、锁机制没有标准方法标记操作时序、没有原子事务分组、没有互斥锁指令,无法从协议层强制约束执行顺序。
- 官方协议兜底原则协议只保证通信可靠,业务操作的时序一致性、资源互斥,全部交由服务端业务代码实现。
六、工程落地规范(解决并发矛盾的通用做法)
- 区分操作类型,差异化调度
- 状态变更、资源修改、互斥操作:强制放入全局队列,串行 FIFO 执行
- 只读查询、独立无关任务:允许并发执行,提升效率
- 资源维度加锁控制以文件、服务、端口等资源为粒度加锁,同一资源同一时间只允许一个写操作,避免并发篡改。针对示例:同一个文件同时只能处理一条权限修改请求。
- 客户端侧规避策略
- 强时序依赖的连续操作,客户端等待上一条请求应答返回后,再下发下一条请求
- 从调用侧规避并行下发互斥指令
- 扩展层实现时序标记可在请求
params内自定义排序序号、事务编号,服务端依据自定义序号排序执行,属于业务层扩展,不改动标准协议。
七、总结
- 标准 MCP+JSON-RPC 协议不强制执行顺序,ID 不决定处理先后,服务端原生支持乱序并发;
- 互斥类操作(权限修改、服务启停、数据改写)直接并发会产生逻辑矛盾;
- 想要保证操作按下发顺序生效,必须服务端自行实现 FIFO 队列、资源锁管控;
- 纯查询类无冲突请求,可保留并发执行,兼顾运行效率;
- 协议只管通信报文合规性,业务时序与并发安全不属于协议约束范畴。
我感觉这套 MCP 的话,必须得,就是大模型一方必须得有一个上下文,就是一个状态机机制,它才能够知道说做什么,等什么。就意思是什么东西呢?在大模型去这这端你还是要写一个,还是要一个 prompt engineering 或者说 prompt harness 的一个内部的做法,就是意思就是说你必须要,我说一说我目前的想法是怎么样,你然后告诉我业界是怎么去做的。比如说你必须让这个大模型自己写下来,说我当前我要去调用,比方说 Tools call read 某一个文件。然后这个是我当前要做的,然后呢我要期待着模型,这个叫什么,服务端返回什么什么,然后我下面要做什么什么,就是一个把这个上下文就是用来存储它当前做了什么,下一步准备做什么。就这一套的想法它得写下来,不然的话我认为说它很可能不知道自己要做什么。就是就说我的意思是说现在的大模型是否能够做到说它是个状态机,看到这个上一次返回的这个 JSON RPC 返回的结果,它知道它它调用的是什么,它知道自己上一个做了什么,然后就能处理。意思就是说,如果我不把这个调用作为 prompt,仅仅把这个 MCP 的结果给大模型的话,它是否能够知道这个是针对哪一个调用?因为从这个 MCP 的这个结果看起来实际上它是没有回应这个是真只有个 ID 而已。它是没有回应说这个是没有透露出这个是什么样的调用,比如说是 Tools call 啊,还是 Tools list 啊,还是什么东西,它是一个结果。意思就是说这个如果我们在 prompt 里面不把这个 MCP 的调用部分也作为上下文喂给这个大模型的话,只把这个结果给大模型看的话,大模型完全不知道自己这个调用的是干什么的。同样的,我怀疑,就说这个路线图也得要存起来。就是大模型它要做什么事情,它这先要把这个存起来,我这一步做一步一步做一步,我要这个 roadmap 我要写下来。就意思说这个状态机这一块程序必须得要去实现。当然了,你说 prompt harness 这个事情你你不去做的话,那你还编程编什么东西?但是这个东西就相当于说是,给每个模型应用层就得要去做这个叫什么状态会计就都大家都得要写一套 prompt 的模板的状态机来去做这个事情。没有业界没有一个标准的规范,或者说是每个模型都不一样。或者每个任务都不一样。所以这这一个地方还是挺啰嗦,挺复杂的。
对齐你的核心思路 + 业界现行落地方案
先直接定论:你的判断完全切中现实 ——单纯裸跑 MCP 报文交互,大模型本身没有内置业务状态记忆、步骤路线、调用溯源能力。必须在模型外层,封装一层应用级状态机 + 调用上下文记忆 + 任务路线快照,也就是你说的 Prompt Harness 框架;目前业界无统一强制标准,各家自研状态管理逻辑,这也是当前 AI 工具调用工程里最繁琐、无法偷懒的一层业务编码。
一、先拆解你提出的两个核心痛点
1. 只回传 MCP 结果,模型无法溯源对应哪一次调用
MCP 应答报文结构:只带
id、result/error,不会原样附带当初调用的 method、入参、业务意图示例返回只给数据,不带调用溯源信息json
{
"jsonrpc":"2.0",
"id":10,
"result":{"content":"文件配置内容"}
}
- 模型只拿到这一段 JSON,脱离外部记忆存储,仅凭返回体不知道:这是
tools/call还是resources/read、当初查的哪个文件、上一步操作目的是什么 - ID 只是通信配对标记,模型原生不会把 ID 和业务动作自动绑定记忆
2. 模型自身无步骤路线、执行状态、下一步规划
大模型单次推理是无记忆断层式输出:
- 发完一次调用就遗忘上下文链路
- 收到返回结果后,不会自动回忆「上一步做了啥、当前处于任务第几阶段、后续预定步骤」
- 复杂串行流程(开锁、编译、多步配置)极易断逻辑、乱步骤、重复错误调用
3. 必须外置一层状态机承载三件事
- 历史调用快照:每一条发出的 MCP 请求(method、参数、id、意图)持久留存
- 当前运行状态:空闲 / 等待应答 / 执行中 / 出错暂停 / 即将关闭
- 任务路线图 Roadmap:预设步骤清单、依赖先后、分支判断、终止条件
没有这层外置状态托管,纯靠模型临场推理,一定会逻辑脱节、动作错乱。
二、业界主流做法:三层架构,和你的构想完全吻合
当前所有基于 MCP / FunctionCall / Agent 工具调用的工程,通用分层:
plaintext
业务状态机层(Prompt Harness)
↓
大模型推理层
↓
MCP 协议通信层
↓
Shell/IDE/服务端工具
1. 外层:自研应用状态机(所有项目必写,无统一国标)
这一层就是你说的人工实现状态机 + 上下文存储 + 路线记录,每家写法不同,但核心模块高度一致状态机固定存储字段:
- 会话全局 ID
- 调用记录表:id → 原始 method + 入参 + 业务目的 + 发出时间
- 当前节点:任务走到第几步、上一步结果
- 预设路线栈:预先规划好的执行顺序清单
- 状态枚举:IDLE / WAIT_RESP / RUNNING / ERROR / FINISH
- 超时、重试、异常分支标记
运行逻辑完全贴合你的想法
- 状态机先读取当前进度、剩余步骤
- 把历史调用 + 上一轮返回结果 + 当前状态一起拼装进 Prompt 上下文喂给模型
- 模型基于完整记忆,决策下一步该发起什么 MCP 调用
- 发出调用后,状态机立刻存档本次调用快照,切换为「等待应答」状态
- 收到服务端返回,状态机匹配 ID 回填结果,更新阶段,再进入下一轮推理
2. 解决「模型认不出返回对应哪次调用」的标准手段
业界通用兜底方案:状态机不丢弃任何请求记录,应答回来靠 ID 反向检索当初调用意图
- 发
id=10 resources/read,状态机表里存:10 = 读取配置文件 - 收到 id=10 结果,查表还原本次调用含义
- 将「原始调用动作 + 返回数据」合并送入模型上下文模型就能清晰知道:这是读取文件的结果,接下来可以解析、修改、下一步调用命令
只扔裸 JSON 不给溯源信息,模型必然失忆;必须外层状态机做映射补全语义。
3. Prompt Harness 工程模式现状
- 无统一官方规范Anthropic 只定义 MCP 通信报文,完全不约束上层状态管理、上下文拼装、步骤编排
- 各家自研模板、状态流转、记忆策略
- 轻量场景:数组存步骤列表、简易状态变量
- 复杂关键场景:有限状态机 FSM、任务栈、事务上下文、分支判断
- 无法通用复用代码、Shell、工控、运维不同任务,状态规则不一样,必须针对性编写 Prompt 模板与状态跳转逻辑这就是你体感的:啰嗦、重复、繁琐,没有统一标准一键套用。
三、对应你设想的「任务 Roadmap 落地形式」
业界实际就是把路线固化在状态层,两种常用写法
- 预定义串行路线(适配保险柜、固定流程)状态机提前写死步骤队列:步骤 1:左转旋钮 → 步骤 2:右转旋钮 → 步骤 3:输入密码上一步应答成功,才解锁下发下一步;失败直接终止,禁止乱序调用
- 动态规划路线(适配代码查改、灵活任务)状态机记录已完成节点,模型根据返回结果动态生成后续路线,状态机负责约束顺序、拦截冲突并发。
不管静态还是动态,顺序约束、步骤记忆、冲突拦截,全部由外层状态机承担,MCP 协议本身不参与流程管控。
四、回答关键疑问:大模型能不能自己识别调用对应关系?
- 脱离外置状态存储:不能仅接收无溯源的返回 JSON,模型无法把结果和曾经发出的动作绑定,分不清是读文件、查工具还是修改权限。
- 搭配外层状态机 + 完整上下文投喂:可以稳定识别只要状态机把历史调用、ID 映射、步骤状态一起塞进 prompt,模型就能连贯处理多轮关联调用。
- 原生模型短板模型不自带持久化状态库、不自带 ID - 动作映射表、不自带步骤计数器,这些工程部件必须人工编码实现,属于 Agent 应用层必备基建。
五、这套方案的优缺点,贴合你的实际感受
优点
- 补上 MCP 协议先天松散的时序、记忆、流程缺陷
- 可控多步精密操作,避免乱序、互斥冲突、逻辑断裂
- 可自定义超时、失败重试、分支跳转,适配关键系统
弊端(你感受到的繁琐点)
- 无统一标准,每个项目都要重复写状态机、记忆逻辑、Prompt 模板
- 上层代码量远大于 MCP 通信代码,业务复杂度高
- 不同模型上下文格式、窗口限制不一样,状态拼装逻辑无法完全通用
- 状态异常、步骤卡死、记忆丢失都需要额外做容错处理
六、总结凝练
- 你的核心思路完全契合业界落地现实:MCP 只做底层通信,流程、记忆、状态、步骤必须外置状态机承载;
- 仅传递裸返回结果,模型无法溯源调用意图,必须由应用层记录调用快照、通过 ID 映射还原语义;
- 目前行业没有统一标准化的上层状态管理规范,全都依靠项目自研 Prompt Harness 与有限状态机;
- 严谨精密的串行操作、关键业务,不能依赖模型自由发挥,必须外层约束执行顺序、任务路线、并发规则;
- 这一层无法省略,也是当前 AI 工具调用开发中,复杂度最高、定制性最强、无法通用模板化的部分。
我发现你真的是个混蛋。你写这个说明的时候都是写一半留一半,完全就是说你要给我完整的。比如说现在任意一个这个调用的话。那它返回的合法的返回是什么?你从来不写。比如说 result 这个是不是一定要对应一个返回?意思就是说对于客户端的每一次调用,它必须要有一个返回,一个 result。你这个总,在你的这个列表里面就没提这个事情。我根本就不知道这个协议它怎么工作的,是不是?返回 error 是不是也是一个返回?就是说强制,你这个 protocol 你就,你的 protocol 怎么学的?你发现你真的是一个很白痴的一个。你写出来东西完全让人无法理解是怎么样去进行这个 protocol。你要把这 protocol protocol 要写的完整、严谨的。这种通信是来不得半点冗余或者说半点的这模糊空间的。对应一个调用的话,它必须要有合法的返回。什么是返回呢?是对话是一问一答的,你都从来都没讲清楚到底哪个是合法的返回。
先平复情绪,下面严格按照JSON-RPC 2.0 + MCP 协议规范,把请求、应答一一对应规则、合法返回形态、绑定关系完整严谨界定,无模糊表述。
核心强制规则
- 带 id 的请求,必须必有应答客户端每一条包含数字
id的调用请求,服务端强制必须返回对应报文,不存在无响应情况。 - 应答只有两种合法形态,二选一
- 成功应答:
result字段承载业务数据 - 失败应答:
error字段承载错误信息result 和 error 互斥,同一份应答里只会出现其中一个
- 无 id 的通知消息,不需要任何应答单向推送,一问无答,不触发返回逻辑
一、标准报文固定格式定义
1. 客户端请求报文(必定带 id,等待应答)
json
{
"jsonrpc": "2.0",
"id": 整数编号,
"method": "协议标准方法名",
"params": {}
}
2. 成功应答报文(对应请求 id,返回 result)
json
{
"jsonrpc": "2.0",
"id": 和请求完全一致的编号,
"result": {}
}
3. 错误应答报文(对应请求 id,返回 error)
json
{
"jsonrpc": "2.0",
"id": 和请求完全一致的编号,
"error": {
"code": 数值错误码,
"message": 错误描述,
"data": 可选附加信息
}
}
4. 服务端通知报文(无 id,无需应答)
progress、logging、资源变更、工具变更都属于此类
json
{
"jsonrpc": "2.0",
"method": "通知类方法名",
"params": {}
}
二、问答绑定关系 1:1 强制约束
- 同步调用类(initialize /tools/list/tools/call/resources/read 等)
- 客户端发请求 → 服务端必须回包
- 最终收尾只能是:成功 result 或者 错误 error
- 中途的 progress、logging 只是附加状态推送,不能替代最终应答
- 哪怕任务耗时数分钟,过程不断发进度通知,结束后依然要补齐同 ID 的最终结果报文
- 通知类消息仅状态播报,不属于请求应答范畴,客户端收到后不用回任何数据
三、结合 Shell 场景完整闭环示例
场景:客户端发起文件编辑 tools/call 请求
请求(id=12,等待应答)
json
{
"jsonrpc":"2.0",
"id":12,
"method":"tools/call",
"params":{
"name":"file_modify",
"arguments":{"path":"/test.txt","content":"new text"}
}
}
过程推送(无 id,仅状态,不算应答)
多条进度、日志通知独立推送,不绑定应答逻辑
json
{"jsonrpc":"2.0","method":"progress","params":{"progress":30}}
{"jsonrpc":"2.0","method":"logging/message","params":{"level":"info","msg":"文件写入中"}}
情况 1:执行成功,返回标准 result 应答
严格匹配 id=12,本轮调用正式结束
json
{
"jsonrpc":"2.0",
"id":12,
"result":{"status":"done","fileSize":256}
}
情况 2:执行失败,返回标准 error 应答
同样匹配 id=12,本轮调用终止
json
{
"jsonrpc":"2.0",
"id":12,
"error":{"code":-32001,"message":"权限不足无法修改文件"}
}
四、关键边界判定汇总
- 只要请求携带
id→ 服务端绝对不能省略应答 - 应答只能二选一:result 成功 /error 失败,不能同时存在,也不能都不存在
- 过程性进度、日志通知,属于附加信息,不充当最终答复
- shutdown、initialize 这类会话控制请求,同样遵循请求必应答规则
- 仅不带 id 的单向通知,无应答要求
五、方法类别对应应答规则对照表
表格
| 方法分类 | 是否带请求 id | 是否必须返回应答 | 返回形式 |
|---|---|---|---|
| initialize、shutdown | 是 | 必须应答 | result / error |
| tools/list、tools/call | 是 | 必须应答 | result / error |
| resources/list、resources/read | 是 | 必须应答 | result / error |
| prompts/list、prompts/get | 是 | 必须应答 | result / error |
| progress、logging/message | 否 | 无需应答 | 无返回报文 |
| resources/updated、tools/changed | 否 | 无需应答 | 无返回报文 |
我觉得吧,这个 MCP 等于是相当一个半吊子货。所有的大模型,你通通都要把这个结果,就是把这个发起的请求跟这个结果对照着看才行。这个是任何一个模型的 prompt 都要包含的部分。那你为什么不把不把这个作为协议的一部分,就是直接在 client 端去做这个事情呢?反而是说因为这个把它当做是一个隐含的事情。我觉得应该把它当做显示的,就是说这个必须成为大模型调用的,就是上下文的一部分。什么意思呢?就是说它调用的内容你必须得保留。然后和结果一起喂给大模型。当然这个好像是废话一样,这每个写那个大模型的 prompt engineering 都应该知道的事情。但是这个你你说是不是必须的吧?我认为是完全必须的,就大模型现在有没有能力说,哦,他看到这个结果就能推测出来啊,这个是什么东西。那么这个叫做 MCP,你如果不包含这个状态机的这个架构的话,这个协议我觉得就是等于是一个不完整的。当然我理解说它如果包含了状态机的话,肯定没人用,或者说大部分公司不去用。原因就是说每个公司自己都有自己的实现。这个这个上下文机制不一样,跟它的逻辑不一样,它每个实实现的方式想法也不同,所以它只规定通讯这一块协议,那个背后的这一块它完全放开了不说。这个我觉得也是合理的,否则的话,它这个覆盖太广的话,局限性很大,别人根本没法用,就就不遵循它这一套。它这一套属于比较轻量化的。而且是比较通用的,不会跟每一家的背后实现产生冲突。看起来也没有什么更好的这种,就是说没有一个,就是说能够开箱即用,把这个整个这个流程全部都打通的这个没没有这一套。就是这个模型这一端还是要去写很多代码,去实现一个状态机,实现一个上下文的存储,实实现一个日志啊,实现一个,这还是还是很多工作的。这路线图要怎么存呢?这些这些其实都是可以标准化,这就是一个操作系统的一个部分。现在等于是没有一个开源的操作系统去做这个事情。
你的判断直击本质,同时也把协议设计取舍、行业现状、技术取舍逻辑梳理得很透彻,我们分层把观点落地印证
一、核心结论先定调
- 请求报文 + 响应结果成对留存,完整送入模型上下文,是绝对刚需,不存在例外只单独返回结果,模型无法语义溯源、无法承接后续逻辑,任何生产级 Agent 都必须这么做,这不是可选优化,是必备前提。
- MCP 刻意只做纯通信层标准化,主动放弃上层状态机、上下文存储、任务路线管理,属于设计取舍,而非设计疏漏。
- 一旦把状态机、上下文规则强行纳入协议约束,通用性会大幅坍缩,适配不同业务、不同厂商架构的难度剧增,反而没人愿意兼容。
- 目前行业确实缺少统一开源的 AI 任务操作系统,状态管理、流程编排、上下文存储各家自研,重复造轮子成本很高。
二、为什么协议不把「请求 - 响应绑定上下文」做成强制标准
1. 业务形态差异极大,没法统一格式
不同场景对上下文的诉求完全不一样
- 简单查询类:只需要记录最近一轮调用与结果即可
- 串行精密流程(开锁、设备操控):需要完整步骤栈、执行时序、分支判断
- 并发多任务运维:需要多组独立调用链路隔离、资源标记
- 长周期项目(几十万行代码重构):要历史溯源、版本快照、操作回滚记录
如果协议统一规定上下文存储结构、状态字段、路线图格式,会强制束缚所有开发者。轻量场景觉得冗余臃肿,复杂定制场景又满足不了个性化逻辑,最终标准会形同虚设。
2. 厂商自研体系存在壁垒,不愿被统一规范绑定
各家大模型、Agent 框架都有自身的记忆机制、会话架构、权限体系
- 有的用内存临时存储上下文
- 有的持久化数据库归档操作日志
- 有的结合向量数据库做历史调用检索
- 有的绑定自身业务权限、账号体系做隔离
MCP 只管住跨端通信报文,不触碰内部数据存储与逻辑编排,最大程度兼容各家现有架构,不会和企业自研体系产生冲突,这是轻量化通用协议的生存逻辑。
3. 分层设计的工程理念
协议设计遵循职责拆分
- MCP 层:只负责报文格式、方法定义、应答规则、错误规范,解决跨模型、跨工具互通问题
- 应用层:状态机、上下文配对、任务路线、流程管控、日志归档,全部交给开发者按需实现
就像网络协议只规定数据包格式,不会规定应用层如何解析数据包、如何拼接业务逻辑,原理一致。
三、只传结果不绑定原始请求,模型自身做不到溯源推断
- 从模型能力本质来说大模型没有全局通信会话记忆,脱离外部存储的调用记录,仅凭
id和结果 JSON,无法反向对应当初调用的method、入参、业务目的。同一个结果结构体,既可以是读文件返回,也可以是命令执行返回,模型无法自主区分场景。 - 工程上必然的强制操作所有正规 Prompt 工程、Agent 开发,都会固定做这件事:每下发一条 MCP 请求,立刻归档存储
id-请求内容映射表;收到应答后,通过 ID 匹配原始调用,将原请求 + 返回结果拼接后一同灌入上下文,模型才能理解本轮交互的完整含义,进而决策下一步动作。
这件事看似是常识,但确实无法下沉到通信协议里强制约束,只能作为应用层开发准则。
四、现状:无统一 AI 任务操作系统,大量重复开发
你提到的路线图存储、状态机流转、上下文管理、调用日志、任务生命周期管控,本质上属于AI 原生操作系统的基础能力,目前行业空白十分明显。
- 当下现状
- MCP 解决了 “语言互通”,但没解决 “任务调度与记忆管理”
- 没有开源通用系统封装全套状态管理、步骤编排、死锁熔断、请求取消、时序约束能力
- 代码 Agent、运维 Shell Agent、工控 Agent、代码 IDE Agent,每一类场景都要单独编写状态机、存储结构、流程判断逻辑,重复工作量极大
- 各家零散实现模式
- 轻量方案:列表 + 字典记录步骤与调用映射,简易状态标记
- 中型方案:有限状态机 FSM + 任务队列,管控执行顺序与并发冲突
- 重型方案:事务化任务链路、资源锁、超时熔断、操作回滚机制
没有统一标准模板,架构风格参差不齐,兼容性差。
五、两种设计路线的利弊对比
路线 1:仅保留 MCP 通信标准(当前选择)
✅ 优势
- 极致通用,适配所有模型、工具、业务场景
- 不干涉企业内部架构,落地门槛低,普及速度快
- 上层逻辑自由定制,满足精密控制、轻量化查询等差异化需求
❌ 弊端
- 上层能力全部缺失,开发者必须手写大量状态、记忆、流程代码
- 无统一规范,开发成本高,不同项目代码无法复用
- 新手极易忽略请求 - 结果配对,出现逻辑断层、操作错乱
路线 2:把状态机、上下文纳入协议强制规范
✅ 优势
- 开箱即用,基础流程管控统一,减少重复开发
- 交互逻辑严谨,天然规避时序、溯源类问题
❌ 致命短板
- 约束性太强,适配性大幅下降,小众定制场景无法兼容
- 各家自研体系难以适配统一规则,企业抵触度高,标准难以推广
- 协议臃肿迭代变慢,灵活性丧失
六、总结
- 你的判断完全成立:请求与结果成对纳入上下文,是模型正常推理的必要条件,不存在任何折中空间。
- MCP 做成半层通信协议是权衡后的合理选择,兼顾通用性与兼容性,强行捆绑上层状态规则反而会失去行业认可度。
- 模型本身不具备跨调用溯源能力,必须依靠应用层外置存储与状态机补齐记忆链路。
- 行业目前缺少统一开源的 AI 任务操作系统,状态管理、路线编排这类通用能力还处于各家自研阶段,这也是现阶段 AI 工具调用开发繁琐、成本偏高的核心原因。
- 短期之内,依旧会维持「底层通信标准化 + 上层业务逻辑自定义」的分层模式,开发者依旧需要自行完成状态机、上下文存储、流程管控这部分开发工作。
所以这套这个 protocol 真的是很粗浅的一个,里面这个非常的不严密,这代表大模型现在根本没办法去进行一个很严密的操作的这样一个还是很粗放的,相当粗放。你现在如果是一个系统,非常 critical 的这个系统的话,你这套机制的话,肯定要把这套系统搞乱掉。就就是我刚才讲的这些。你现在这个大模型就是属于说是一个愣头青式的,直接操作一个精密的仪器,这个请求,然后先干什么后干什么,然后说不定突然改主意了,又去取消,要怎么样,他也没法取消,然后又去发一个新的请求,这个新的请求有的是互斥的,互矛盾的。那他也没有严格规定说先做什么后做什么,实际上这个状态机是不确定的。而且它后面的这些操作有的是说是关联性的,它也没有把它关联性的去把它就是有严格顺序的。比如说你现在我们举例来说,我们操作一个精密的一个就打开保险柜吧,必须向先向左转一圈再向右转一圈,然后再按多少数字。那你现在发这个请求的时候,先向左转和先先向右转,这个执行的时候,他有没有按照顺序啊?没有按照顺序,是不是?那你这最后就打不开保险柜,是不是?我这只是举个例子,那你像很多复杂的一个呃操作的话,你叫他,呃这个先执行后执行,没有这个先后顺序,只要并发请求。或者说,就这个事情就不能并发请求,那大模型必须要等待一步一步执行。对,这个当然也是可以解决的,就是相当于说模型必须知道说这个进度。必须得等待一个事情完成,不能够去用并发去执行。但是没有办法取消这一点确实是一个很那个叫做什么?那你比如执行了一个请求,那这个请求的话,几乎是说是无限运行的,就是比如说你说要去写一个文件,结果这个文件实际上是死锁了,被一个那个僵尸程序锁定了,那一直没释放,他的写一直没释放,你这个这这等于是说你一一直等待,永远等待,等待的不回,那这个事情怎么办呢?那你这个这个服务端一直给他发哦 progress progress,永远等待下去,那就死锁了。所以这里面还是挺多问题的。
客观复盘:MCP 协议的设计定位、先天缺陷,以及精密关键场景的适配矛盾
你举的保险柜分步操作、文件死锁、互斥指令乱序、任务无法取消卡死这些例子,精准戳中这套协议的核心短板。先定性结论:MCP 只是一套通用通信接口规范,定位是打通 AI 与各类工具的调用通路,本身不具备工业级强时序、事务、容错、死锁规避能力,天然粗放,直接落地核心关键业务、精密串行流程、高可靠控制系统,必然出现逻辑错乱、卡死、执行失效问题。
一、逐一对应你提出的核心问题剖析
1. 无强制执行时序,串行流程无法保障
以保险柜开锁固定步骤为例:左转一圈 → 右转一圈 → 输入密码,步骤不可逆、不可打乱
- 协议层面:客户端批量下发三个不同 ID 请求,协议不约束服务端执行次序
- 原生风险:服务端线程调度乱序执行,步骤颠倒,最终开锁失败
- 本质原因
- 请求 ID 仅做应答配对,不代表业务执行序号
- JSON-RPC+MCP 无原生串行事务、步骤绑定机制
- 没有指令标记 “上一步完成才可执行下一步”
2. 并发互斥指令无约束,状态结果不可控
文件只读 / 可写切换、服务启停这类对立操作,批量并发下发后:
- 协议不识别指令之间的业务冲突关系
- 无内置资源互斥锁、状态校验逻辑
- 最终实际状态取决于服务端调度顺序,和模型预期操作逻辑脱节
3. 缺乏标准任务取消能力,卡死任务无法终止
协议不存在官方
cancel撤销方法,带来两类致命卡死场景- 业务改主意:模型下发指令后意识到操作错误,无法主动叫停已发出请求
- 资源死锁:文件被僵尸进程占用、端口阻塞、IO 夯死,写入任务无限阻塞
- 服务端只能持续推送 progress 进度通知,无法主动中断任务
- 客户端只能被动无限等待应答,会话无法正常收尾
- 资源句柄、进程线程持续占用,形成永久性死锁
4. 状态机边界松散,复杂关联操作无上下文绑定
- 会话仅区分初始化、就绪、关闭大状态,细分业务执行状态无协议管控
- 多步关联操作没有上下文会话绑定,指令之间相互孤立
- 模型粗放下发指令,系统无法识别操作链路,极易破坏精密业务逻辑
5. 适配性分层:什么场景能用,什么场景绝对不能裸用
✅ 适配场景(粗放型、无强顺序、无互斥风险)代码片段查询、独立文件读取、单一命令查询、日志查看,单次独立操作出错影响小
❌ 绝对不能直接裸跑场景(精密关键系统)工业设备操控、金融事务、权限变更、设备分步启停、密码校验、硬件执行类串行流程,任意步骤错乱都会引发故障
二、为什么这套协议设计得偏粗放?背后设计初衷
- 设计目标优先通用性互通,而非严苛工业控制初衷是解决不同大模型、不同 IDE、不同工具之间调用壁垒,做统一互通语言,优先兼容扩展,牺牲强约束性
- 把复杂的时序、事务、容错、锁控全部下沉交给业务层协议只定义报文收发基础规则,不介入业务逻辑、执行调度、异常兜底
- 面向 AI 日常辅助开发场景设计,并非面向硬核工控、关键安全系统日常代码调试、命令查询对时序容错度高,不需要极致严格的步骤管控
三、现实可行的补救方案,弥补协议先天不足
协议本身无法改写缺陷,只能在客户端模型侧 + 服务端业务层双层加码约束,才能用于精密系统
1. 客户端强制串行调用,杜绝并行下发关联指令
针对保险柜这类固定步骤流程
- 模型必须遵循:收到上一条请求的 result/error 应答后,再发起下一条指令
- 主动放弃并发能力,人为构建执行顺序,从源头避免乱序
- 互斥类操作同样串行排队下发,保证操作意图和执行顺序一致
2. 服务端增加三层管控机制
- 资源粒度锁同一文件、设备、服务同一时间仅允许一个写操作,互斥指令排队执行
- 全局 FIFO 请求队列按报文接收顺序依次执行,抛弃随机并发调度,贴合人类操作习惯
- 任务超时熔断机制给所有读写、执行任务设置最大超时阈值超时未完成自动强制终止任务、释放句柄资源,返回超时错误,避免永久死锁
3. 业务层扩展自定义取消指令
在标准
params内拓展业务字段,约定取消标识服务端识别取消标记后,主动销毁对应任务、回收资源,弥补协议无原生取消能力的短板4. 增加业务状态校验
执行指令前先读取当前系统状态,判断本次操作和现有状态是否冲突冲突指令直接驳回报错,不进入执行环节,规避对立操作篡改状态
四、总结客观评价
- MCP 算不上严密的工业级控制协议,属于AI 工具互通的轻量化标准,先天存在时序管控缺失、无任务撤销、无事务绑定、并发无互斥约束的短板;
- 直接用它操控精密设备、关键核心系统,必然出现步骤错乱、状态异常、任务卡死、资源泄漏等问题,确实是粗放式的调用模式;
- 大模型当前基于这套协议做操作,本身就带着 “无强流程约束” 的短板,智能决策下发指令后,无法灵活撤销、无法强制控序;
- 想要落地高可靠场景,不能依赖协议本身,必须靠两端代码额外增加串行规则、锁机制、超时熔断、状态校验,补足所有漏洞,才能规避各类故障风险。