Plugin SDK reference
Plugin manifest
This page covers the native OpenClaw plugin manifest, openclaw.plugin.json. For compatible bundle layouts (Agent Plugins, Codex, Claude, Cursor), see Plugin bundles.
Compatible bundle formats use their own manifest files instead:
- Agent Plugins bundle:
plugin.jsonat the package root, per the open Agent Plugins standard - Codex bundle:
.codex-plugin/plugin.json - Claude bundle:
.claude-plugin/plugin.json, or the default Claude component layout with no manifest - Cursor bundle:
.cursor-plugin/plugin.json
OpenClaw auto-detects those layouts but does not validate them against the openclaw.plugin.json schema below. For a compatible bundle, OpenClaw reads bundle metadata, declared skill roots, Claude command roots, Claude settings.json defaults, Claude LSP defaults, and supported hook packs, when the layout matches OpenClaw's runtime expectations.
Every native OpenClaw plugin must ship openclaw.plugin.json in the plugin root. OpenClaw reads it to validate configuration without executing plugin code. A missing or invalid manifest blocks config validation and is treated as a plugin error.
See Plugins for the full plugin system guide, and Capability model for the native capability model and current external-compatibility guidance.
What this file does
openclaw.plugin.json is metadata OpenClaw reads before loading your plugin code. Everything in it must be cheap enough to inspect without booting plugin runtime.
Use it for:
- plugin identity, config validation, and config UI hints
- auth, onboarding, and setup metadata (alias, auto-enable, provider env vars, auth choices)
- activation hints for control-plane surfaces
- root CLI command names, descriptions, and subcommand markers (
cliCommands) - shorthand model-family ownership
- static capability-ownership snapshots (
contracts) - dashboard widget data bindings and action verbs
- static MCP servers that should exist while the plugin is enabled
- durable and regenerable state- or agent-relative backup resources
- QA runner metadata the shared
openclaw qahost can inspect - channel-specific config metadata merged into catalog and validation surfaces
Do not use it for: registering native runtime hooks, declaring the full plugin runtime entrypoint, or npm install metadata. Those belong in your plugin code and package.json.
Where each field is documented
Every manifest field is documented on this page or on one of the seven child pages below. The anchors from the single-page version still resolve here.
Model fields
Manifest model fields — Manifest model catalog, shorthand family, id normalization, and pricing fields.
Provider fields
Manifest provider fields — Manifest generation, media-understanding, endpoint, and request provider metadata.
imageGenerationProviderMetadata,videoGenerationProviderMetadata,musicGenerationProviderMetadatamediaUnderstandingProviderMetadataproviderEndpointsproviderRequest
Setup and auth fields
Manifest setup and auth fields — Manifest setup descriptors, auth choices, conversation discovery, and config UI hints.
setup.nativeSessionCatalogproviderAuthChoicessetup,providerUsageAuthEnvVarssetup.providerssetupfield tableuiHints
Capability fields
Manifest capability fields — Manifest capability ownership, tool availability metadata, and activation planning.
Host surface fields
Manifest host surface fields — Manifest fields for icons, CLI, MCP, Control UI, dashboard, QA, channel, and backup surfaces.
- Plugin icon,
doctorContract,doctorHealthChecks,sessionRouteStateOwners transcriptSourcesbackupResourcesmcpServerscontrolUidashboardcatalogcliCommandscommandAliasesqaRunnerschannelConfigschannelConfigs.<id>.preferOver
Config and secret fields
Manifest config and secret fields — Manifest dangerous-flag, SecretRef migration, and secret provider preset metadata.
Manifest and package.json fields
Manifest versus package.json — Which pre-runtime metadata lives in package.json, and which duplicate plugin id wins.
Minimal example
{ "id": "voice-call", "configSchema": { "type": "object", "additionalProperties": false, "properties": {} }}Rich example
{ "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"], "setup": { "providers": [ { "id": "openrouter", "envVars": ["OPENROUTER_API_KEY"] } ] }, "providerAuthAliases": { "openrouter-coding": "openrouter" }, "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" } } }}Top-level field reference
| Field | Required | Type | What it means |
|---|---|---|---|
id |
Yes | string |
Canonical plugin id. This is the id used in plugins.entries.<id>. Exception: a package whose package.json declares multiple plugin entries registers each entry as <id>/<entry-basename> (for example pack/one), and that entry-scoped id is the plugins.entries key for that entry. Entry basenames must be unique within the package; colliding basenames are rejected at discovery. |
configSchema |
Yes | object |
Inline JSON Schema for this plugin's config. |
requiresPlugins |
No | string[] |
Plugin ids that must also be installed for this plugin to have an effect. Discovery keeps the plugin loadable but warns when any required plugin is missing. |
enabledByDefault |
No | true |
Marks a bundled plugin as enabled by default. Omit it, or set any non-true value, to leave the plugin disabled by default. |
enabledByDefaultOnPlatforms |
No | string[] |
Marks a bundled plugin as enabled by default only on the listed Node.js platforms, for example ["darwin"]. Explicit config still wins. |
legacyPluginIds |
No | string[] |
Legacy ids that normalize to this canonical plugin id. |
autoEnableWhenConfiguredProviders |
No | string[] |
Provider ids that should auto-enable this plugin when auth, config, or model refs mention them. |
kind |
No | PluginKind | PluginKind[] |
Declares one or more exclusive plugin kinds ("memory", "context-engine") used by plugins.slots.*. A plugin that owns both slots declares both kinds in one array. |
channels |
No | string[] |
Channel ids owned by this plugin. Used for discovery and config validation. |
providers |
No | string[] |
Provider ids owned by this plugin. |
providerCatalogEntry |
No | string |
Lightweight provider-catalog module path, relative to the plugin root, for manifest-scoped provider catalog metadata that can be loaded without activating the full plugin runtime. |
capabilityCatalogEntry |
No | string |
Lightweight module of typed speech, realtime transcription, and realtime voice provider descriptors, relative to the plugin root. See Capability catalogs. |
modelSupport |
No | object |
Manifest-owned shorthand model-family metadata used to auto-load the plugin before runtime. |
modelCatalog |
No | object |
Declarative model catalog metadata for providers owned by this plugin. This is the control-plane contract for future read-only listing, onboarding, model pickers, aliases, and suppression without loading plugin runtime. |
modelPricing |
No | object |
Provider-owned hosted-pricing publication policy. Use it to opt local/self-hosted providers out of published pricing or map provider refs to supported public pricing catalogs without hardcoding provider ids in core. |
modelIdNormalization |
No | object |
Provider-owned model-id alias/prefix cleanup that must run before provider runtime loads. |
providerEndpoints |
No | object[] |
Manifest-owned endpoint host/baseUrl metadata for provider routes that core must classify before provider runtime loads. |
providerRequest |
No | object |
Cheap provider-family and request-compatibility metadata used by generic request policy before provider runtime loads. |
secretProviderIntegrations |
No | Record<string, object> |
Declarative SecretRef exec provider presets that setup or install surfaces can offer without hardcoding provider-specific integrations in core. |
cliBackends |
No | string[] |
CLI inference backend ids owned by this plugin. Used for startup auto-activation from explicit config refs. |
syntheticAuthRefs |
No | string[] |
Provider or CLI backend refs whose plugin-owned synthetic auth hook should be probed during cold model discovery before runtime loads. |
nonSecretAuthMarkers |
No | string[] |
Bundled-plugin-owned placeholder API key values that represent non-secret local, OAuth, or ambient credential state. |
commandAliases |
No | object[] |
Command names owned by this plugin that should produce plugin-aware config and CLI diagnostics before runtime loads. |
cliCommands |
No | object[] |
Root CLI commands shown in openclaw --help before plugin code loads. Each row requires name, description, and hasSubcommands. |
providerUsageAuthEnvVars |
No | Record<string, string[]> |
Usage/billing-only provider credentials. OpenClaw uses these names for usage discovery and secret scrubbing but never for inference auth. |
providerAuthAliases |
No | Record<string, AuthAlias> |
Provider ids that reuse another provider for auth lookup. A baseUrls condition applies only when that provider's configured endpoint matches; stored credentials retain their provider identity. |
providerAuthChoices |
No | object[] |
Cheap auth-choice metadata for onboarding pickers, preferred-provider resolution, and simple CLI flag wiring. |
activation |
No | object |
Cheap activation planner metadata for startup, provider, command, channel, route, and capability-triggered loading. Metadata only; plugin runtime still owns actual behavior. |
backupResources |
No | object[] |
Manifest-owned durable or regenerable state- or agent-relative backup resources. Applied only for effectively activated, loadable plugins without executing their runtime. See backupResources reference. |
setup |
No | object |
Cheap setup/onboarding descriptors that discovery and setup surfaces can inspect without loading plugin runtime. |
doctorContract |
No | object |
Declares which dynamic doctor-contract surfaces the plugin artifact exports so doctor loads only relevant modules. |
doctorHealthChecks |
No | boolean |
Declares health-check registration in the selected plugin's public API. Read by the Codex doctor health API. |
sessionRouteStateOwners |
No | object[] |
Static session-route ownership for doctor cleanup. Each entry declares an id, label, and optional providerIds, runtimeIds, cliSessionKeys, and authProfilePrefixes. |
qaRunners |
No | object[] |
Cheap QA runner descriptors used by the shared openclaw qa host before plugin runtime loads. |
dashboard |
No | object |
Dashboard widget data bindings and action verbs. Each entry is validated against a Gateway method registered by this plugin with the required read or write scope. See dashboard reference. |
mcpServers |
No | Record<string, object> |
Static MCP server definitions contributed while this plugin is enabled. Relative command arguments and working directories resolve from the plugin root. Operator mcp.servers entries override or disable definitions with the same name. See MCP server reference. |
contracts |
No | object |
Static capability ownership snapshot for external auth hooks, embeddings, speech, realtime transcription, realtime voice, media-understanding, image/video/music generation, web fetch, web search, worker providers, document/web-content extraction, and tool ownership. |
transcriptSources |
No | Record<string, object> |
Static transcript source names and auto-start locator requirements for IDs declared in contracts.transcriptSourceProviders. See Transcript sources reference. |
configContracts |
No | object |
Manifest-owned config behavior consumed by generic core helpers: dangerous-flag detection, SecretRef migration targets, and legacy config-path narrowing. See configContracts reference. |
mediaUnderstandingProviderMetadata |
No | Record<string, object> |
Cheap media-understanding defaults for provider ids declared in contracts.mediaUnderstandingProviders. |
imageGenerationProviderMetadata |
No | Record<string, object> |
Cheap image-generation auth metadata for provider ids declared in contracts.imageGenerationProviders, including provider-owned auth aliases and base-url guards. |
videoGenerationProviderMetadata |
No | Record<string, object> |
Cheap video-generation auth metadata for provider ids declared in contracts.videoGenerationProviders, including provider-owned auth aliases and base-url guards. |
musicGenerationProviderMetadata |
No | Record<string, object> |
Cheap music-generation auth metadata for provider ids declared in contracts.musicGenerationProviders, including provider-owned auth aliases and base-url guards. |
toolMetadata |
No | Record<string, object> |
Cheap availability metadata for plugin-owned tools declared in contracts.tools. Use it when a tool should not load runtime unless config, env, or auth evidence exists. |
channelConfigs |
No | Record<string, object> |
Manifest-owned channel config metadata merged into discovery and validation surfaces before runtime loads. |
skills |
No | string[] |
Skill directories to load, relative to the plugin root. |
name |
No | string |
Human-readable plugin name. |
description |
No | string |
Short summary shown in plugin surfaces. |
catalog |
No | object |
Optional presentation hints for plugin catalog surfaces. This metadata does not install, enable, or grant trust to a plugin. |
categories |
No | string[] |
One to three controlled catalog category slugs, ordered with the primary category first. Bundled plugins must declare exactly one active category. |
version |
No | string |
Informational plugin version. |
uiHints |
No | Record<string, object> |
UI labels, placeholders, and sensitivity hints for config fields. |
An AuthAlias is either a provider id string or an object with provider and
baseUrls. An object alias applies only to the configured model-provider
endpoint after trimming whitespace and trailing slashes. It does not rename
stored credential providers or contribute a new setup provider. Existing profile
order, explicit bindings, and plugin trust checks still apply.
Catalog categories
Choose the one category that best describes why someone would install the plugin.
Use its main user purpose, not every tool, provider, or runtime capability it exposes.
For example, an agent execution backend belongs in agent-runtimes, document extraction
belongs in documents-files, and a messaging adapter belongs in channels even when
it also provides workspace tools.
Bundled OpenClaw plugins declare exactly one active category. New ClawHub publications also accept exactly one declared category, using the same array shape, or omit the field for ClawHub to generate a category.
OpenClaw's manifest reader continues to accept one to three unique, ordered categories so previously installed and published packages remain readable. When reading older multiple-category declarations, the first remains primary and all remain searchable. The stricter new-publication rule does not invalidate an installed plugin's manifest.
The active categories below are listed in browse order:
| Slug | Use for |
|---|---|
channels |
Human-agent messaging transports and channel adapters. Choose this when the main purpose is letting people talk to the agent through a messaging service, even if the adapter also exposes workspace tools. |
models |
General model providers, inference backends, and model routing. Agent execution engines belong in Agent runtimes; specialized speech or media generators belong in Voice or Media when that is their main purpose. |
agent-runtimes |
Agent execution engines and backends that run model/tool loops and manage native sessions, including Codex, ACP, and Copilot runtimes. Context assembly belongs in Context; coordinating work across agents belongs in Agent orchestration. |
memory |
Durable agent memory, embeddings, and retrieval across conversations. Building or compacting the active conversation context belongs in Context. |
context |
Building, selecting, compacting, or managing the active conversation context. Durable memory belongs in Memory; an engine that runs the agent and owns its native sessions belongs in Agent runtimes. |
voice |
Speech synthesis, transcription, voice calls, and spoken interaction. Music and general media creation or analysis belong in Media. |
web |
General web search, browser control, and fetching web pages. A tool whose main purpose is a specific research or business workflow belongs in that workflow's category. |
media |
Creating, transforming, or understanding images, video, music, and other media. Spoken interaction and transcription belong in Voice. |
security |
Protecting access and enforcing trust through authentication, authorization, credential controls, security auditing, or policy. Authentication incidental to another purpose does not belong here. |
integrations |
General connectors, API bridges, and service integration platforms without a more specific user purpose. A connector to a particular workflow belongs in that workflow's category; exposing tools or MCP is not enough. |
developer-tools |
Writing, reviewing, testing, and debugging software, development environments, and coding workflows. Plugins whose main purpose is providing the agent execution engine belong in Agent runtimes. |
infrastructure |
Deploying, hosting, monitoring, and operating systems, networks, services, and execution environments. Engines that run the agent loop belong in Agent runtimes; coordinating agents belongs in Agent orchestration. |
documents-files |
Reading, creating, extracting, transferring, and managing documents and files. Software code review belongs in Developer tools; task and project management belongs in Productivity. |
inbox-collaboration |
Managing email, inboxes, team communication, and collaborative workspaces. Providing a transport for people to talk to the agent belongs in Channels. |
productivity |
Managing tasks, notes, projects, plans, and personal or team work. Appointments and availability belong in Scheduling; document processing belongs in Documents & files. |
scheduling |
Calendars, appointments, availability, and booking. Technical job scheduling belongs with the workflow it supports, or Infrastructure for general system scheduling. |
finance-payments |
Payments, billing, accounting, banking, trading, and financial workflows. General business reporting belongs in Data & analytics. |
sales-marketing |
Customer relationships, sales, customer support, outreach, campaigns, and marketing operations. General email or chat management belongs in Inbox & collaboration. |
data-analytics |
Querying databases, processing datasets, analysis, reporting, and business intelligence. Agent memory storage belongs in Memory; operational telemetry belongs in Infrastructure. |
agent-orchestration |
Coordinating agents, delegating work, and running multi-step agent workflows. Engines and backends that execute the agent loop and manage its native sessions belong in Agent runtimes. |
research |
Investigating topics, evaluating sources, working with scientific literature, and synthesizing evidence. General web search, browsing, and page fetching belong in Web. |
other |
Use only when the plugin's main purpose does not fit another category or the available evidence is insufficient. Do not use this just because a plugin has several capabilities. |
Legacy tools, runtime, and gateway declarations remain valid so existing
packages keep loading. They are retired from the active browse taxonomy. Choose
active categories for new declarations; legacy values are not automatically
translated into a different category.
Omission remains valid for external plugin compatibility. When an external catalog supplies a derived fallback, an explicit package declaration takes precedence. Bundled OpenClaw plugins must declare exactly one active category.
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 }). - Config is validated against the manifest schema at config read/write time and before the plugin loads.
- When extending or forking a bundled plugin with new config keys, update that plugin's
openclaw.plugin.jsonconfigSchemaat the same time. Bundled plugin schemas are strict, so addingplugins.entries.<id>.config.myNewKeyin user config without addingmyNewKeytoconfigSchema.propertieswill be rejected before the plugin runtime loads.
Example schema extension:
{ "configSchema": { "type": "object", "additionalProperties": false, "properties": { "myNewKey": { "type": "string" } } }}Validation behavior
Capability catalogs
capabilityCatalogEntry declares a lightweight module relative to the selected
plugin root, for example "./capability-catalog.ts". It exports actual speech,
realtime transcription, or realtime voice provider descriptors without importing
the full plugin entry. See the typed SDK contract.
Each supplied family is authoritative, including an empty array. An omitted
family, or a plugin without this declaration, retains the existing register()
discovery contract for installed plugins. A malformed, missing, or broken declared
entry fails with a repair diagnostic; it does not fall through to full registration.
Already registered runtime providers remain authoritative, including live broker
and readiness closures.
The entry uses the same plugin-root boundary checks, installed-owner precedence, prepared metadata generation, and source/built artifact policy as other plugin surfaces. Repository builds include declared entries and rewrite emitted manifest paths to the corresponding JavaScript artifacts. Plugin reload owns invalidation; catalog requests do not poll files for changes.
Configuration validation
- Required-field errors identify every missing field after schema defaults are applied. For dependencies on multiple fields, the error reports the dependency condition without claiming that fields already present are missing.
- Unknown
channels.*keys are errors, unless the channel id is declared by a plugin manifest. If the same id also appears inplugins.allow,plugins.entries, orplugins.installs(a plugin that is referenced but not currently discoverable), OpenClaw downgrades this to a warning instead. plugins.entries.<id>,plugins.allow, andplugins.denyreferencing unknown plugin ids are warnings ("stale config entry ignored"), not errors, so upgrades and removed/renamed plugins do not block gateway startup. An exact{ enabled: false }plugin entry is an intentional uninstall marker, so validation and Doctor keep it without a stale-config warning.plugins.slots.memoryreferencing an unknown plugin id is an error, except for the knownmemory-lancedbofficial external plugin, which warns instead.- 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.
See Configuration reference for the full plugins.* schema.
Notes
- The manifest is required for native OpenClaw plugins, including local filesystem loads. Runtime still loads the plugin module separately; the manifest is only for discovery + validation.
- Native manifests are parsed with JSON5, so comments, trailing commas, and unquoted keys are accepted as long as the final value is still an object.
- Only documented manifest fields are read by the manifest loader. Avoid custom top-level keys.
channels,providers,cliBackends, andskillscan all be omitted when a plugin does not need them.providerCatalogEntrymust stay lightweight and should not import broad runtime code; use it for static provider catalog metadata or narrow discovery descriptors, not request-time execution.- Exclusive plugin kinds are selected through
plugins.slots.*:kind: "memory"viaplugins.slots.memory(defaultmemory-core),kind: "context-engine"viaplugins.slots.contextEngine(defaultlegacy). - Declare exclusive plugin kind in this manifest. Bundled plugins use manifest kinds without loading their runtime during enablement. Runtime-entry
OpenClawPluginDefinition.kindwas deprecated on 2026-07-25 and remains only as a compatibility fallback for older external plugins; its removal gate is 2026-10-01. See the compatibility policy. - Env-var metadata in
setup.providers[].envVarsis declarative only. Status, audit, cron delivery validation, and other read-only surfaces still apply plugin trust and effective activation policy before treating an env var as configured. - For runtime wizard metadata that requires provider code, see Provider runtime hooks.
- If your plugin depends on native modules, document the build steps and any package-manager allowlist requirements (for example, pnpm
allow-build-scripts+pnpm rebuild <package>).
Related
Getting started with plugins.
Internal architecture and capability model.
Plugin SDK reference and subpath imports.
Manifest model catalog, shorthand family, id normalization, and pricing fields.
Manifest generation, media-understanding, endpoint, and request provider metadata.
Manifest setup descriptors, auth choices, conversation discovery, and config UI hints.
Manifest capability ownership, tool availability metadata, and activation planning.
Manifest fields for icons, CLI, MCP, Control UI, dashboard, QA, channel, and backup surfaces.
Manifest dangerous-flag, SecretRef migration, and secret provider preset metadata.
Which pre-runtime metadata lives in package.json, and which duplicate plugin id wins.
Packaging and config schemas that consume this manifest.
definePluginEntry and the other entry helpers a plugin's code exports.
Declaring contracts.tools for agent tools.
Installing and enabling the plugins this manifest describes.
The backupResources surface declared here.