Appearance
本页是 OpenClaw 原生插件 manifest 文件(openclaw.plugin.json)的完整字段参考。如果你正在构建一个 OpenClaw 插件、需要提供插件配置 schema 或排查插件校验错误,这里列出了所有可用的 manifest 字段、JSON Schema 要求及各字段的业务含义。每个原生插件必须在插件根目录放置 openclaw.plugin.json,缺失或格式错误会直接阻断配置验证,openclaw doctor 可帮助诊断。
OpenClaw Plugin Manifest 完整字段参考:openclaw.plugin.json 配置指南
本页仅适用于原生 OpenClaw 插件 manifest。
兼容的 Bundle 格式(Codex/Claude/Cursor)使用各自的 manifest 文件,OpenClaw 会自动检测那些布局,但不会用本页描述的 schema 验证它们。关于兼容 bundle 布局的说明,见 Plugin bundles。
每个原生 OpenClaw 插件必须在插件根目录下提供 openclaw.plugin.json。OpenClaw 在不执行插件代码的情况下用它验证配置。缺失或格式不合法的 manifest 视为插件错误,阻断配置验证。
完整插件系统指南:插件安装与使用
原生能力模型及外部兼容性指导:能力模型
这个文件的作用
openclaw.plugin.json 是 OpenClaw 加载插件代码之前读取的元数据。以下所有内容必须能在不启动插件 runtime 的情况下低成本检查。
用来声明:
- 插件身份、配置验证、配置 UI 提示
- 认证、引导和设置元数据(别名、自动启用、provider 环境变量、认证选项)
- 控制平面激活提示
- 简写模型家族所有权(runtime 之前自动加载)
- 静态能力所有权快照(
contracts) - QA runner 元数据,供共享的
openclaw qa宿主检查 - 渠道特定配置元数据,合并到 catalog 和验证面
不能用来: 注册运行时行为、声明代码入口点、npm 安装元数据。那些分别属于插件代码和 package.json。
最简示例
json
{
"id": "voice-call",
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {}
}
}完整示例
json
{
"id": "openrouter",
"name": "OpenRouter",
"description": "OpenRouter provider plugin",
"version": "1.0.0",
"providers": ["openrouter"],
"modelSupport": {
"modelPrefixes": ["router-"]
},
"modelIdNormalization": {
"providers": {
"openrouter": {
"prefixWhenBare": "openrouter"
}
}
},
"providerEndpoints": [
{
"endpointClass": "openrouter",
"hostSuffixes": ["openrouter.ai"]
}
],
"providerRequest": {
"providers": {
"openrouter": {
"family": "openrouter"
}
}
},
"cliBackends": ["openrouter-cli"],
"syntheticAuthRefs": ["openrouter-cli"],
"providerAuthEnvVars": {
"openrouter": ["OPENROUTER_API_KEY"]
},
"providerAuthAliases": {
"openrouter-coding": "openrouter"
},
"channelEnvVars": {
"openrouter-chatops": ["OPENROUTER_CHATOPS_TOKEN"]
},
"providerAuthChoices": [
{
"provider": "openrouter",
"method": "api-key",
"choiceId": "openrouter-api-key",
"choiceLabel": "OpenRouter API key",
"groupId": "openrouter",
"groupLabel": "OpenRouter",
"optionKey": "openrouterApiKey",
"cliFlag": "--openrouter-api-key",
"cliOption": "--openrouter-api-key <key>",
"cliDescription": "OpenRouter API key",
"onboardingScopes": ["text-inference"]
}
],
"uiHints": {
"apiKey": {
"label": "API key",
"placeholder": "sk-or-v1-...",
"sensitive": true
}
},
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"apiKey": {
"type": "string"
}
}
}
}顶级字段参考
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
id | 是 | string | 规范插件 id,用于 plugins.entries.<id> |
configSchema | 是 | object | 此插件配置的内联 JSON Schema |
enabledByDefault | 否 | true | 标记内置插件默认启用。省略或设置非 true 值则默认禁用 |
enabledByDefaultOnPlatforms | 否 | string[] | 仅在特定 Node.js 平台(如 ["darwin"])上默认启用内置插件。显式配置仍然优先 |
legacyPluginIds | 否 | string[] | 规范化到此插件 id 的旧 id |
autoEnableWhenConfiguredProviders | 否 | string[] | 当 auth/config/模型引用出现这些 provider id 时自动启用本插件 |
kind | 否 | "memory" | "context-engine" | 声明独占插件类型,由 plugins.slots.* 使用 |
channels | 否 | string[] | 此插件拥有的渠道 id,用于发现和配置验证 |
providers | 否 | string[] | 此插件拥有的 provider id |
providerCatalogEntry | 否 | string | 轻量 provider-catalog 模块路径(相对插件根目录),用于在不激活完整 runtime 时加载 manifest 级 catalog 元数据 |
modelSupport | 否 | object | manifest 级简写模型家族元数据,用于 runtime 之前自动加载插件 |
modelCatalog | 否 | object | 声明式模型目录元数据,供未来只读列表、引导、模型选择器使用,无需加载 runtime |
modelPricing | 否 | object | provider 拥有的外部定价查找策略 |
modelIdNormalization | 否 | object | provider 拥有的模型 id 别名/前缀清理,在 provider runtime 加载前执行 |
providerEndpoints | 否 | object[] | manifest 级端点宿主/baseUrl 元数据,供核心在 provider runtime 加载前分类路由 |
providerRequest | 否 | object | 轻量 provider 家族和请求兼容性元数据,供核心在 runtime 加载前使用 |
cliBackends | 否 | string[] | 此插件拥有的 CLI 推理后端 id |
syntheticAuthRefs | 否 | string[] | provider 或 CLI 后端 ref,其插件拥有的合成 auth hook 应在冷模型发现时探测 |
nonSecretAuthMarkers | 否 | string[] | 内置插件拥有的占位 API 密钥值,代表非秘密的本地/OAuth/环境凭证状态 |
commandAliases | 否 | object[] | 此插件拥有的命令名,用于在 runtime 加载前产生插件感知的配置和 CLI 诊断 |
providerAuthEnvVars | 否 | Record<string, string[]> | (已废弃)provider auth/状态查找的兼容环境元数据。新插件应使用 setup.providers[].envVars |
providerAuthAliases | 否 | Record<string, string> | 应复用另一 provider id 进行 auth 查找的 provider id,例如共享基础 API 密钥的编码 provider |
channelEnvVars | 否 | Record<string, string[]> | 轻量渠道环境元数据,供通用启动/配置助手检查 |
providerAuthChoices | 否 | object[] | 引导选择器的认证选项元数据 |
activation | 否 | object | 轻量激活计划元数据,标记启动、provider、命令、渠道等触发条件 |
setup | 否 | object | 轻量设置/引导描述符,供发现和设置面在加载 runtime 前检查 |
qaRunners | 否 | object[] | 轻量 QA runner 描述符,供共享 openclaw qa 宿主在 runtime 加载前使用 |
contracts | 否 | object | 静态能力所有权快照,覆盖外部 auth hooks、嵌入、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索、工具所有权 |
mediaUnderstandingProviderMetadata | 否 | Record<string, object> | 媒体理解 provider 的轻量默认值 |
imageGenerationProviderMetadata | 否 | Record<string, object> | 图像生成 provider 的轻量 auth 元数据 |
videoGenerationProviderMetadata | 否 | Record<string, object> | 视频生成 provider 的轻量 auth 元数据 |
musicGenerationProviderMetadata | 否 | Record<string, object> | 音乐生成 provider 的轻量 auth 元数据 |
toolMetadata | 否 | Record<string, object> | 轻量工具可用性元数据,用于在 config/env/auth 证据不足时不加载 runtime |
channelConfigs | 否 | Record<string, object> | manifest 级渠道配置元数据,在 runtime 加载前合并到发现和验证面 |
skills | 否 | string[] | 要加载的 skill 目录(相对插件根目录) |
name | 否 | string | 可读的插件名称 |
description | 否 | string | 插件摘要,显示在插件面上 |
version | 否 | string | 信息性插件版本 |
uiHints | 否 | Record<string, object> | 配置字段的 UI 标签、占位符、敏感性提示 |
Generation provider metadata 参考
生成类 provider(图像/视频/音乐)使用 contracts.*GenerationProviders 声明所有权,使用对应 *GenerationProviderMetadata 字段提供静态 auth 信号。OpenClaw 在 provider runtime 加载前读取这些信号,供核心工具判断可用性,无需导入每个 provider 插件。
只应放入声明性事实。传输、请求转换、令牌刷新、凭证验证和实际生成行为始终位于插件 runtime 中。
json
{
"contracts": {
"imageGenerationProviders": ["example-image"]
},
"imageGenerationProviderMetadata": {
"example-image": {
"aliases": ["example-image-oauth"],
"authProviders": ["example-image"],
"configSignals": [
{
"rootPath": "plugins.entries.example-image.config",
"overlayPath": "image",
"mode": {
"path": "mode",
"default": "local",
"allowed": ["local"]
},
"requiredAny": ["workflow", "workflowPath"],
"required": ["promptNodeId"]
}
],
"authSignals": [
{
"provider": "example-image"
},
{
"provider": "example-image-oauth",
"providerBaseUrl": {
"provider": "example-image",
"defaultBaseUrl": "https://api.example.com/v1",
"allowedBaseUrls": ["https://api.example.com/v1"]
}
}
]
}
}
}每个元数据条目支持的字段(以 imageGenerationProviderMetadata 为例,其他类似):
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
aliases | 否 | string[] | 额外的 provider id,视为该生成 provider 的静态 auth 别名 |
authProviders | 否 | string[] | provider id,其已配置的 auth profile 应视为该生成 provider 的 auth |
configSignals | 否 | object[] | 轻量纯配置可用性信号,适用于无需 auth profile 或 env vars 的本地/自托管 provider |
authSignals | 否 | object[] | 显式 auth 信号。存在时替换来自 provider id、aliases 和 authProviders 的默认信号集 |
referenceAudioInputs | 否 | boolean | 仅视频生成。true 表示该 provider 接受参考音频资源 |
每个 configSignals 条目的字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
rootPath | 是 | string | 要检查的插件拥有的配置对象的点路径,如 plugins.entries.example.config |
overlayPath | 否 | string | 根配置内部的点路径,其对象应在评估信号前覆盖根对象。用于能力特定配置(如 image、video、music) |
required | 否 | string[] | 有效配置中必须存在非空值的点路径(字符串非空,对象/数组不为空) |
requiredAny | 否 | string[] | 有效配置中至少有一个必须存在非空值的点路径 |
mode | 否 | object | 有效配置内的可选字符串模式守卫。用于配置仅适用于某一模式的情况 |
mode 守卫支持的字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
path | 否 | string | 有效配置内的点路径,默认为 mode |
default | 否 | string | 配置省略该路径时使用的模式值 |
allowed | 否 | string[] | 若存在,仅当有效模式是其中之一时信号通过 |
disallowed | 否 | string[] | 若存在,有效模式是其中之一时信号失败 |
每个 authSignals 条目的字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
provider | 是 | string | 要在已配置 auth profiles 中检查的 provider id |
providerBaseUrl | 否 | object | 可选守卫:仅当引用的已配置 provider 使用允许的 base URL 时信号才计数。用于 auth 别名只对某些 API 有效的情况 |
providerBaseUrl 守卫支持的字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
provider | 是 | string | 要检查其 baseUrl 的 provider 配置 id |
defaultBaseUrl | 否 | string | provider 配置省略 baseUrl 时假定的 base URL |
allowedBaseUrls | 是 | string[] | 该 auth 信号允许的 base URL。配置的或默认的 base URL 不匹配规范化值之一时,信号被忽略 |
Tool metadata 参考
toolMetadata 使用与 generation provider metadata 相同的 configSignals 和 authSignals 形状,按键为工具名。contracts.tools 声明所有权,toolMetadata 声明轻量可用性证据,使 OpenClaw 无需导入插件 runtime 去调用返回 null 的工具工厂。
json
{
"providerAuthEnvVars": {
"example": ["EXAMPLE_API_KEY"]
},
"contracts": {
"tools": ["example_search"]
},
"toolMetadata": {
"example_search": {
"authSignals": [
{
"provider": "example"
}
],
"configSignals": [
{
"rootPath": "plugins.entries.example.config",
"overlayPath": "search",
"required": ["apiKey"]
}
]
}
}
}如果某个工具没有 toolMetadata,OpenClaw 保留现有行为:当工具合约匹配策略时加载拥有者插件。对于工厂依赖 auth/config 的热路径工具,插件作者应声明 toolMetadata,而不是让核心导入 runtime 来询问。
providerAuthChoices 参考
每条 providerAuthChoices 条目描述一个引导或认证选项。OpenClaw 在 provider runtime 加载前读取。Provider 设置列表使用这些 manifest 选项、描述派生的设置选项和安装目录元数据,无需加载 provider runtime。
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
provider | 是 | string | 该选项所属的 provider id |
method | 是 | string | 要分派的认证方法 id |
choiceId | 是 | string | 引导和 CLI 流程使用的稳定认证选项 id |
choiceLabel | 否 | string | 用户可见标签。省略时回退到 choiceId |
choiceHint | 否 | string | 选择器的简短提示文字 |
assistantPriority | 否 | number | 值越小在助手驱动的交互选择器中排越靠前 |
assistantVisibility | 否 | "visible" | "manual-only" | 在助手选择器中隐藏,但仍允许手动 CLI 选择 |
deprecatedChoiceIds | 否 | string[] | 旧选项 id,应将用户重定向到此替换选项 |
groupId | 否 | string | 分组 id |
groupLabel | 否 | string | 分组的用户可见标签 |
groupHint | 否 | string | 分组的简短提示文字 |
optionKey | 否 | string | 简单单 flag 认证流程的内部 option key |
cliFlag | 否 | string | CLI flag 名,如 --openrouter-api-key |
cliOption | 否 | string | 完整 CLI option,如 --openrouter-api-key <key> |
cliDescription | 否 | string | CLI help 中显示的描述 |
onboardingScopes | 否 | Array<"text-inference" | "image-generation" | "music-generation"> | 此选项应出现在哪些引导页面。省略时默认 ["text-inference"] |
commandAliases 参考
当插件拥有一个运行时命令名,而用户可能错误地将其放入 plugins.allow 或尝试作为根 CLI 命令运行时,使用 commandAliases。OpenClaw 无需导入 runtime 代码即可使用此元数据进行诊断。
json
{
"commandAliases": [
{
"name": "dreaming",
"kind": "runtime-slash",
"cliCommand": "memory"
}
]
}| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
name | 是 | string | 属于此插件的命令名 |
kind | 否 | "runtime-slash" | 标记该别名为聊天斜杠命令,而非根 CLI 命令 |
cliCommand | 否 | string | 相关的根 CLI 命令,用于 CLI 操作建议 |
activation 参考
当插件可以廉价声明哪些控制平面事件应将其包含在激活/加载计划中时,使用 activation。此块是计划器元数据,不是生命周期 API。
每个插件应有意设置 activation.onStartup。仅在插件必须在 Gateway 启动期间运行时设为 true;插件在启动时是惰性的且只应从更窄的触发器加载时设为 false。省略 onStartup 不再隐式启动加载插件。
json
{
"activation": {
"onStartup": false,
"onProviders": ["openai"],
"onCommands": ["models"],
"onChannels": ["web"],
"onRoutes": ["gateway-webhook"],
"onConfigPaths": ["browser"],
"onCapabilities": ["provider", "tool"]
}
}| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
onStartup | 否 | boolean | 显式 Gateway 启动激活。每个插件应设置。true 表示启动时导入插件;false 保持启动惰性,除非另一匹配触发器要求加载 |
onProviders | 否 | string[] | 应包含此插件在激活/加载计划中的 provider id |
onAgentHarnesses | 否 | string[] | 内嵌的 agent 运行时 id(用于代理 harness),应包含此插件。顶层 cliBackends 用于 CLI 后端别名 |
onCommands | 否 | string[] | 应包含此插件的命令 id |
onChannels | 否 | string[] | 应包含此插件的渠道 id |
onRoutes | 否 | string[] | 应包含此插件的路由种类 |
onConfigPaths | 否 | string[] | 根相对配置路径,当路径存在且未显式禁用时,应包含此插件在启动/加载计划中 |
onCapabilities | 否 | Array<"provider" | "channel" | "tool" | "hook"> | 宽泛的能力提示,用于控制平面激活计划。尽可能使用更窄的字段 |
当前实时消费者详见原文的“Current live consumers”部分,这里不再冗余列出。
qaRunners 参考
当插件为共享的 openclaw qa 根贡献一个或多个传输 runner 时使用。
json
{
"qaRunners": [
{
"commandName": "matrix",
"description": "Run the Docker-backed Matrix live QA lane against a disposable homeserver"
}
]
}| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
commandName | 是 | string | 挂载在 openclaw qa 下的子命令,如 matrix |
description | 否 | string | 共享宿主需要 stub 命令时使用的回退帮助文本 |
setup 参考
当设置和引导面需要在 runtime 加载前获取插件拥的廉价元数据时使用。
json
{
"setup": {
"providers": [
{
"id": "openai",
"authMethods": ["api-key"],
"envVars": ["OPENAI_API_KEY"],
"authEvidence": [
{
"type": "local-file-with-env",
"fileEnvVar": "OPENAI_CREDENTIALS_FILE",
"requiresAllEnv": ["OPENAI_PROJECT"],
"credentialMarker": "openai-local-credentials",
"source": "openai local credentials"
}
]
}
],
"cliBackends": ["openai-cli"],
"configMigrations": ["legacy-openai-auth"],
"requiresRuntime": false
}
}顶层 cliBackends 仍然有效并继续描述 CLI 推理后端。setup.cliBackends 是仅用于设置/控制平面流程的描述符面。
当存在 setup.providers 和 setup.cliBackends 时,它们是设置发现的首选描述符优先查找面。如果描述符只缩小了候选插件,但设置仍需要更丰富的设置时 runtime hooks,则设置 requiresRuntime: true 并保持 setup-api 作为回退执行路径。
setup.providers 字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
id | 是 | string | 设置或引导期间暴露的 provider id。保持规范化 id 全局唯一 |
authMethods | 否 | string[] | 该 provider 无需加载完整 runtime 即可支持的设置/认证方法 id |
envVars | 否 | string[] | 通用设置/状态面可在 runtime 加载前检查的环境变量 |
authEvidence | 否 | object[] | 轻量本地凭证标记,用于无需加载 runtime 即可验证的非秘密认证证据 |
authEvidence 支持的字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
type | 是 | string | 当前仅 local-file-with-env |
fileEnvVar | 否 | string | 包含显式凭证文件路径的环境变量 |
fallbackPaths | 否 | string[] | 当 fileEnvVar 缺失或为空时检查的本地凭证文件路径。支持 ${HOME} 和 ${APPDATA} |
requiresAnyEnv | 否 | string[] | 至少一个列出的环境变量必须非空证据才有效 |
requiresAllEnv | 否 | string[] | 所有列出的环境变量必须非空证据才有效 |
credentialMarker | 是 | string | 证据存在时返回的非秘密标记 |
source | 否 | string | 面向用户的来源标签,用于 auth/status 输出 |
setup 顶层字段:
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
providers | 否 | object[] | 设置和引导期间暴露的 provider 描述符 |
cliBackends | 否 | string[] | 设置时后端 id,用于描述符优先的设置查找。保持规范化 id 全局唯一 |
configMigrations | 否 | string[] | 此插件设置面拥有的配置迁移 id |
requiresRuntime | 否 | boolean | 描述符查找后设置是否仍需要 setup-api 执行 |
uiHints 参考
uiHints 是从配置字段名到渲染提示的映射。
json
{
"uiHints": {
"apiKey": {
"label": "API key",
"help": "Used for OpenRouter requests",
"placeholder": "sk-or-v1-...",
"sensitive": true
}
}
}每个字段提示可包含:
| 字段 | 类型 | 说明 |
|---|---|---|
label | string | 用户可见字段标签 |
help | string | 简短帮助文字 |
tags | string[] | 可选 UI 标签 |
advanced | boolean | 标记为高级字段 |
sensitive | boolean | 标记为秘密或敏感字段 |
placeholder | string | 表单输入框占位符 |
contracts 参考
contracts 仅用于 OpenClaw 无需导入插件 runtime 即可读取的静态能力所有权元数据。
json
{
"contracts": {
"agentToolResultMiddleware": ["pi", "codex"],
"externalAuthProviders": ["acme-ai"],
"embeddingProviders": ["openai-compatible"],
"speechProviders": ["openai"],
"realtimeTranscriptionProviders": ["openai"],
"realtimeVoiceProviders": ["openai"],
"memoryEmbeddingProviders": ["local"],
"mediaUnderstandingProviders": ["openai", "openai-codex"],
"imageGenerationProviders": ["openai"],
"videoGenerationProviders": ["qwen"],
"webFetchProviders": ["firecrawl"],
"webSearchProviders": ["gemini"],
"migrationProviders": ["hermes"],
"gatewayMethodDispatch": ["authenticated-request"],
"tools": ["firecrawl_search", "firecrawl_scrape"]
}
}每个列表为可选。关键字段含义:
| 字段 | 类型 | 说明 |
|---|---|---|
embeddedExtensionFactories | string[] | Codex 应用服务器扩展工厂 id,当前为 codex-app-server |
agentToolResultMiddleware | string[] | 内置插件可注册工具结果中间件的运行时 id |
externalAuthProviders | string[] | 其外部 auth profile 钩子由此插件拥有的 provider id |
embeddingProviders | string[] | 此插件拥有的通用嵌入 provider id |
speechProviders | string[] | 此插件拥有的语音 provider id |
realtimeTranscriptionProviders | string[] | 实时转录 provider id |
realtimeVoiceProviders | string[] | 实时语音 provider id |
memoryEmbeddingProviders | string[] | 内存嵌入 provider id |
mediaUnderstandingProviders | string[] | 媒体理解 provider id |
imageGenerationProviders | string[] | 图像生成 provider id |
videoGenerationProviders | string[] | 视频生成 provider id |
webFetchProviders | string[] | 网页抓取 provider id |
webSearchProviders | string[] | 网页搜索 provider id |
migrationProviders | string[] | 用于 openclaw migrate 的导入 provider id |
gatewayMethodDispatch | string[] | 保留的授权,用于在进程内分发 Gateway 方法的已验证插件 HTTP 路由 |
tools | string[] | 此插件拥有的 agent 工具名 |
mediaUnderstandingProviderMetadata 参考
当媒体理解 provider 具有默认模型、自动认证回退优先级或核心帮助器在 runtime 加载前需要原生文档支持时使用。键也必须声明在 contracts.mediaUnderstandingProviders 中。
json
{
"contracts": {
"mediaUnderstandingProviders": ["example"]
},
"mediaUnderstandingProviderMetadata": {
"example": {
"capabilities": ["image", "audio"],
"defaultModels": {
"image": "example-vision-latest",
"audio": "example-transcribe-latest"
},
"autoPriority": {
"image": 40
},
"nativeDocumentInputs": ["pdf"]
}
}
}每个 provider 条目可包含:
| 字段 | 类型 | 说明 |
|---|---|---|
capabilities | ("image" | "audio" | "video")[] | 该 provider 暴露的媒体能力 |
defaultModels | Record<string, string> | 能力到模型的默认值,当配置未指定模型时使用 |
autoPriority | Record<string, number> | 较低数字在自动凭据驱动 provider 回退中排更靠前 |
nativeDocumentInputs | "pdf"[] | provider 支持的原生文档输入 |
channelConfigs 参考
当渠道插件在 runtime 加载前需要廉价配置元数据时使用。channelConfigs 的 schema 用于验证 channels.<channel-id>,而 configSchema 用于验证 plugins.entries.<plugin-id>.config。
json
{
"channelConfigs": {
"matrix": {
"schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"homeserverUrl": { "type": "string" }
}
},
"uiHints": {
"homeserverUrl": {
"label": "Homeserver URL",
"placeholder": "https://matrix.example.com"
}
},
"label": "Matrix",
"description": "Matrix homeserver 连接",
"commands": {
"nativeCommandsAutoEnabled": true,
"nativeSkillsAutoEnabled": true
},
"preferOver": ["matrix-legacy"]
}
}
}每个渠道条目可包含:
| 字段 | 类型 | 说明 |
|---|---|---|
schema | object | channels.<id> 的 JSON Schema。每个声明条目必填 |
uiHints | Record<string, object> | 可选 UI 标签/占位符/敏感性提示 |
label | string | 运行时未就绪时合并到选择器和 inspect 面的渠道标签 |
description | string | 渠道简短描述 |
commands | object | 静态原生命令和原生技能自动默认值,用于运行时前的配置检查 |
preferOver | string[] | 本渠道在选择面中应优先于这些旧/低优先级插件 id |
替换另一个渠道插件: 使用 preferOver 当你的插件是某个渠道 id 的首选拥有者,而另一个插件也能提供该渠道。例如,重命名的插件 id、替代内置插件的独立插件、或者保持相同渠道 id 以进行配置兼容的维护分支。
modelSupport 参考
当 OpenClaw 在 runtime 加载前需要从简写模型 id(如 gpt-5.5)推断 provider 插件时使用。
json
{
"modelSupport": {
"modelPrefixes": ["gpt-", "o1", "o3", "o4"],
"modelPatterns": ["^computer-use-preview"]
}
}优先级:
- 显式
provider/model引用 → 使用拥有者插件的providers元数据 modelPatterns优先于modelPrefixes- 一个非内置插件和一个内置插件都匹配时,非内置插件胜出
- 其余歧义忽略,直到用户/配置指定 provider
| 字段 | 类型 | 说明 |
|---|---|---|
modelPrefixes | string[] | 用 startsWith 匹配简写模型 id 的前缀 |
modelPatterns | string[] | 去掉 profile 后缀后匹配简写模型 id 的正则表达式来源 |
modelCatalog 参考
当 OpenClaw 在加载 plugin runtime 之前需要 provider 模型元数据时使用。这是 manifest 拥有的固定目录行、provider 别名、抑制规则和发现模式的来源。运行时刷新仍属于 provider runtime 代码,但 manifest 告诉核心何时需要 runtime。
json
{
"providers": ["openai"],
"modelCatalog": {
"providers": {
"openai": {
"baseUrl": "https://api.openai.com/v1",
"api": "openai-responses",
"models": [
{
"id": "gpt-5.4",
"name": "GPT-5.4",
"input": ["text", "image"],
"reasoning": true,
"contextWindow": 256000,
"maxTokens": 128000,
"cost": {
"input": 1.25,
"output": 10,
"cacheRead": 0.125
},
"status": "available",
"tags": ["default"]
}
]
}
},
"aliases": {
"azure-openai-responses": {
"provider": "openai",
"api": "azure-openai-responses"
}
},
"suppressions": [
{
"provider": "azure-openai-responses",
"model": "gpt-5.3-codex-spark",
"reason": "not available on Azure OpenAI Responses"
}
],
"discovery": {
"openai": "static"
}
}
}discovery 字段使用 "static"、"refreshable" 或 "runtime" 指示目录如何获取。不要将运行时数据放入 modelCatalog。
modelIdNormalization 参考
用于 provider 拥有的模型 id 清理,必须在 provider runtime 加载前执行。
json
{
"providers": ["anthropic", "openrouter"],
"modelIdNormalization": {
"providers": {
"anthropic": {
"aliases": {
"sonnet-4.6": "claude-sonnet-4-6"
}
},
"openrouter": {
"prefixWhenBare": "openrouter"
}
}
}
}Provider 字段包括 aliases(不区分大小写的精确模型 id 别名)、stripPrefixes(在别名查找前去除的前缀)和 prefixWhenBare(当规范化模型 id 不包含 / 时添加的前缀)等。
providerEndpoints 参考
用于通用请求策略在 provider runtime 加载前必须知道的端点分类。核心仍拥有每个 endpointClass 的含义;插件 manifest 拥有 host 和 base URL 元数据。
端点字段:endpointClass、hosts、hostSuffixes、baseUrls、googleVertexRegion、googleVertexRegionHostSuffix。
providerRequest 参考
用于通用请求策略需要的轻量请求兼容性元数据。保持行为特定的有效负载重写在 provider runtime hooks 或共享的 provider 家族帮助器中。
Provider 字段:family、compatibilityFamily、openAICompletions。
modelPricing 参考
用于需要对 model pricing 进行控制平面行为的 provider,例如本地/自托管 provider 设置 external: false 阻止 OpenRouter/LiteLLM 定价查找。
json
{
"providers": ["ollama", "openrouter"],
"modelPricing": {
"providers": {
"ollama": {
"external": false
},
"openrouter": {
"openRouter": {
"passthroughProviderModel": true
},
"liteLLM": false
}
}
}
}Provider 字段:external(false 禁用外部定价)、openRouter、liteLLM。源字段包括 provider、passthroughProviderModel、modelIdTransforms。
Manifest 与 package.json 的职责划分
| 文件 | 用途 |
|---|---|
openclaw.plugin.json | 插件代码运行前的发现、配置校验、认证选项元数据和 UI 提示 |
package.json | npm 元数据、依赖安装、入口点声明、安装门控、设置或目录元数据 |
判断规则:插件代码运行前 OpenClaw 必须知道的 → 放 manifest;关于打包、入口文件或 npm 安装行为的 → 放 package.json。
package.json 下 openclaw 块中的关键发现字段(只列出常用项,完整列表见原文):
| package.json 字段 | 说明 |
|---|---|
openclaw.extensions | 声明原生插件入口点,必须在插件包目录内 |
openclaw.setupEntry | 轻量设置入口点,用于引导、延迟渠道启动、只读渠道状态/SecretRef 发现 |
openclaw.channel | 廉价渠道目录元数据,如标签、文档路径、别名、选择文本 |
openclaw.channel.commands | 静态原生命令和原生技能自动默认元数据 |
openclaw.install.npmSpec / openclaw.install.clawhubSpec | 安装/更新提示 |
详细字段说明请参见原文的“package.json fields that affect discovery”部分。
发现优先级(重复插件 id)
OpenClaw 从多个根发现插件。如果两个发现共享相同的 id,只有最高优先级的 manifest 会保留,低优先级的副本会被丢弃。优先级从高到低:
- 配置选择 - 在
plugins.entries.<id>中显式固定的路径 - 内置 - 随 OpenClaw 发布的插件
- 全局安装 - 安装在全局 OpenClaw 插件根目录的插件
- 工作区 - 从当前工作区发现的插件
JSON Schema 要求
- 每个插件必须附带 JSON Schema,即使不接受任何配置
- 空 schema 合法(例如
{ "type": "object", "additionalProperties": false }) - Schema 在配置读写时验证,不在运行时验证
- 扩展或复刻内置插件时,必须同步更新
configSchema
验证行为
- 未声明渠道 id 的
channels.*键报错 plugins.entries.<id>、plugins.allow、plugins.deny、plugins.slots.*必须引用可发现的插件 id,未知项报错- 插件 manifest 缺失或损坏时,验证失败,Doctor 报告插件错误
- 插件配置存在但插件已禁用时,Doctor 和日志显示警告
注意事项
- Manifest 对原生插件必需,包括本地文件系统加载。Runtime 单独加载插件模块,manifest 仅用于发现和验证
- 原生 manifest 使用 JSON5 解析,支持注释、尾逗号、未引号的键
- 只读取文档化的 manifest 字段。避免自定义顶级键
channels、providers、cliBackends、skills可在不需要时忽略providerCatalogEntry必须保持轻量,不应导入广泛 runtime 代码- 独占插件类型(
memory/context-engine)通过plugins.slots.*选择 - 环境变量元数据(
setup.providers[].envVars、废弃的providerAuthEnvVars、channelEnvVars)仅声明性。读状态面仍应用插件信任和有效激活策略 - 旧版顶级能力键(
speechProviders等)已废弃,使用openclaw doctor --fix移入contracts
相关文档
常见问题
manifest 中的 configSchema 必须包含所有配置字段吗?
是。OpenClaw 以 manifest 中 configSchema 为准进行配置校验。如果某个字段在用户配置中存在但 schema 未声明,且 additionalProperties 为 false,就会报错。建议将所有插件配置字段都声明在 schema 的 properties 中。
插件 manifest 缺失或损坏时会出现什么表现?
配置验证失败,OpenClaw 会阻止启动。运行 openclaw doctor 可以查看详细的插件错误报告。最常见的错误是缺少 openclaw.plugin.json 文件、JSON 格式错误或必填字段(如 id、configSchema)缺失。
如何让插件在启动时自动启用?
在 manifest 中设置 "enabledByDefault": true(仅对内置插件有效)。对于非内置插件,需要在用户配置的 plugins.entries.<id> 中显式启用。另外,使用 activation.onStartup: true 可以让插件在 Gateway 启动时加载(无论是否内置)。注意,enabledByDefault 控制默认启用状态,而 activation.onStartup 控制启动时是否加载代码。