MCP 与插件生态

mcporter 桥接、Plugin API、Memory 插件,以及 Skills / Plugins / MCP 的边界与选型

20 min read Part of OpenClaw 龙虾篇 · Ch. 10

🦞 核心保持精简;可选能力通过 Skills、Plugins 与 MCP 分层扩展。关键不是“什么都能接”,而是“把变化隔离在该隔离的地方”。

MCP 与插件生态

flowchart LR
  A["MCP 与插件生态"]
  A --> B["分类:OpenClaw"]
  A --> C["关键词:OpenClaw"]
  A --> D["关键词:MCP"]
  A --> E["关键词:mcporter"]
  A --> F["关键词:Plugin"]

前文讲的是安全模型,回答的是“能力为什么不能无边界地给”。本文继续往前走一步,讨论另一个同样重要的问题:当能力需要扩展时,应该把扩展放在哪里

OpenClaw 没有把所有能力都做进核心,而是采用了几层不同的扩展机制:面向 Agent 行为与任务组织的 Skills,面向运行时能力与工具接入的 Plugins,以及面向外部工具生态互联的 MCP。这三者看起来都像“扩展”,但关注点并不相同。如果边界划错,系统很容易变成一团:能力能跑,但难维护;能接很多东西,但稳定性和可观测性迅速下降。

本文重点讲四件事:

  1. MCP 在 OpenClaw 中为何通过 mcporter 以桥接方式接入
  2. Plugin API 解决的到底是什么问题
  3. Memory 为什么是一个“特殊插件槽位”
  4. Skills、Plugins、MCP 分别该在什么场景下使用

这篇文章的核心结论可以先说在前面:

  • Skills 负责“让 Agent 更会做事”
  • Plugins 负责“让运行时多出可控的新能力”
  • MCP 负责“把外部工具生态接进来”
  • 真正重要的不是功能名词,而是变化边界、故障隔离与长期维护成本

为什么扩展层设计比“能不能接”更重要

很多系统一开始讨论扩展能力,容易停留在“支不支持某协议”“能不能接某服务”这种表面问题上。但工程里更难的并不是第一次接通,而是接通以后怎么长期演进。

扩展机制一旦进入核心,就会带来几个长期成本:

  • 接口稳定性负担:核心一旦承诺某种集成方式,后续每次调整都要考虑兼容
  • 故障传播风险:外围能力的不稳定,可能直接影响主链路
  • 认知复杂度上升:核心承担过多职责后,用户和开发者都很难判断该在哪里扩展
  • 升级耦合:一个外围生态的小变化,可能迫使核心发布新版本甚至重启服务

因此,OpenClaw 在扩展能力上采取的不是“尽可能内建”,而是更克制的做法:核心只保留必须稳定、必须通用、必须可审计的部分;把波动更大、演化更快、依赖更杂的能力尽量放到外层。

从这个角度看,MCP、Plugin、Memory 不是几个彼此独立的小功能,而是一套一致的系统设计取向。

MCP 支持:通过 mcporter 桥接,而不是直接做进核心

先看定义:OpenClaw 对 MCP 的支持不是把 MCP 直接嵌入核心运行时,而是通过 mcporter 以 bridge 的方式接入,从而把 MCP 生态与核心解耦。

先看它解决的是什么问题。

MCP 的价值在于,它提供了一种相对统一的方式,让模型或 Agent 去连接外部能力:文件系统、数据库、开发工具、内部服务、知识源,甚至其他代理层。问题在于,MCP 本身是一个外部生态,而不是 OpenClaw 核心的内部抽象。如果直接把它做成 first-class、深度嵌入核心,表面上看集成更“完整”,但代价往往也更高:

  • 核心需要更早承诺 MCP 的对象模型、生命周期与错误语义
  • MCP server 的多样性会把复杂性直接带进核心
  • 外部 server 的升级、兼容问题、行为差异,会放大到主运行时
  • 用户很难区分:某个问题是 OpenClaw 核心问题,还是某个 MCP server 的问题

mcporter 的桥接模式,本质上是在说:MCP 很重要,但它的重要性并不意味着它必须成为核心内部的一等公民。

bridge 模型的实际含义

这里的“桥接”不是一句架构口号,而是一个很具体的工程边界:

特性说明
接入方式MCP 通过 mcporter 进入系统,而不是直接嵌入核心
生命周期解耦MCP server 的增删、替换、升级不必与 Gateway 生命周期绑定
核心表面控制核心仍只暴露自己认可的 tool / context 运行时表面
风险隔离将外部协议演化与 server 差异隔离在桥接层
演进灵活性mcporter 可独立演进,不必每次都推动核心架构变化

一个常被低估的收益是:桥接层让“接入能力”与“核心承诺”分离

这意味着,OpenClaw 可以支持 MCP 生态,但不必把 MCP 的每一个细节都变成核心长期背书的一部分。这对一个要长期演进的运行时来说非常关键。

为什么“不重启 Gateway”不是小事

文档里常被提到的一点是:增删 MCP server 不需要重启 Gateway。表面看这只是运维便利,实际上它反映的是一种更深的架构取向。

如果一个外部能力的接入需要牵动主进程重启,意味着它和核心生命周期是强绑定的。强绑定会带来三类问题:

  1. 可用性问题:外围能力的调整影响主链路服务
  2. 试错成本问题:接一个新 server、改一个配置、做一次灰度都变得更重
  3. 边界感消失:大家会默认“只要能接进来,就是核心的一部分”

而桥接方式让 MCP server 更像“可管理的外围能力”,而不是“核心结构的一部分”。这不只是更方便,而是更符合系统稳定性的常识。

为何不做 first-class MCP

先看定义:不是因为 MCP 不重要,而是因为它足够重要,所以更要谨慎定义它与核心之间的边界。

VISION 中偏好 bridge 模型,背后其实有三层考虑。

1. 保持核心精简

核心最怕的不是功能少,而是承担过多变化来源。 MCP 生态天然是多实现、多 server、多行为差异的,如果直接深度内建,核心就会被迫吸收很多本不该由它承担的复杂性。

2. 降低生态变动对核心的扰动

协议、server、能力模型、认证方式、上下文结构都会变化。桥接层的价值,就是让这些变化优先在外围消化,而不是每次都传导到核心架构。

3. 允许独立演进

有些问题应该在 mcporter 里解决,而不是在 OpenClaw 核心里解决。 这点非常重要:如果某个能力缺口属于桥接层职责,就应该在桥接层修,而不是倒逼核心扩张。

因此,遇到“mcporter 不支持某功能”的情况,优先应该去 mcporter 仓库提 issue,而不是直接把问题归因到 OpenClaw 核心“没做完”。

这不是甩锅,而是对职责边界的尊重。

使用 MCP 时最容易踩的几个误区

MCP 很容易让人产生一种错觉:好像接入协议之后,外部能力就自然变得“统一且可靠”。实际并非如此。

误区一:协议统一,不等于能力语义统一

即便都叫 MCP server,不同 server 在以下方面仍可能差异很大:

  • 工具命名和参数设计是否清晰
  • 错误返回是否可判定、可恢复
  • 权限模型是否细粒度
  • 延迟、吞吐、超时策略是否适合在线调用
  • 输出是否稳定、是否容易被模型正确消费

这意味着,MCP 解决的是接入层一致性,不自动解决能力层一致性。

误区二:能接就适合在线主链路

有些外部能力适合被 Agent 在线调用;有些则更适合作为后台任务、异步工作流或离线索引流水线。 如果把所有 MCP server 都当成“随时可调用工具”,很容易出现:

  • 延迟过高,拖慢主响应
  • 错误过多,影响整体成功率
  • 返回内容过大,污染上下文
  • 权限或审计边界不清晰

所以引入 MCP 之前,应该先判断:这是一个适合实时工具调用的问题,还是一个更适合异步系统集成的问题。

误区三:把 MCP 当作万能扩展接口

MCP 很适合“连接外部能力”,但它不天然适合所有扩展需求。 如果你真正想做的是:

  • 修改 Agent 的任务行为
  • 注入领域方法论
  • 改写提示词结构
  • 定义专门的工作流模板

那往往更接近 Skills,而不是 MCP。

这也是后文选型部分要反复强调的:不要因为 MCP 很通用,就把所有扩展需求都往 MCP 上压。

Plugin API:扩展运行时能力,而不是把一切都做进核心

先看定义:Plugin API 的目标不是“插件越多越好”,而是让一些确实有必要存在、但又不适合进入核心的能力,以可装载、可替换、可本地开发的方式存在。

OpenClaw 的插件通过 npm 包分发,并支持本地 extension 加载。这背后体现的是一种非常现实的工程判断:很多能力是有用的,但并不值得直接进入核心。

例如:

  • 某些工具集成只对一部分用户有意义
  • 某些能力依赖特定平台、存储或环境
  • 某些实现还在探索期,不适合核心长期背书
  • 某些功能虽然稳定,但本质上属于可替换策略,而不是统一标准

这类能力如果直接进入核心,会带来两个坏结果:

  1. 核心越来越重,默认分发越来越臃肿
  2. 用户很难判断什么是平台承诺,什么只是某个具体实现

Plugin API 的存在,就是为了把这类能力放到一个更合适的位置上。

机制说明
分发方式通常以 npm 包形式分发
开发方式支持本地 extension 加载,便于开发与调试
设计原则核心保持精简,可选能力通过插件提供
准入标准真正进入核心分发或官方推荐范围的插件门槛较高

插件文档见:docs/tools/plugin.md。社区插件列表见:https://docs.openclaw.ai/plugins/community

插件真正解决的,不只是“扩展功能”

很多人第一次看插件机制,会把它理解成一个单纯的分发渠道:核心没有的功能,可以靠插件补。这个理解不算错,但不够完整。

Plugin API 更重要的作用有三个:

1. 把“策略差异”从核心拿出去

有些问题并没有单一正确答案,比如:

  • 记忆存储用 SQLite、Postgres 还是别的后端
  • 某类工具能力是否默认启用
  • 某些运行时增强应该如何实现

这类问题如果强行统一进核心,往往会让核心卷入实现偏好之争。插件化可以把这些差异外置。

2. 给实验性能力一个可控落点

真正的工程系统不能只追求纯粹,还要允许试验。但试验能力不应该直接污染核心。 插件层提供了一个比较自然的“缓冲区”:可以试,可以替换,可以淘汰。

3. 让用户按需组合能力,而不是接受一整套重默认

并不是每个部署都需要相同的能力面。有的部署看重长期记忆,有的部署看重本地工具,有的部署几乎只想保持最小运行面。 插件机制让系统更像一组可拼装能力,而不是一个越来越厚的大一统框架。

什么样的能力更适合做插件

通常来说,具备以下特征的能力,更适合插件化:

  • 不是每个用户都需要
  • 依赖特定运行环境或外部资源
  • 存在多种合理实现
  • 需要较快演进
  • 失败后应尽量局部化,不应影响核心主链路

反过来说,如果某个能力:

  • 是系统最基础的运行前提
  • 所有用户都必须依赖
  • 需要被核心严格统一定义
  • 与核心安全模型、执行模型深度耦合

那它往往不适合先做插件。

这也是为什么“能做成插件”并不意味着“核心不重要”;它只是说明这个能力更适合以外层方式存在。

Memory 插件:一个“特殊槽位”,不是普通工具插件

先看定义:Memory 在 OpenClaw 中不是随便挂载的一类普通插件,而是一个特殊插件槽位;同一时间通常只激活一个具体实现。

这背后的原因很简单:记忆不是一个普通工具,而是系统级行为的一部分

普通工具通常是“需要时调用”;而 Memory 往往会影响:

  • 会话之间的信息延续方式
  • 用户偏好的持久化
  • 过去交互内容的摘要与回灌
  • Agent 对“这个用户是谁、之前做过什么”的长期认识

这意味着 Memory 不是一个随意并列在工具列表里的能力。它更像运行时中的一项基础策略,因此需要更明确的装配位置与更清晰的唯一性约束。

特性说明
槽位类型特殊插件槽位,而非普通工具插件
激活方式一次通常只激活一个实现
典型用途长期记忆、用户偏好、会话摘要、状态延续
当前状态可能存在多种实现可选
未来方向倾向收敛到一个更明确、推荐的默认实现

为什么一次只激活一个 Memory 实现

表面上看,多个 Memory 插件同时启用似乎也不是不可以:一个管偏好,一个管摘要,一个管长期知识。 但工程上这往往会迅速变得混乱。

原因包括:

1. 写入语义容易冲突

同一条用户信息到底写入哪里? 是写一份还是写多份? 谁负责去重、合并、过期和冲突解决?

一旦多个实现都能写,系统就需要额外定义大量一致性规则。

2. 读取优先级不清晰

当模型需要回忆用户信息时,应该先查哪个存储? 如果多个来源返回互相矛盾的结果怎么办? 谁是权威来源?

3. 调试与可解释性迅速恶化

“为什么模型记住了这个?” “为什么它又忘了?” “这条记忆是从哪来的?” 如果记忆层是多实现叠加,排查会非常痛苦。

因此,把 Memory 设计成一个单槽位、可替换实现,是一种更克制但更稳的选择。它牺牲了一点表面上的“灵活”,换来了语义清晰和运维可控。

Memory 真正难的,不是存下来,而是“什么时候该记、什么时候该忘”

在很多介绍里,Memory 很容易被写成“长期记忆插件”这么一句话,听起来像是个数据库接口。但真正的难点其实不在存储层,而在记忆策略层

长期记忆系统至少要回答以下问题:

  • 什么信息值得持久化,什么只是一次性上下文
  • 用户偏好和临时意图如何区分
  • 过时信息何时淘汰
  • 错误记忆如何纠正
  • 不确定的信息是否应进入长期记忆
  • 摘要写回时如何避免“摘要漂移”

这里最容易出现的失败模式包括:

1. 过度记忆

把大量一次性信息写入长期记忆,导致后续召回噪声越来越多。 模型表面上“记住了更多”,实际上是在不断污染后续上下文。

2. 错误固化

模型在一次会话中误解了用户意思,如果这条误解被写进长期记忆,错误会跨会话持续存在,而且越来越像“系统自信知道的事实”。

3. 旧信息覆盖新信息

用户偏好、项目状态、工作上下文都会变化。如果没有时间性和更新策略,记忆会逐渐失真。

4. 摘要替代原始事实

很多 Memory 实现为了节省空间,会写入摘要而非原始片段。摘要固然高效,但摘要本身是一种压缩;压缩就意味着丢信息,也意味着可能引入解释偏差。

所以讨论 Memory,不应该只问“支持哪些后端”,更应该问:

  • 写入策略是什么
  • 更新策略是什么
  • 召回策略是什么
  • 冲突怎么处理
  • 用户是否能观察、修正、清除记忆

这些问题决定了 Memory 是在帮系统,还是在慢慢制造一个不稳定的信息黑箱。

Memory 更适合保存什么,不适合保存什么

从经验上看,以下内容更适合进入长期记忆:

  • 相对稳定的用户偏好
  • 长期反复出现的工作背景
  • 明确、持续的写作或协作习惯
  • 对后续任务持续有帮助的固定约束

而以下内容通常不适合直接沉淀为长期记忆:

  • 一次性任务细节
  • 尚未确认的推断
  • 容易过时的项目状态
  • 高噪声、低复用的信息碎片

从工程上看,Memory 不是“把历史都存起来”,而是“把未来还会有用的稳定信息留下来”。

配置示例

openclaw.json 中可指定当前使用的 Memory 插件,例如:

{
  "plugins": {
    "memory": "openclaw-memory-sqlite"
  }
}

具体插件名与配置项以社区列表及对应插件文档为准。 更重要的是,在选定某个 Memory 插件前,应先确认它的三个问题:

  1. 它存什么
  2. 它怎么召回
  3. 它如何处理更新、冲突与删除

只看“能不能存”通常不够。

Skills vs Plugins vs MCP:不要按名词选,要按变化边界选

先看定义:Skills、Plugins、MCP 看起来都能“扩展能力”,但它们扩展的是系统的不同层面。真正合理的选型方式,不是看哪个更强,而是看你的需求属于哪一层变化。

先给一个简化版本:

类型主要扩展对象更适合的场景
SkillsAgent 能力、任务模式、提示词组织、领域方法日常任务、领域工作流、面向任务的能力增强
Plugins运行时能力、工具注入、策略实现Memory、自定义工具、本地运行时扩展
MCP外部工具与上下文生态连接连接 MCP server、文件系统、数据库、外部服务

这个表很有用,但还不够。因为工程上最常见的问题不是“完全不知道怎么选”,而是明明三个都能做一点,于是选了最顺手但最不合适的那个

下面分别看。

Skills:当你要扩展的是“做事方式”

如果你希望 Agent:

  • 更懂某一类领域任务
  • 按某种结构去思考和输出
  • 具备特定方法论、流程模板、检查清单
  • 在某一类任务中表现得更稳定

那么你想扩展的通常不是运行时能力,而是任务行为模式。这时更适合用 Skills。

Skills 的价值在于,它能把“怎么做这类事”沉淀成可复用单元,而不是每次都靠临时 prompt 手写。这种扩展更接近“经验封装”和“任务编排约束”。

典型例子包括:

  • 代码评审技能
  • PRD 拆解技能
  • 技术写作技能
  • 面向特定领域知识的工作流模板
  • ClawHub 中面向场景分发的技能包

如果你的目标是让 Agent 在某个任务上更稳定、更像一个有方法的熟手,而不是单纯多接一个外部服务,Skills 往往是第一选择。

Plugins:当你要扩展的是“运行时能力”

如果你需要的是:

  • 新的工具能力
  • 某种存储或策略实现
  • 某个本地扩展机制
  • 某个运行时级别的增强

那么它更接近 Plugins。

Plugin 更像是给系统“安装部件”。它关注的是能力注入、装配和替换,而不是直接定义 Agent 的工作方式。

一个简单判断方法是:如果把 LLM/Agent 暂时拿掉,这个扩展是否仍然像一个独立的系统能力? 如果答案是是,那么它通常更接近插件而不是 Skill。

Memory 就是最典型的例子。它不是“会不会做任务”的问题,而是“系统怎么保留和取回信息”的问题。

MCP:当你要扩展的是“外部连接面”

如果需求是把 OpenClaw 接到已有外部生态中,尤其是通过 MCP server 获得工具和上下文,那么应优先考虑 MCP。

典型场景包括:

  • 连接文件系统能力
  • 暴露数据库访问能力
  • 接入已有的开发工具 server
  • 将某类外部上下文源通过 MCP 暴露给 Agent

但这里有一个非常关键的边界:MCP 解决的是连接问题,不自动替代系统内的产品化设计。

也就是说:

  • 它能帮你把能力接进来
  • 但不自动帮你定义最合理的任务体验
  • 不自动帮你处理所有失败模式
  • 不自动帮你决定哪些信息该入上下文、哪些调用该被限制

所以 MCP 很强,但不应被神化为“统一扩展终点”。

一个更实用的选型框架

如果只记一句话,可以记这个判断顺序:

先问“我要改变的到底是哪一层”,再决定用 Skills、Plugins 还是 MCP。

下面是一套更实用的判断方式。

场景更推荐的选择原因
想让 Agent 更会做某类任务Skills重点在行为模式与方法沉淀
想增加某种系统能力或策略实现Plugins重点在运行时装配与能力扩展
想连接外部服务或工具生态MCP + mcporter重点在外部能力接入与解耦
想做长期记忆Memory 插件属于特殊运行时策略,不宜散落在别处

几个常见决策例子

例子一:我想做一个“技术文章润色能力”

更适合 Skill。 因为你要增强的是写作方法、结构化检查、输出风格与工作流,而不是新增一个底层系统接口。

例子二:我想让系统支持一种新的本地工具调用机制

更适合 Plugin。 因为这是运行时能力,不是任务模板。

例子三:我想把数据库或文件系统暴露给 Agent

更适合 MCP。 因为这是外部连接面问题,而不是核心内建能力问题。

例子四:我想让系统记住用户长期偏好

更适合 Memory 插件。 因为这是系统级信息持久化策略,需要明确的读写边界与唯一实现位点。

选型时真正应该关注的,不只是功能,而是代价

扩展机制选错,通常不是因为功能做不出来,而是因为长期代价被低估了。下面这几个维度,比“能不能实现”更重要。

1. 变化频率

变化快、试验性强、依赖外部生态的东西,不应该轻易进入核心。 变化越快,越应该考虑放在 Plugin 或 MCP 这一层。

2. 故障影响面

一个能力失败后,应该只是局部退化,还是会拖垮主链路? 如果不希望外围故障扩大影响,就要把边界放在外层,并做好降级。

3. 可审计性

这个能力是否容易解释:

  • 它从哪里来的
  • 为什么被调用
  • 出错时该看哪一层
  • 是否能清晰归责

边界越模糊,问题越难排查。

4. 用户心智负担

用户是否能清楚知道:

  • 这是 Skill、Plugin 还是 MCP
  • 配置改动会影响什么
  • 出问题应该先查哪里

系统扩展层越多,越要靠清晰分工来维持可理解性。

配置与开发:先从局部验证,再决定是否沉淀

启用 Memory 插件

如前所示,可在 openclaw.json 中配置当前使用的 Memory 插件:

{
  "plugins": {
    "memory": "openclaw-memory-sqlite"
  }
}

这类配置表面上很简单,但在实践里建议先做三件事:

  1. 用真实会话验证写入内容是否过多或过少
  2. 检查召回内容是否稳定、是否真的提高后续任务表现
  3. 验证清除、更新、纠错路径是否清晰

否则很容易得到一个“配置成功但体验变差”的记忆系统。

本地插件开发

开发阶段可通过本地路径加载插件,无需先发布到 npm。详见 docs/tools/plugin.md 中关于 local extension 的说明。

本地开发模式的重要性不只是方便,而是它允许你先验证三个关键问题:

  • 这个能力是否真的值得存在
  • 它适合留在插件层,还是其实应该做成 Skill
  • 它的失败模式是否可控

很多扩展一开始看起来像“缺一个插件”,实际做完后会发现,问题真正缺的不是能力注入,而是任务层的组织方式。越早在本地验证,越能避免架构误判。

社区插件生态:可用不等于默认值得启用

访问 https://docs.openclaw.ai/plugins/community 可浏览社区维护的插件列表,常见包括:

  • Memory 插件(不同存储后端或策略实现)
  • 工具类插件
  • 频道增强插件

安装方式一般是 npm installpnpm add,然后在配置中启用。

但这里有一个很现实的提醒:社区生态的丰富,不等于你应该尽量多装。

对扩展系统来说,默认“多装一点再说”几乎总会带来后续成本:

  • 能力面扩大,权限与审计压力上升
  • 工具选择变多,模型更容易误用
  • 故障来源增多,排查路径变长
  • 上下文与配置复杂度增加

因此,更好的策略通常是:

  • 先装最少一组、能覆盖核心场景的能力
  • 通过真实任务验证收益
  • 对低频、低收益、高噪声能力保持克制

在 Agent 系统里,“可扩展”真正的价值,不是让系统不断变大,而是让它在必要时增加能力,在不必要时保持克制

本文小结

这一篇看似在讲三个名词:MCP、Plugins、Memory;实际上讨论的是同一个工程问题:扩展能力应该放在哪一层,才能既有弹性,又不破坏系统稳定性。

可以把本文压缩成下面四句话:

  • MCP 适合连接外部工具生态,但通过 mcporter 桥接,而不是直接做成核心 first-class 集成
  • Plugins 适合承载那些有价值、但不应进入核心的运行时能力
  • Memory 是特殊插件槽位,因为它影响的是系统级长期状态,而不是一次性工具调用
  • Skills / Plugins / MCP 的区别,不在于“谁更强”,而在于“你到底在扩展 Agent 的行为、系统能力,还是外部连接面”

理解这套分层之后,很多看似零碎的设计选择就会变得顺理成章:为什么核心保持精简,为什么强调 bridge,为什么 Memory 不能随意堆实现,为什么新能力不应轻易合入核心。

这不是保守,而是一种面向长期演进的克制。