Plugin manifest (openclaw.plugin.json)
Every plugin must ship a openclaw.plugin.json file in the plugin root.
OpenClaw uses this manifest to validate configuration without executing plugin
code. Missing or invalid manifests are treated as plugin errors and block
config validation.
See the plugin authoring guide: Write your first plugin.
Required fields
Required keys:
id (string): canonical plugin id.
configSchema (object): JSON Schema for plugin config (inline).
Optional keys:
kind (string): plugin kind (example: "memory").
channels (array): channel ids registered by this plugin (example: ["matrix"]).
providers (array): provider ids registered by this plugin.
skills (array): skill directories to load (relative to the plugin root).
name (string): display name for the plugin.
description (string): short plugin summary.
uiHints (object): config field labels/placeholders/sensitive flags for UI rendering.
version (string): plugin version (informational).
sessionConsumers (array): declares session-end consumers for the claim/ack pipeline.
Each entry has effectKind (string, default "session.end"), subCursors (array,
max 8, each ^[a-z][a-z0-9-]*$), consumeScopes (array, authz scopes), and
consumeLanes (array, lane scopes). See
Session Consumer Claims for the full SDK surface.
JSON Schema requirements
- Every plugin must ship a JSON Schema, even if it accepts no config.
- An empty schema is acceptable (for example,
{ "type": "object", "additionalProperties": false }).
- Schemas are validated at config read/write time, not at runtime.
Validation behavior
- Unknown
channels.* keys are errors, unless the channel id is declared by
a plugin manifest.
plugins.entries.<id>, plugins.allow, plugins.deny, and plugins.slots.*
must reference discoverable plugin ids. Unknown ids are errors.
- If a plugin is installed but has a broken or missing manifest or schema,
validation fails and Doctor reports the plugin error.
- If plugin config exists but the plugin is disabled, the config is kept and
a warning is surfaced in Doctor + logs.
Run openclaw plugins doctor to see manifest, schema, and config issues across all
discovered plugins.
Notes
- The manifest is required for all plugins, including local filesystem loads.
- The manifest carries no dependency information: bundled extensions carry no
openclaw
peer dependency (ADR 0005), and third-party plugins target our published SemVer. See
Plugin SDK — Installation for the package.json pattern.
- Runtime still loads the plugin module separately; the manifest is only for
discovery + validation.
- If your plugin depends on native modules, document the build steps and any
package-manager allowlist requirements (for example, pnpm
allow-build-scripts
sessionConsumers
Declares that this plugin consumes ended-session work. Each entry keys a durable claim stream: effectKind (required, unique per plugin), optional subCursors (max 8), consumeScopes, consumeLanes, and enabled (default true). Entries are validated at manifest load — non-array shapes, invalid effectKind patterns, or duplicate effectKinds are plugin errors.
At runtime, api.claimSessionWork() / api.ackSessionWork() gate the queue: the consumerId is loader-bound to your manifest declaration (never caller-supplied), and claims outside your declared scopes or lanes are skipped, never leased. Declared consumers also obligation-gate session pruning — the session store will not prune sessions with non-terminal claims from your plugin.
See Session consumer claims for the full contract, lease semantics, and diagnostics events.
Where config lands
Users set plugin config under the plugin’s id. Inside register, it arrives as api.pluginConfig (Record<string, unknown> | undefined). Always handle a missing or partial config gracefully.
What’s next