Caricamento in corso...
Caricamento in corso...
Last synced: Today, 22:00
Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.
Use this file to discover all available pages before exploring further.
This page is for the native OpenClaw plugin manifest only.
For compatible bundle layouts, see Plugin bundles.
Compatible bundle formats use different manifest files:
.codex-plugin/plugin.json.claude-plugin/plugin.json.cursor-plugin/plugin.jsonOpenClaw auto-detects those bundle layouts too, but they are not validated against the
openclaw.plugin.jsonFor compatible bundles, OpenClaw currently reads bundle metadata plus declared skill roots, Claude command roots, Claude bundle
settings.jsonEvery native OpenClaw plugin must ship a
openclaw.plugin.jsonSee the full plugin system guide: Plugins. For the native capability model and current external-compatibility guidance: Capability model.
openclaw.plugin.jsonUse it for:
contractsopenclaw qaDo not use it for: registering runtime behavior, declaring code entrypoints, or npm install metadata. Those belong in your plugin code and
package.jsonjson{ "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" } } } }
| Field | Required | Type | What it means |
|---|---|---|---|
text id | Yes | text string | Canonical plugin id. This is the id used in text plugins.entries.<id> |
text configSchema | Yes | text object | Inline JSON Schema for this plugin's config. |
text enabledByDefault | No | text true | Marks a bundled plugin as enabled by default. Omit it, or set any non- text true |
text legacyPluginIds | No | text string[] | Legacy ids that normalize to this canonical plugin id. |
text autoEnableWhenConfiguredProviders | No | text string[] | Provider ids that should auto-enable this plugin when auth, config, or model refs mention them. |
text kind | No | text "memory"text "context-engine" | Declares an exclusive plugin kind used by text plugins.slots.* |
text channels | No | text string[] | Channel ids owned by this plugin. Used for discovery and config validation. |
text providers | No | text string[] | Provider ids owned by this plugin. |
text providerDiscoveryEntry | No | text string | Lightweight provider-discovery module path, relative to the plugin root, for manifest-scoped provider catalog metadata that can be loaded without activating the full plugin runtime. |
text modelSupport | No | text object | Manifest-owned shorthand model-family metadata used to auto-load the plugin before runtime. |
text modelCatalog | No | text 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. |
text modelPricing | No | text object | Provider-owned external pricing lookup policy. Use it to opt local/self-hosted providers out of remote pricing catalogs or map provider refs to OpenRouter/LiteLLM catalog ids without hardcoding provider ids in core. |
text modelIdNormalization | No | text object | Provider-owned model-id alias/prefix cleanup that must run before provider runtime loads. |
text providerEndpoints | No | text object[] | Manifest-owned endpoint host/baseUrl metadata for provider routes that core must classify before provider runtime loads. |
text providerRequest | No | text object | Cheap provider-family and request-compatibility metadata used by generic request policy before provider runtime loads. |
text cliBackends | No | text string[] | CLI inference backend ids owned by this plugin. Used for startup auto-activation from explicit config refs. |
text syntheticAuthRefs | No | text string[] | Provider or CLI backend refs whose plugin-owned synthetic auth hook should be probed during cold model discovery before runtime loads. |
text nonSecretAuthMarkers | No | text string[] | Bundled-plugin-owned placeholder API key values that represent non-secret local, OAuth, or ambient credential state. |
text commandAliases | No | text object[] | Command names owned by this plugin that should produce plugin-aware config and CLI diagnostics before runtime loads. |
text providerAuthEnvVars | No | text Record<string, string[]> | Deprecated compatibility env metadata for provider auth/status lookup. Prefer text setup.providers[].envVars |
text providerAuthAliases | No | text Record<string, string> | Provider ids that should reuse another provider id for auth lookup, for example a coding provider that shares the base provider API key and auth profiles. |
text channelEnvVars | No | text Record<string, string[]> | Cheap channel env metadata that OpenClaw can inspect without loading plugin code. Use this for env-driven channel setup or auth surfaces that generic startup/config helpers should see. |
text providerAuthChoices | No | text object[] | Cheap auth-choice metadata for onboarding pickers, preferred-provider resolution, and simple CLI flag wiring. |
text activation | No | text object | Cheap activation planner metadata for startup, provider, command, channel, route, and capability-triggered loading. Metadata only; plugin runtime still owns actual behavior. |
text setup | No | text object | Cheap setup/onboarding descriptors that discovery and setup surfaces can inspect without loading plugin runtime. |
text qaRunners | No | text object[] | Cheap QA runner descriptors used by the shared text openclaw qa |
text contracts | No | text object | Static bundled capability snapshot for external auth hooks, speech, realtime transcription, realtime voice, media-understanding, image-generation, music-generation, video-generation, web-fetch, web search, and tool ownership. |
text mediaUnderstandingProviderMetadata | No | text Record<string, object> | Cheap media-understanding defaults for provider ids declared in text contracts.mediaUnderstandingProviders |
text channelConfigs | No | text Record<string, object> | Manifest-owned channel config metadata merged into discovery and validation surfaces before runtime loads. |
text skills | No | text string[] | Skill directories to load, relative to the plugin root. |
text name | No | text string | Human-readable plugin name. |
text description | No | text string | Short summary shown in plugin surfaces. |
text version | No | text string | Informational plugin version. |
text uiHints | No | text Record<string, object> | UI labels, placeholders, and sensitivity hints for config fields. |
Each
providerAuthChoices| Field | Required | Type | What it means |
|---|---|---|---|
text provider | Yes | text string | Provider id this choice belongs to. |
text method | Yes | text string | Auth method id to dispatch to. |
text choiceId | Yes | text string | Stable auth-choice id used by onboarding and CLI flows. |
text choiceLabel | No | text string | User-facing label. If omitted, OpenClaw falls back to text choiceId |
text choiceHint | No | text string | Short helper text for the picker. |
text assistantPriority | No | text number | Lower values sort earlier in assistant-driven interactive pickers. |
text assistantVisibility | No | text "visible"text "manual-only" | Hide the choice from assistant pickers while still allowing manual CLI selection. |
text deprecatedChoiceIds | No | text string[] | Legacy choice ids that should redirect users to this replacement choice. |
text groupId | No | text string | Optional group id for grouping related choices. |
text groupLabel | No | text string | User-facing label for that group. |
text groupHint | No | text string | Short helper text for the group. |
text optionKey | No | text string | Internal option key for simple one-flag auth flows. |
text cliFlag | No | text string | CLI flag name, such as text --openrouter-api-key |
text cliOption | No | text string | Full CLI option shape, such as text --openrouter-api-key <key> |
text cliDescription | No | text string | Description used in CLI help. |
text onboardingScopes | No | text Array<"text-inference" | "image-generation"> | Which onboarding surfaces this choice should appear in. If omitted, it defaults to text ["text-inference"] |
Use
commandAliasesplugins.allowjson{ "commandAliases": [ { "name": "dreaming", "kind": "runtime-slash", "cliCommand": "memory" } ] }
| Field | Required | Type | What it means |
|---|---|---|---|
text name | Yes | text string | Command name that belongs to this plugin. |
text kind | No | text "runtime-slash" | Marks the alias as a chat slash command rather than a root CLI command. |
text cliCommand | No | text string | Related root CLI command to suggest for CLI operations, if one exists. |
Use
activationThis block is planner metadata, not a lifecycle API. It does not register runtime behavior, does not replace
register(...)providerschannelscommandAliasessetup.providerscontracts.toolsPrefer the narrowest metadata that already describes ownership. Use
providerschannelscommandAliasescontractsactivationcliBackendsclaude-clicodex-cligoogle-gemini-cliactivation.onAgentHarnessesThis block is metadata only. It does not register runtime behavior, and it does not replace
register(...)setupEntryEvery plugin should set
activation.onStartuptruefalseonStartupactivation.onStartup: truelegacy-implicit-startup-sidecarFor migration testing, set
OPENCLAW_DISABLE_LEGACY_IMPLICIT_STARTUP_SIDECARS=1activation.onStartup: truejson{ "activation": { "onStartup": false, "onProviders": ["openai"], "onCommands": ["models"], "onChannels": ["web"], "onRoutes": ["gateway-webhook"], "onConfigPaths": ["browser"], "onCapabilities": ["provider", "tool"] } }
| Field | Required | Type | What it means |
|---|---|---|---|
text onStartup | No | text boolean | Explicit Gateway startup activation. Every plugin should set this. text truetext false |
text onProviders | No | text string[] | Provider ids that should include this plugin in activation/load plans. |
text onAgentHarnesses | No | text string[] | Embedded agent harness runtime ids that should include this plugin in activation/load plans. Use top-level text cliBackends |
text onCommands | No | text string[] | Command ids that should include this plugin in activation/load plans. |
text onChannels | No | text string[] | Channel ids that should include this plugin in activation/load plans. |
text onRoutes | No | text string[] | Route kinds that should include this plugin in activation/load plans. |
text onConfigPaths | No | text string[] | Root-relative config paths that should include this plugin in startup/load plans when the path is present and not explicitly disabled. |
text onCapabilities | No | text Array<"provider" | "channel" | "tool" | "hook"> | Broad capability hints used by control-plane activation planning. Prefer narrower fields when possible. |
Current live consumers:
activation.onStartupcommandAliases[].cliCommandcommandAliases[].nameactivation.onAgentHarnessescliBackends[]channels[]activation.onConfigPathsbrowserproviders[]cliBackends[]Planner diagnostics can distinguish explicit activation hints from manifest ownership fallback. For example,
activation-command-hintactivation.onCommandsmanifest-command-aliascommandAliasesUse
qaRunnersopenclaw qaruntime-api.tsqaRunnerCliRegistrationsjson{ "qaRunners": [ { "commandName": "matrix", "description": "Run the Docker-backed Matrix live QA lane against a disposable homeserver" } ] }
| Field | Required | Type | What it means |
|---|---|---|---|
text commandName | Yes | text string | Subcommand mounted beneath text openclaw qatext matrix |
text description | No | text string | Fallback help text used when the shared host needs a stub command. |
Use
setupjson{ "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 } }
Top-level
cliBackendssetup.cliBackendsWhen present,
setup.providerssetup.cliBackendsrequiresRuntime: truesetup-apiOpenClaw also includes
setup.providers[].envVarsproviderAuthEnvVarssetup.providers[].envVarsOpenClaw can also derive simple setup choices from
setup.providers[].authMethodssetup.requiresRuntime: falseproviderAuthChoicesSet
requiresRuntime: falsefalsesetup-apiopenclaw.setupEntryrequiresRuntimeBecause setup lookup can execute plugin-owned
setup-apisetup.providers[].idsetup.cliBackends[]When setup runtime does execute, setup registry diagnostics report descriptor drift if
setup-api| Field | Required | Type | What it means |
|---|---|---|---|
text id | Yes | text string | Provider id exposed during setup or onboarding. Keep normalized ids globally unique. |
text authMethods | No | text string[] | Setup/auth method ids this provider supports without loading full runtime. |
text envVars | No | text string[] | Env vars that generic setup/status surfaces can check before plugin runtime loads. |
text authEvidence | No | text object[] | Cheap local auth evidence checks for providers that can authenticate through non-secret markers. |
authEvidenceSupported evidence entries:
| Field | Required | Type | What it means |
|---|---|---|---|
text type | Yes | text string | Currently text local-file-with-env |
text fileEnvVar | No | text string | Env var containing an explicit credential file path. |
text fallbackPaths | No | text string[] | Local credential file paths checked when text fileEnvVartext ${HOME}text ${APPDATA} |
text requiresAnyEnv | No | text string[] | At least one listed env var must be non-empty before the evidence is valid. |
text requiresAllEnv | No | text string[] | Every listed env var must be non-empty before the evidence is valid. |
text credentialMarker | Yes | text string | Non-secret marker returned when the evidence is present. |
text source | No | text string | User-facing source label for auth/status output. |
| Field | Required | Type | What it means |
|---|---|---|---|
text providers | No | text object[] | Provider setup descriptors exposed during setup and onboarding. |
text cliBackends | No | text string[] | Setup-time backend ids used for descriptor-first setup lookup. Keep normalized ids globally unique. |
text configMigrations | No | text string[] | Config migration ids owned by this plugin's setup surface. |
text requiresRuntime | No | text boolean | Whether setup still needs text setup-api |
uiHintsjson{ "uiHints": { "apiKey": { "label": "API key", "help": "Used for OpenRouter requests", "placeholder": "sk-or-v1-...", "sensitive": true } } }
Each field hint can include:
| Field | Type | What it means |
|---|---|---|
text label | text string | User-facing field label. |
text help | text string | Short helper text. |
text tags | text string[] | Optional UI tags. |
text advanced | text boolean | Marks the field as advanced. |
text sensitive | text boolean | Marks the field as secret or sensitive. |
text placeholder | text string | Placeholder text for form inputs. |
Use
contractsjson{ "contracts": { "agentToolResultMiddleware": ["pi", "codex"], "externalAuthProviders": ["acme-ai"], "speechProviders": ["openai"], "realtimeTranscriptionProviders": ["openai"], "realtimeVoiceProviders": ["openai"], "memoryEmbeddingProviders": ["local"], "mediaUnderstandingProviders": ["openai", "openai-codex"], "imageGenerationProviders": ["openai"], "videoGenerationProviders": ["qwen"], "webFetchProviders": ["firecrawl"], "webSearchProviders": ["gemini"], "migrationProviders": ["hermes"], "tools": ["firecrawl_search", "firecrawl_scrape"] } }
Each list is optional:
| Field | Type | What it means |
|---|---|---|
text embeddedExtensionFactories | text string[] | Codex app-server extension factory ids, currently text codex-app-server |
text agentToolResultMiddleware | text string[] | Runtime ids a bundled plugin may register tool-result middleware for. |
text externalAuthProviders | text string[] | Provider ids whose external auth profile hook this plugin owns. |
text speechProviders | text string[] | Speech provider ids this plugin owns. |
text realtimeTranscriptionProviders | text string[] | Realtime-transcription provider ids this plugin owns. |
text realtimeVoiceProviders | text string[] | Realtime-voice provider ids this plugin owns. |
text memoryEmbeddingProviders | text string[] | Memory embedding provider ids this plugin owns. |
text mediaUnderstandingProviders | text string[] | Media-understanding provider ids this plugin owns. |
text imageGenerationProviders | text string[] | Image-generation provider ids this plugin owns. |
text videoGenerationProviders | text string[] | Video-generation provider ids this plugin owns. |
text webFetchProviders | text string[] | Web-fetch provider ids this plugin owns. |
text webSearchProviders | text string[] | Web-search provider ids this plugin owns. |
text migrationProviders | text string[] | Import provider ids this plugin owns for text openclaw migrate |
text tools | text string[] | Agent tool names this plugin owns for bundled contract checks. |
contracts.embeddedExtensionFactoriescontracts.agentToolResultMiddlewareapi.registerAgentToolResultMiddleware(...)Provider plugins that implement
resolveExternalAuthProfilescontracts.externalAuthProvidersBundled memory embedding providers should declare
contracts.memoryEmbeddingProviderslocalUse
mediaUnderstandingProviderMetadatacontracts.mediaUnderstandingProvidersjson{ "contracts": { "mediaUnderstandingProviders": ["example"] }, "mediaUnderstandingProviderMetadata": { "example": { "capabilities": ["image", "audio"], "defaultModels": { "image": "example-vision-latest", "audio": "example-transcribe-latest" }, "autoPriority": { "image": 40 }, "nativeDocumentInputs": ["pdf"] } } }
Each provider entry can include:
| Field | Type | What it means |
|---|---|---|
text capabilities | text ("image" | "audio" | "video")[] | Media capabilities exposed by this provider. |
text defaultModels | text Record<string, string> | Capability-to-model defaults used when config does not specify a model. |
text autoPriority | text Record<string, number> | Lower numbers sort earlier for automatic credential-based provider fallback. |
text nativeDocumentInputs | text "pdf"[] | Native document inputs supported by the provider. |
Use
channelConfigssetup.requiresRuntime: falsechannelConfigschannels.<channel-id>For a channel plugin,
configSchemachannelConfigsconfigSchemaplugins.entries.<plugin-id>.configchannelConfigs.<channel-id>.schemachannels.<channel-id>Non-bundled plugins that declare
channels[]channelConfigschannelConfigs.<channel-id>.commands.nativeCommandsAutoEnablednativeSkillsAutoEnabledautopackage.json#openclaw.channel.commandsjson{ "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 connection", "commands": { "nativeCommandsAutoEnabled": true, "nativeSkillsAutoEnabled": true }, "preferOver": ["matrix-legacy"] } } }
Each channel entry can include:
| Field | Type | What it means |
|---|---|---|
text schema | text object | JSON Schema for text channels.<id> |
text uiHints | text Record<string, object> | Optional UI labels/placeholders/sensitive hints for that channel config section. |
text label | text string | Channel label merged into picker and inspect surfaces when runtime metadata is not ready. |
text description | text string | Short channel description for inspect and catalog surfaces. |
text commands | text object | Static native command and native skill auto-defaults for pre-runtime config checks. |
text preferOver | text string[] | Legacy or lower-priority plugin ids this channel should outrank in selection surfaces. |
Use
preferOverjson{ "id": "acme-chat", "channels": ["chat"], "channelConfigs": { "chat": { "schema": { "type": "object", "additionalProperties": false, "properties": { "webhookUrl": { "type": "string" } } }, "preferOver": ["chat"] } } }
When
channels.chatKeep
preferOverUse
modelSupportgpt-5.5claude-sonnet-4.6json{ "modelSupport": { "modelPrefixes": ["gpt-", "o1", "o3", "o4"], "modelPatterns": ["^computer-use-preview"] } }
OpenClaw applies this precedence:
provider/modelprovidersmodelPatternsmodelPrefixesFields:
| Field | Type | What it means |
|---|---|---|
text modelPrefixes | text string[] | Prefixes matched with text startsWith |
text modelPatterns | text string[] | Regex sources matched against shorthand model ids after profile suffix removal. |
Use
modelCatalogjson{ "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" } } }
Top-level fields:
| Field | Type | What it means |
|---|---|---|
text providers | text Record<string, object> | Catalog rows for provider ids owned by this plugin. Keys should also appear in top-level text providers |
text aliases | text Record<string, object> | Provider aliases that should resolve to an owned provider for catalog or suppression planning. |
text suppressions | text object[] | Model rows from another source that this plugin suppresses for a provider-specific reason. |
text discovery | text Record<string, "static" | "refreshable" | "runtime"> | Whether the provider catalog can be read from manifest metadata, refreshed into cache, or requires runtime. |
aliasessuppressionssuppressBuiltInModelmodelCatalog.aliasesProvider fields:
| Field | Type | What it means |
|---|---|---|
text baseUrl | text string | Optional default base URL for models in this provider catalog. |
text api | text ModelApi | Optional default API adapter for models in this provider catalog. |
text headers | text Record<string, string> | Optional static headers that apply to this provider catalog. |
text models | text object[] | Required model rows. Rows without an text id |
Model fields:
| Field | Type | What it means |
|---|---|---|
text id | text string | Provider-local model id, without the text provider/ |
text name | text string | Optional display name. |
text api | text ModelApi | Optional per-model API override. |
text baseUrl | text string | Optional per-model base URL override. |
text headers | text Record<string, string> | Optional per-model static headers. |
text input | text Array<"text" | "image" | "document" | "audio" | "video"> | Modalities the model accepts. |
text reasoning | text boolean | Whether the model exposes reasoning behavior. |
text contextWindow | text number | Native provider context window. |
text contextTokens | text number | Optional effective runtime context cap when different from text contextWindow |
text maxTokens | text number | Maximum output tokens when known. |
text cost | text object | Optional USD per million token pricing, including optional text tieredPricing |
text compat | text object | Optional compatibility flags matching OpenClaw model config compatibility. |
text status | text "available"text "preview"text "deprecated"text "disabled" | Listing status. Suppress only when the row must not appear at all. |
text statusReason | text string | Optional reason shown with non-available status. |
text replaces | text string[] | Older provider-local model ids this model supersedes. |
text replacedBy | text string | Replacement provider-local model id for deprecated rows. |
text tags | text string[] | Stable tags used by pickers and filters. |
Suppression fields:
| Field | Type | What it means |
|---|---|---|
text provider | text string | Provider id for the upstream row to suppress. Must be owned by this plugin or declared as an owned alias. |
text model | text string | Provider-local model id to suppress. |
text reason | text string | Optional message shown when the suppressed row is requested directly. |
text when.baseUrlHosts | text string[] | Optional list of effective provider base URL hosts required before the suppression applies. |
text when.providerConfigApiIn | text string[] | Optional list of exact provider-config text api |
Do not put runtime-only data in
modelCatalogstaticrefreshableruntimeUse
modelIdNormalizationjson{ "providers": ["anthropic", "openrouter"], "modelIdNormalization": { "providers": { "anthropic": { "aliases": { "sonnet-4.6": "claude-sonnet-4-6" } }, "openrouter": { "prefixWhenBare": "openrouter" } } } }
Provider fields:
| Field | Type | What it means |
|---|---|---|
text aliases | text Record<string,string> | Case-insensitive exact model-id aliases. Values are returned as written. |
text stripPrefixes | text string[] | Prefixes to remove before alias lookup, useful for legacy provider/model duplication. |
text prefixWhenBare | text string | Prefix to add when the normalized model id does not already contain text / |
text prefixWhenBareAfterAliasStartsWith | text object[] | Conditional bare-id prefix rules after alias lookup, keyed by text modelPrefixtext prefix |
Use
providerEndpointsendpointClassEndpoint fields:
| Field | Type | What it means |
|---|---|---|
text endpointClass | text string | Known core endpoint class, such as text openroutertext moonshot-nativetext google-vertex |
text hosts | text string[] | Exact hostnames that map to the endpoint class. |
text hostSuffixes | text string[] | Host suffixes that map to the endpoint class. Prefix with text . |
text baseUrls | text string[] | Exact normalized HTTP(S) base URLs that map to the endpoint class. |
text googleVertexRegion | text string | Static Google Vertex region for exact global hosts. |
text googleVertexRegionHostSuffix | text string | Suffix to strip from matching hosts to expose the Google Vertex region prefix. |
Use
providerRequestjson{ "providers": ["vllm"], "providerRequest": { "providers": { "vllm": { "family": "vllm", "openAICompletions": { "supportsStreamingUsage": true } } } } }
Provider fields:
| Field | Type | What it means |
|---|---|---|
text family | text string | Provider family label used by generic request compatibility decisions and diagnostics. |
text compatibilityFamily | text "moonshot" | Optional provider-family compatibility bucket for shared request helpers. |
text openAICompletions | text object | OpenAI-compatible completions request flags, currently text supportsStreamingUsage |
Use
modelPricingjson{ "providers": ["ollama", "openrouter"], "modelPricing": { "providers": { "ollama": { "external": false }, "openrouter": { "openRouter": { "passthroughProviderModel": true }, "liteLLM": false } } } }
Provider fields:
| Field | Type | What it means |
|---|---|---|
text external | text boolean | Set text false |
text openRouter | text false | object | OpenRouter pricing lookup mapping. text false |
text liteLLM | text false | object | LiteLLM pricing lookup mapping. text false |
Source fields:
| Field | Type | What it means |
|---|---|---|
text provider | text string | External catalog provider id when it differs from the OpenClaw provider id, for example text z-aitext zai |
text passthroughProviderModel | text boolean | Treat slash-containing model ids as nested provider/model refs, useful for proxy providers such as OpenRouter. |
text modelIdTransforms | text "version-dots"[] | Extra external catalog model-id variants. text version-dotstext claude-opus-4.6 |
The OpenClaw Provider Index is OpenClaw-owned preview metadata for providers whose plugins may not be installed yet. It is not part of a plugin manifest. Plugin manifests remain the installed-plugin authority. The Provider Index is the internal fallback contract that future installable-provider and pre-install model picker surfaces will consume when a provider plugin is not installed.
Catalog authority order:
modelCatalogThe Provider Index must not contain secrets, enabled state, runtime hooks, or live account-specific model data. Its preview catalogs use the same
modelCatalogapibaseUrl/modelsProvider Index entries may also carry installable-plugin metadata for providers whose plugin has moved out of core or is otherwise not installed yet. This metadata mirrors the channel catalog pattern: package name, npm install spec, expected integrity, and cheap auth-choice labels are enough to show an installable setup option. Once the plugin is installed, its manifest wins and the Provider Index entry is ignored for that provider.
Legacy top-level capability keys are deprecated. Use
openclaw doctor --fixspeechProvidersrealtimeTranscriptionProvidersrealtimeVoiceProvidersmediaUnderstandingProvidersimageGenerationProvidersvideoGenerationProviderswebFetchProviderswebSearchProviderscontractsThe two files serve different jobs:
| File | Use it for |
|---|---|
text openclaw.plugin.json | Discovery, config validation, auth-choice metadata, and UI hints that must exist before plugin code runs |
text package.json | npm metadata, dependency installation, and the text openclaw |
If you are unsure where a piece of metadata belongs, use this rule:
openclaw.plugin.jsonpackage.jsonSome pre-runtime plugin metadata intentionally lives in
package.jsonopenclawopenclaw.plugin.jsonImportant examples:
| Field | What it means |
|---|---|
text openclaw.extensions | Declares native plugin entrypoints. Must stay inside the plugin package directory. |
text openclaw.runtimeExtensions | Declares built JavaScript runtime entrypoints for installed packages. Must stay inside the plugin package directory. |
text openclaw.setupEntry | Lightweight setup-only entrypoint used during onboarding, deferred channel startup, and read-only channel status/SecretRef discovery. Must stay inside the plugin package directory. |
text openclaw.runtimeSetupEntry | Declares the built JavaScript setup entrypoint for installed packages. Must stay inside the plugin package directory. |
text openclaw.channel | Cheap channel catalog metadata like labels, docs paths, aliases, and selection copy. |
text openclaw.channel.commands | Static native command and native skill auto-default metadata used by config, audit, and command-list surfaces before channel runtime loads. |
text openclaw.channel.configuredState | Lightweight configured-state checker metadata that can answer "does env-only setup already exist?" without loading the full channel runtime. |
text openclaw.channel.persistedAuthState | Lightweight persisted-auth checker metadata that can answer "is anything already signed in?" without loading the full channel runtime. |
text openclaw.install.npmSpectext openclaw.install.localPath | Install/update hints for bundled and externally published plugins. |
text openclaw.install.defaultChoice | Preferred install path when multiple install sources are available. |
text openclaw.install.minHostVersion | Minimum supported OpenClaw host version, using a semver floor like text >=2026.3.22 |
text openclaw.install.expectedIntegrity | Expected npm dist integrity string such as text sha512-... |
text openclaw.install.allowInvalidConfigRecovery | Allows a narrow bundled-plugin reinstall recovery path when config is invalid. |
text openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen | Lets setup-only channel surfaces load before the full channel plugin during startup. |
Manifest metadata decides which provider/channel/setup choices appear in onboarding before runtime loads.
package.json#openclaw.installopenclaw.plugin.jsonopenclaw.install.minHostVersionExact npm version pinning already lives in
npmSpec"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"expectedIntegrityexpectedIntegrityexpectedIntegrityChannel plugins should provide
openclaw.setupEntryRuntime entrypoint fields do not override package-boundary checks for source entrypoint fields. For example,
openclaw.runtimeExtensionsopenclaw.extensionsopenclaw.install.allowInvalidConfigRecoverychannels.<id>openclaw doctor --fixopenclaw.channel.persistedAuthStatejson{ "openclaw": { "channel": { "id": "whatsapp", "persistedAuthState": { "specifier": "./auth-presence", "exportName": "hasAnyWhatsAppAuth" } } } }
Use it when setup, doctor, status, or read-only presence flows need a cheap yes/no auth probe before the full channel plugin loads. Persisted auth state is not configured channel state: do not use this metadata to auto-enable plugins, repair runtime dependencies, or decide whether a channel runtime should load. The target export should be a small function that reads persisted state only; do not route it through the full channel runtime barrel.
openclaw.channel.configuredStatejson{ "openclaw": { "channel": { "id": "telegram", "configuredState": { "specifier": "./configured-state", "exportName": "hasTelegramConfiguredState" } } } }
Use it when a channel can answer configured-state from env or other tiny non-runtime inputs. If the check needs full config resolution or the real channel runtime, keep that logic in the plugin
config.hasConfiguredStateOpenClaw discovers plugins from several roots (bundled, global install, workspace, explicit config-selected paths). If two discoveries share the same
idPrecedence, highest to lowest:
plugins.entries.<id>Implications:
plugins.entries.<id>{ "type": "object", "additionalProperties": false }channels.*plugins.entries.<id>plugins.allowplugins.denyplugins.slots.*See Configuration reference for the full
plugins.*channelsproviderscliBackendsskillsproviderDiscoveryEntryplugins.slots.*kind: "memory"plugins.slots.memorykind: "context-engine"plugins.slots.contextEnginelegacyOpenClawPluginDefinition.kindsetup.providers[].envVarsproviderAuthEnvVarschannelEnvVarsallow-build-scriptspnpm rebuild <package>© 2024 TaskFlow Mirror
Powered by TaskFlow Sync Engine