基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-11-13 11:32

四款 MCP 服务被报告存在更新丢失

dev.to · AI#MCP#并发控制#数据一致性
Editor brief · 编辑速览

一份商业审计机构发布的报告称,GitHub、Grafana 与 PostHog 的 MCP 服务出现并发写入覆盖,且双方均收到成功响应。Kubernetes MCP 案例则涉及缺少 resourceVersion 的对象回写,将其他写入者的修改还原。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

两个 AI agent 同时修改同一条 GitHub issue 的不同字段,都收到成功回复,最后却有一处修改消失。作者通过 GitHub 官方 MCP server 做了 30 组并发测试,19 组出现这种情况;直接调用 GitHub 的字段更新 API,28 组没有丢失。

这组审计想提醒开发者:工具返回成功,不代表并发修改被完整保留。GitHub、Grafana、PostHog 和 Kubernetes 都测出了问题,但原因不同,有的是 MCP 扩大了写入范围,有的是后端 API 存在竞争窗口,还有的是主动选择了强制覆盖。

只改一个字段,为什么会覆盖别人的修改

丢失更新(lost update)常见于「先读、再改、最后整份写回」。

假设两个 agent 读到同一份旧数据,一个改标题,一个改描述。如果各自提交时都附带其他字段的旧值,后提交的请求就可能把前一个人的修改覆盖掉。两个请求都执行成功,最终数据却没有同时包含两人的改动。

GitHub 的 MCP 工具就是这种情况:设置一个 issue 字段时,先读取所有字段,合并修改,再整组写回,而且没有版本检查。直接调用 GitHub 的字段更新 API 没有复现丢失,说明这次风险由 MCP 层引入。

用户要求修改的范围,应该尽量等于工具实际写入的范围。

Grafana 多了一层问题。它的 MCP patch 模式看起来只是局部修改,实际仍然是读取整个 dashboard、应用补丁、保存整份 dashboard,并强制开启 overwrite,导致版本检查不执行。

允许版本检查运行时,Grafana 在 10 次测试中全部拒绝了过期保存。但旧版保存端点仍有竞争窗口:两次保存恰好同时到达,即使开启检查,也可能双双通过。Grafana 13 的 Kubernetes 风格 API 则在 30 组同时保存中,每组都拒绝了其中一次。

这里要区分「能发现旧版本」和「检查、写入之间不会被插队」。前者通过了,不代表后者也成立。

有些问题要修 API,有些要重新考虑强制覆盖

PostHog 的结果与 GitHub 相反:直接调用产品 API,丢失更新的频率与通过 MCP 调用差不多。MCP 没有制造额外损失,也没有消除它。

修复位置因此应该在 API。把 MCP 工具换个名字、补几句提示词,都不能修掉后端的并发缺陷。作者称,PostHog 的小范围修复在次日上午完成审查并合并,但输入没有提供修复后的完整对照数据。

Kubernetes 的情况又不同。开源 containers/kubernetes-mcp-server 的 resources_create_or_update 使用 server-side apply,并设置 force: true。这是上游在 issue 799 中主动选择的行为,作者将其作为已测量的设计取舍,而非新提交的缺陷。

原本有两道保护:不强制 apply 时,其他 manager 拥有的字段会受到所有权冲突检查;请求体携带 resourceVersion 时,过期写入会失败。force: true 取消了第一道,第二道则依赖客户端保留读取时的版本。

审计中的两个原生 agent 会话都没有发送 resourceVersion。并发编辑任务里,另一个写入者在 agent 读取 ConfigMap 约半秒后,把 MAX_CONNECTIONS 从 100 改成 200;约四秒后,agent 用旧副本强制 apply,又把它改回 100,还告诉用户其他键没有变化。

同一服务器的 resources_scale 提供了对照:它会发送读到的 resourceVersion。注入冲突时,3 次全部返回错误且没有改动;真实竞争中,10 次全部暴露了冲突。

另一个问题 K8S-04 出在 resources_delete:请求没有 uid 或 resourceVersion 前置条件。对象在读取后被删除、重建,工具仍可能删掉这个新对象,10 次测试全部发生。原文也指出,kubectl 同样没有 uid 前置条件。

怎样验证自己的工具有没有丢失更新

作者的方法可以直接用于内部 MCP 验收:

选择一个只修改对象局部的工具,让两个独立服务器进程同时修改同一对象的不同部分,至少重复 10 次。随后重新读取对象,检查两处修改是否都在。如果两个调用都报告成功,但一处修改消失,就确认了一次丢失更新。

接着,把相同修改直接发给产品 API,重复测试。API 不丢、MCP 丢,优先检查工具的读写转换;两边都丢,则继续查后端。后端提供冲突信号时,工具应把它传出来。

判断写入是否可靠,要核对最终状态,不能只数成功响应。

不过,这些数字不能当成生产事故率。GitHub、Grafana 和 PostHog 每个测试单元只有 11 至 30 组,而且刻意同时释放请求。Kubernetes 多数测试每组 10 次,API 对照和注入 scale 冲突各 3 次,环境也仅覆盖单台机器、单个集群或测试账号。

四份审计都有真实 agent 任务,但丢失更新的计数来自脚本测试,不是真实会话的自然碰撞统计。四个项目也是按广泛使用、开放源码挑选,没有随机抽样。输入提到的汇总图表未提供具体内容或图片 URL,因此无法补出其他丢失比例。

复现材料也有边界。GitHub 实验仓库 isokron-ai/github-mcp-writepath-experiment 基于 v2.1.0,修复以独立提交提供;go test ./... 运行上游和新增测试,但并发测试程序依赖私有仓库,尚未公开。PostHog 实验仓库 isokron-ai/posthog-mcp-writepath-experiment 的测试程序在 harness/。Kubernetes 实验仓库 isokron-ai/kubernetes-mcp-writepath-experiment 提供固定测试程序,可用 for b in baseline fixed research; do harness/build/build.sh $b; done 构建三个二进制。Grafana 修复对应上游 pull request 1518。

我的判断

我赞同作者最关键的做法:用产品原生 API 做对照。否则,一句「MCP 会丢数据」容易把工具实现、后端缺陷和强制写入策略混成同一个问题,最后修错地方。

对前端和全栈团队,这也不陌生。表单拿着旧快照提交整个对象,或 Node 服务做读取、合并、写回,同样需要处理并发。MCP 值得额外检查,是因为多个 agent 可以同时操作同一份共享数据。

但这篇没有证明多 agent 在日常任务中究竟多容易碰撞,也没有比较串行队列、字段更新和版本控制的性能成本。根据这些结果调整具体写入路径有依据,直接认定所有 MCP 写工具都不可靠则超出了证据。

三个同时写入的案例里,丢失的修改可以重新写回,Grafana 还保留 dashboard 版本历史。麻烦在于系统没有告诉用户需要恢复。冲突报错会打断任务,静默覆盖却可能让后续任务继续使用错误状态。

作者经营销售 MCP 审计服务的 IsoKron,研究自费、使用 AI 辅助,也声明由本人在另一台机器复测。商业关系不自动推翻结果,但仍应结合公开方法和可复现程度判断,不能把作者的复核声明当成独立验证。

能拿来做什么

  • 给团队实际使用的 MCP 写工具补一轮并发验收,让两个独立进程修改不同字段,并在成功返回后核对最终数据。
  • 检查 Node 工具封装是否为了修改一个字段而回写整个对象;后端支持字段更新或版本条件时,把这些能力保留到工具调用中。
  • 使用 Kubernetes 写工具时,确认 agent 是否携带 resourceVersion,并明确 force: true 是否符合这次任务的覆盖意图。
  • 给 AI 编程任务保留冲突处理分支;遇到版本冲突后重新读取、核对差异,再决定如何重试,避免原样重放旧副本。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
GUI 智能体本地运行的架构取舍
下一篇
用编码记录自动整理工时与站会汇报

资讯速览

dev.to · AI · 2026-11-13 11:32

AI 评分 8.0 / 10

相关标签

#MCP#并发控制#数据一致性

继续阅读

  • 决策模型让分类任务告别文本解析
  • GUI 智能体本地运行的架构取舍
  • 用编码记录自动整理工时与站会汇报
  • 逐个核查 robots.txt 是否挡住 AI 爬虫
  • 用零依赖 Node.js 日志追踪智能体执行