Skip to content

本页是 OpenClaw 插件打包配置的完整参考,解决 package.json openclaw 字段(extensions/setupEntry/channel/install/compat/build/startup)、manifest 文件格式、setup-entry.ts 与完整入口分工、延迟加载(deferConfiguredChannelFullLoadUntilAfterListen)配置、config schema 定义(JSON Schema 或 Zod/TypeBox)、ChannelSetupWizard 向导编写以及 ClawHub 发布命令。先确认插件类型(渠道/Provider/工具),再对照表格填写元数据。setupEntry 只注册 gateway 监听前所需的最小集,完整入口处理重任务。

OpenClaw 插件打包配置:package.json、manifest、setup entry 完整指南

本页是插件 package.json 元数据、manifest(openclaw.plugin.json)、setup entry 和 config schema 的完整参考。如果已经了解流程,可作为快速查阅表;如果首次开发,先参阅 渠道插件开发Provider 插件开发

Package 元数据

package.json 需要 openclaw 字段,告诉插件系统你的插件提供了什么。根据插件类型选择下方模板:

渠道插件

json
{
  "name": "@myorg/openclaw-my-channel",
  "version": "1.0.0",
  "type": "module",
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "channel": {
      "id": "my-channel",
      "label": "My Channel",
      "blurb": "Short description of the channel."
    }
  }
}

Provider 插件 / ClawHub 发布基线

json
{
  "name": "@myorg/openclaw-my-plugin",
  "version": "1.0.0",
  "type": "module",
  "openclaw": {
    "extensions": ["./index.ts"],
    "compat": {
      "pluginApi": ">=2026.3.24-beta.2",
      "minGatewayVersion": "2026.3.24-beta.2"
    },
    "build": {
      "openclawVersion": "2026.3.24-beta.2",
      "pluginSdkVersion": "2026.3.24-beta.2"
    }
  }
}

注意: 发布到 ClawHub 时,compatbuild 字段必填。规范发布代码片段见 docs/snippets/plugin-publish/

openclaw 字段总览

字段类型说明
extensionsstring[]入口文件(相对于包根目录)
setupEntrystring轻量 setup-only 入口(可选)
channelobject渠道目录元数据,用于 setup/picker/quickstart/status 面
providersstring[]此插件注册的 Provider id
installobject安装提示:npmSpec, localPath, defaultChoice, minHostVersion, expectedIntegrity, allowInvalidConfigRecovery
startupobject启动行为标志

openclaw.channel 字段详解

openclaw.channel 是廉价元数据,仅用于渠道发现和 setup 面,不涉及 runtime 加载。

字段类型说明
idstring规范渠道 id
labelstring主要渠道标签
selectionLabelstring选择器/setup 标签(与 label 不同时使用)
detailLabelstring次要标签,用于更丰富的渠道目录和状态面
docsPathstringsetup 和选择链接的文档路径
docsLabelstring文档链接中使用的标签(与 channel id 不同时使用)
blurbstring简短引导/目录描述
ordernumber渠道目录中的排序顺序
aliasesstring[]渠道选择的额外别名
preferOverstring[]本渠道优先于这些低优先级插件/渠道 id
systemImagestring可选的图标/系统图片名称
selectionDocsPrefixstring选择面中文档链接前的前缀文本
selectionDocsOmitLabelboolean在选择面中直接显示文档路径而不是带标签的文档链接
selectionExtrasstring[]额外短字符串,附加在选择副本中
markdownCapableboolean标记渠道支持 markdown 出站格式化
exposureobject渠道在 setup/configured/docs 面的可见性控制
quickstartAllowFromboolean将渠道纳入标准 quickstart allowFrom 设置流程
forceAccountBindingboolean即使只有一个账号也要求显式账号绑定
preferSessionLookupForAnnounceTargetboolean解析通知目标时优先使用会话查找

完整示例:

json
{
  "openclaw": {
    "channel": {
      "id": "my-channel",
      "label": "My Channel",
      "selectionLabel": "My Channel (self-hosted)",
      "detailLabel": "My Channel Bot",
      "docsPath": "/channels/my-channel",
      "docsLabel": "my-channel",
      "blurb": "Webhook-based self-hosted chat integration.",
      "order": 80,
      "aliases": ["mc"],
      "preferOver": ["my-channel-legacy"],
      "selectionDocsPrefix": "Guide:",
      "selectionExtras": ["Markdown"],
      "markdownCapable": true,
      "exposure": {
        "configured": true,
        "setup": true,
        "docs": true
      },
      "quickstartAllowFrom": true
    }
  }
}

exposure 对象支持三个子字段:

  • configured:是否包含在已配置/状态列表面
  • setup:是否包含在交互式 setup/配置选择器
  • docs:是否在文档/导航面中公开

旧版别名 showConfiguredshowInSetup 仍受支持,建议优先使用 exposure

openclaw.install 字段详解

openclaw.install 属于包元数据,不是 manifest 元数据。

字段类型说明
clawhubSpecstring规范 ClawHub spec,用于安装/更新和引导按需安装流程
npmSpecstring规范 npm spec,用于安装/更新回退流程
localPathstring本地开发或内置安装路径
defaultChoice"clawhub" | "npm" | "local"多种安装源可用时的首选来源
minHostVersionstring最低支持的 OpenClaw 版本,格式 >=x.y.z>=x.y.z-prerelease
expectedIntegritystring预期 npm dist integrity 字符串(通常 sha512-...),用于固定安装
allowInvalidConfigRecoveryboolean允许内置插件重装流程从特定的过期配置故障中恢复

引导行为

交互式引导也使用 openclaw.install 实现按需安装面。如果插件在 runtime 加载前暴露 provider 认证选项或渠道 setup/目录元数据,引导流程可以显示这些选项,提示用户选择 ClawHub/npm/本地安装,安装或启用插件,然后继续所选流程。ClawHub 引导选项使用 clawhubSpec,优先可用;npm 选项需要注册表元数据中带有 npmSpec;精确版本和 expectedIntegrity 是可选的 npm 固定项。

minHostVersion 强制

设置了 minHostVersion 后,安装和非捆绑 manifest 注册加载都会强制检查。旧版 host 会跳过外部插件;无效版本字符串会被拒绝。内置源码插件假定与 host 代码同版本。

固定 npm 安装

json
{
  "openclaw": {
    "install": {
      "npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3",
      "expectedIntegrity": "sha512-REPLACE_WITH_NPM_DIST_INTEGRITY",
      "defaultChoice": "npm"
    }
  }
}

allowInvalidConfigRecovery 范围

allowInvalidConfigRecovery 不是配置损坏的通用绕过项。它只用于狭窄的内置插件恢复场景:重装/setup 可以修复已知的升级遗留问题(如丢失的内置插件路径或同一插件过时的 channels.<id> 条目)。如果配置因无关原因损坏,安装仍然失败关闭,并提示运行 openclaw doctor --fix

延迟完整加载(Deferred Full Load)

渠道插件可以开启延迟加载,减少启动时间:

json
{
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "startup": {
      "deferConfiguredChannelFullLoadUntilAfterListen": true
    }
  }
}

开启后,即使渠道已配置,OpenClaw 在 pre-listen 启动阶段也只加载 setupEntry,完整入口在 gateway 开始监听后才加载。

警告: 仅当 setupEntry 已注册 gateway 监听前所需的全部内容(渠道注册、HTTP 路由、gateway 方法)时才启用延迟加载。如果完整入口拥有必要的启动能力,保持默认行为。

如果 setup/完整入口注册了 gateway RPC 方法,务必将它们放在插件特有的前缀下。保留的核心管理命名空间(config.*exec.approvals.*wizard.*update.*)始终归属于核心,并解析到 operator.admin

Plugin Manifest

每个原生插件必须在包根目录下提供 openclaw.plugin.json,用于在执行插件代码之前验证配置。

基础模板:

json
{
  "id": "my-plugin",
  "name": "My Plugin",
  "description": "Adds My Plugin capabilities to OpenClaw",
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "webhookSecret": {
        "type": "string",
        "description": "Webhook verification secret"
      }
    }
  }
}

渠道插件需加 kindchannels

json
{
  "id": "my-channel",
  "kind": "channel",
  "channels": ["my-channel"],
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}

即使不接受任何配置的插件也必须提供 manifest,空 schema 合法:

json
{
  "id": "my-plugin",
  "configSchema": {
    "type": "object",
    "additionalProperties": false
  }
}

完整 manifest 字段参考见 Plugin Manifest

ClawHub 发布

对于插件包,使用包专用的 ClawHub 命令:

bash
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin

clawhub skill publish 是旧版技能专用别名,插件包始终使用 clawhub package publish

Setup Entry

setup-entry.tsindex.ts 的轻量替代。当 OpenClaw 只需要 setup 面(引导、配置修复、禁用渠道检查)时加载。

typescript
// setup-entry.ts
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
import { myChannelPlugin } from "./src/channel.js";

export default defineSetupPluginEntry(myChannelPlugin);

这样可以避免在 setup 流程中加载繁重的 runtime 代码(加密库、CLI 注册、后台服务)。

内置工作区渠道如果已经在 sidecar 模块中保持了 setup 安全的导出,可以使用 defineBundledChannelSetupEntry(...)(来自 openclaw/plugin-sdk/channel-entry-contract)替代 defineSetupPluginEntry(...)。该内置合约还支持可选的 runtime 导出,使 setup 时的 runtime 接线保持轻量和显式。

什么时候会使用 setupEntry 而非完整入口?

  • 渠道已禁用但需要 setup/引导面
  • 渠道已启用但未配置
  • 开启了延迟加载(deferConfiguredChannelFullLoadUntilAfterListen

setupEntry 必须注册的内容

  • 渠道插件对象(通过 defineSetupPluginEntry
  • gateway 监听前所需的 HTTP 路由
  • 启动时所需的 gateway 方法
  • 这些启动 gateway 方法应避免使用保留的核心管理命名空间(如 config.*update.*

setupEntry 不应包含的内容

  • CLI 注册
  • 后台服务
  • 繁重的 runtime 导入(加密、SDK)
  • 只在启动后才需要的 gateway 方法

窄型 Setup Helper 导入

对于热门 setup-only 路径,优先使用窄型 helper 而非宽泛的 plugin-sdk/setup

导入路径用途关键导出
plugin-sdk/setup-runtimesetup 时的 runtime helper,在 setupEntry/延迟渠道启动中可用createSetupTranslator, createPatchedAccountSetupAdapter, createEnvPatchedAccountSetupAdapter, createSetupInputPresenceValidator, noteChannelLookupFailure, noteChannelLookupSummary, promptResolvedAllowFrom, splitSetupEntries, createAllowlistSetupWizardProxy, createDelegatedSetupWizardProxy
plugin-sdk/setup-adapter-runtime已废弃的兼容别名;使用 plugin-sdk/setup-runtimecreateEnvPatchedAccountSetupAdapter
plugin-sdk/setup-toolssetup/安装 CLI/归档/文档 helperformatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR

需要完整 setup 工具箱(包含配置 patch helper 如 moveSingleAccountChannelSectionToDefaultAccount(...))时,使用宽泛的 plugin-sdk/setup

使用 createSetupTranslator(...) 创建固定 setup 向导文本。它遵循 CLI 向导区域设置(OPENCLAW_LOCALE,然后是系统区域设置变量),默认回退到英语。插件特有的 setup 文本应放在插件拥有的代码中,只对常见的 setup 标签、状态文本和官方内置插件 setup 副本使用共享目录键。

setup patch 适配器在热路径上是安全的:其内置的单账号升级合约接口查找是惰性的,导入 plugin-sdk/setup-runtime 不会在适配器实际使用前急切加载合约接口发现。

渠道自有的单账号升级

当渠道从顶层单账号配置升级到 channels.<id>.accounts.* 时,默认共享行为是将升级后的账号值移入 accounts.default

内置渠道可通过其 setup 合约接口缩窄或覆盖该升级策略:

  • singleAccountKeysToMove:应移入升级账号的额外顶层键
  • namedAccountPromotionKeys:当命名账号已存在时,只将这些键移入升级账号;共享策略/交付键保留在渠道根
  • resolveSingleAccountPromotionTarget(...):选择哪个已有账号接收升级值

Matrix 是当前的内置示例。如果恰好有一个已命名的 Matrix 账号存在,或 defaultAccount 指向非规范键(如 Ops),升级会保留该账号而非创建新的 accounts.default 条目。

Config Schema

插件配置按 manifest 中的 JSON Schema 验证。用户通过以下配置来配置插件:

json5
{
  plugins: {
    entries: {
      "my-plugin": {
        config: {
          webhookSecret: "abc123",
        },
      },
    },
  },
}

插件注册期间通过 api.pluginConfig 接收此配置。

渠道特定配置使用渠道配置区块:

json5
{
  channels: {
    "my-channel": {
      token: "bot-token",
      allowFrom: ["user1", "user2"],
    },
  },
}

构建渠道 Config Schema

使用 buildChannelConfigSchema(来自 openclaw/plugin-sdk/channel-config-schema)将 Zod schema 转换为 OpenClaw 验证的 ChannelConfigSchema 包装器:

typescript
import { z } from "zod";
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";

const accountSchema = z.object({
  token: z.string().optional(),
  allowFrom: z.array(z.string()).optional(),
  accounts: z.object({}).catchall(z.any()).optional(),
  defaultAccount: z.string().optional(),
});

const configSchema = buildChannelConfigSchema(accountSchema);

如果你已经将合约编写为 JSON Schema 或 TypeBox,使用直接 helper 可以让 OpenClaw 在元数据路径上跳过 Zod 到 JSON Schema 的转换:

typescript
import { Type } from "typebox";
import { buildJsonChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";

const configSchema = buildJsonChannelConfigSchema(
  Type.Object({
    token: Type.Optional(Type.String()),
    allowFrom: Type.Optional(Type.Array(Type.String())),
  }),
);

对于第三方插件,冷路径合约仍然是插件 manifest:将生成的 JSON Schema 镜像到 openclaw.plugin.json#channelConfigs,这样配置 schema、setup 和 UI 面可以在不加载 runtime 代码的情况下检查 channels.<id>

Setup 向导

渠道插件可以为 openclaw onboard 提供交互式 setup 向导。向导是一个 ChannelSetupWizard 对象,位于 ChannelPlugin 上:

typescript
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/channel-setup";

const setupWizard: ChannelSetupWizard = {
  channel: "my-channel",
  status: {
    configuredLabel: "Connected",
    unconfiguredLabel: "Not configured",
    resolveConfigured: ({ cfg }) => Boolean((cfg.channels as any)?.["my-channel"]?.token),
  },
  credentials: [
    {
      inputKey: "token",
      providerHint: "my-channel",
      credentialLabel: "Bot token",
      preferredEnvVar: "MY_CHANNEL_BOT_TOKEN",
      envPrompt: "Use MY_CHANNEL_BOT_TOKEN from environment?",
      keepPrompt: "Keep current token?",
      inputPrompt: "Enter your bot token:",
      inspect: ({ cfg, accountId }) => {
        const token = (cfg.channels as any)?.["my-channel"]?.token;
        return {
          accountConfigured: Boolean(token),
          hasConfiguredValue: Boolean(token),
        };
      },
    },
  ],
};

ChannelSetupWizard 类型支持 credentialstextInputsdmPolicyallowFromgroupAccesspreparefinalize 等。完整示例参考内置插件包(如 Discord 插件的 src/channel.setup.ts)。

共享 allowFrom 提示

对于只需标准 note → prompt → parse → merge → patch 流程的 DM allowlist 提示,优先使用 openclaw/plugin-sdk/setup 中的共享 helper:createPromptParsedAllowFromForAccount(...)createTopLevelChannelParsedAllowFromPrompt(...)createNestedChannelParsedAllowFromPrompt(...)

标准渠道 setup 状态

对于仅因标签、评分和可选额外行而不同的渠道 setup 状态块,优先使用 openclaw/plugin-sdk/setup 中的 createStandardChannelSetupStatus(...),而不是在每个插件中手写相同的 status 对象。

可选渠道 setup 面

对于只在特定上下文中出现的可选 setup 面,使用 createOptionalChannelSetupSurface

typescript
import { createOptionalChannelSetupSurface } from "openclaw/plugin-sdk/channel-setup";

const setupSurface = createOptionalChannelSetupSurface({
  channel: "my-channel",
  label: "My Channel",
  npmSpec: "@myorg/openclaw-my-channel",
  docsPath: "/channels/my-channel",
});
// 返回 { setupAdapter, setupWizard }

plugin-sdk/channel-setup 还暴露了底层构建器 createOptionalChannelSetupAdapter(...)createOptionalChannelSetupWizard(...),适用于只需要可选安装面的半边情况。生成的可选适配器/向导在真实配置写入时故障关闭;它们复用一条"安装必需"的消息,适用于 validateInputapplyAccountConfigfinalize,当设置了 docsPath 时会附加文档链接。

二进制后端 setup helper

对于二进制后端 setup UI,优先使用共享委托 helper:

  • createDetectedBinaryStatus(...):状态块仅依赖于标签、提示、评分和二进制检测
  • createCliPathTextInput(...):路径后端的文本输入
  • createDelegatedSetupWizardStatusResolvers(...)createDelegatedPrepare(...)createDelegatedFinalize(...)createDelegatedResolveConfigured(...):当 setupEntry 需要惰性委托给更重的完整向导时使用
  • createDelegatedTextInputShouldPrompt(...):当 setupEntry 只需要委托 textInputs[*].shouldPrompt 决策时使用

发布与安装

外部插件: 发布到 ClawHub 或 npm,然后安装:

bash
openclaw plugins install @myorg/openclaw-my-plugin

裸包 spec 会在启动切换期间从 npm 安装。

bash
# 强制 ClawHub
openclaw plugins install clawhub:@myorg/openclaw-my-plugin

# 强制 npm(适用于未迁移的包)
openclaw plugins install npm:@myorg/openclaw-my-plugin

内部仓库插件: 放入内置插件工作区目录,构建时自动发现。

用户安装方式:

bash
openclaw plugins install <package-name>

openclaw plugins install 会在 ~/.openclaw/npm 下安装包,并禁用生命周期脚本。保持插件依赖树为纯 JS/TS,避免需要 postinstall 构建的包。

Gateway 启动不会安装插件依赖。npm/git/ClawHub 安装流程负责依赖汇聚;本地插件必须已安装其依赖。

内置包元数据是显式的,而不是在 gateway 启动时从构建的 JavaScript 推断。runtime 依赖属于拥有它们的插件包;打包后的 OpenClaw 启动永远不会修复或镜像插件依赖。

相关文档

常见问题

setupEntry 和完整入口(index.ts)的职责怎么划分?

setupEntry 只注册"渠道禁用/未配置时也需要的最小集合":渠道插件对象本身(通过 defineSetupPluginEntry)、setup 流程中需要的 HTTP 路由和 gateway 方法。繁重的后台服务、CLI 注册器、SDK 初始化都放完整入口。原则:setupEntry 不引入 runtime 依赖,开机即可加载。

什么情况下需要开启 deferConfiguredChannelFullLoadUntilAfterListen

当渠道 runtime 较重(如需要动态编译、大量 SDK 初始化)且 pre-listen 阶段不需要它时,开启延迟加载可以缩短 gateway 启动时间。前提是 setupEntry 已经注册好 gateway 监听前所需的全部内容。如果完整入口有启动必需的内容,不要开启,否则 gateway 可能在完整入口加载完成前就开始处理请求。

发布插件时 compat.minGatewayVersion 有什么作用?

minGatewayVersion 声明插件运行所需的最低 OpenClaw 版本。用户使用旧版 gateway 安装插件时,系统会提示版本不兼容并拒绝安装,防止因接口不匹配导致的静默错误。发布到 ClawHub 时此字段必填。如果设置不当导致版本冲突,可以用 openclaw doctor --fix 检查。