diff --git a/docs/plugins/bundles.md b/docs/plugins/bundles.md
index 62688f96d56b..04142733e3b3 100644
--- a/docs/plugins/bundles.md
+++ b/docs/plugins/bundles.md
@@ -1,34 +1,50 @@
---
-summary: "Install and use Codex, Claude, and Cursor bundles as OpenClaw plugins"
+summary: "Install Codex, Claude, and Cursor-compatible bundles as OpenClaw plugins"
read_when:
- You want to install a Codex, Claude, or Cursor-compatible bundle
- - You need to understand how OpenClaw maps bundle content into native features
- - You are debugging bundle detection or missing capabilities
+ - You need to know which bundle features OpenClaw executes
+ - You are debugging bundle detection, MCP tools, LSP defaults, or missing capabilities
title: "Plugin bundles"
+doc-schema-version: 1
---
-OpenClaw can install plugins from three external ecosystems: **Codex**, **Claude**,
-and **Cursor**. These are called **bundles** — content and metadata packs that
-OpenClaw maps into native features like skills, hooks, and MCP tools.
+Plugin bundles let OpenClaw reuse compatible Codex, Claude, and Cursor plugin
+layouts without loading them as native OpenClaw runtime modules. Use this page
+when you have an existing bundle and need to install it, verify how OpenClaw
+classified it, and understand which parts become OpenClaw skills, hooks, MCP
+tools, settings, or diagnostics.
- Bundles are **not** the same as native OpenClaw plugins. Native plugins run
- in-process and can register any capability. Bundles are content packs with
- selective feature mapping and a narrower trust boundary.
+ Bundles are not native OpenClaw plugins. Native plugins run in process and can
+ register OpenClaw capabilities directly. Bundles are content and metadata
+ packs that OpenClaw maps selectively into supported surfaces.
-## Why bundles exist
+## Choose the right plugin format
-Many useful plugins are published in Codex, Claude, or Cursor format. Instead
-of requiring authors to rewrite them as native OpenClaw plugins, OpenClaw
-detects these formats and maps their supported content into the native feature
-set. This means you can install a Claude command pack or a Codex skill bundle
-and use it immediately.
+Use a bundle when you already have a Codex, Claude, or Cursor-compatible
+package and want OpenClaw to map its supported content into skills, hook packs,
+MCP tools, settings, or LSP defaults without rewriting it as a native plugin.
+Build a native OpenClaw plugin when the integration must register a channel,
+provider, service, HTTP route, Gateway method, plugin-owned CLI command, or
+another runtime capability.
-## Install a bundle
+| Need | Use |
+| --------------------------------------------------------------------------------------- | ------------- |
+| Reuse skills, command markdown, MCP config, or LSP defaults from a compatible ecosystem | Bundle |
+| Execute arbitrary plugin runtime code in OpenClaw | Native plugin |
+| Publish a full OpenClaw capability | Native plugin |
+| Port an existing Claude or Cursor command pack | Bundle |
+
+See [Building plugins](/plugins/building-plugins) for native plugin authoring
+and [Plugins](/tools/plugin) for the main install workflow.
+
+## Install and verify a bundle
-
+
+ Install from a local directory, archive, or supported marketplace source:
+
```bash
# Local directory
openclaw plugins install ./my-bundle
@@ -43,268 +59,281 @@ and use it immediately.
-
+
```bash
openclaw plugins list
openclaw plugins inspect
```
- Bundles show as `Format: bundle` with a subtype of `codex`, `claude`, or `cursor`.
+ A compatible bundle appears with `Format: bundle` and a `codex`, `claude`,
+ or `cursor` subtype.
-
+
```bash
openclaw gateway restart
```
- Mapped features (skills, hooks, MCP tools, LSP defaults) are available in the next session.
+ Installing or updating plugin code requires restarting the Gateway.
## What OpenClaw maps from bundles
-Not every bundle feature runs in OpenClaw today. Here is what works and what
-is detected but not yet wired.
+Not every bundle feature runs in OpenClaw today. OpenClaw maps supported content
+into native surfaces and reports detect-only content in plugin diagnostics.
### Supported now
-| Feature | How it maps | Applies to |
-| ------------- | ------------------------------------------------------------------------------------------- | -------------- |
-| Skill content | Bundle skill roots load as normal OpenClaw skills | All formats |
-| Commands | `commands/` and `.cursor/commands/` treated as skill roots | Claude, Cursor |
-| Hook packs | OpenClaw-style `HOOK.md` + `handler.ts` layouts | Codex |
-| MCP tools | Bundle MCP config merged into embedded Pi settings; supported stdio and HTTP servers loaded | All formats |
-| LSP servers | Claude `.lsp.json` and manifest-declared `lspServers` merged into embedded Pi LSP defaults | Claude |
-| Settings | Claude `settings.json` imported as embedded Pi defaults | Claude |
+| Feature | How it maps | Applies to |
+| ------------- | -------------------------------------------------------------------------------------------- | --------------- |
+| Skill content | Bundle skill roots load as normal OpenClaw skills | All formats |
+| Commands | `commands/` and `.cursor/commands/` are treated as skill roots | Claude, Cursor |
+| Hook packs | OpenClaw-style `HOOK.md` and `handler.ts` or `handler.js` layouts | Primarily Codex |
+| MCP tools | Bundle MCP config merges into embedded Pi settings; supported stdio and HTTP servers load | All formats |
+| LSP servers | Claude `.lsp.json` and manifest-declared `lspServers` merge into embedded Pi LSP defaults | Claude |
+| Settings | Claude `settings.json` imports as embedded Pi defaults after shell override keys are removed | Claude |
-#### Skill content
+### Skill content
-- bundle skill roots load as normal OpenClaw skill roots
-- Claude `commands` roots are treated as additional skill roots
-- Cursor `.cursor/commands` roots are treated as additional skill roots
+Bundle skill roots load as normal OpenClaw skill roots. Claude `commands/` and
+Cursor `.cursor/commands/` load through the same path.
-This means Claude markdown command files work through the normal OpenClaw skill
-loader. Cursor command markdown works through the same path.
+### Hook packs
-#### Hook packs
+Bundle hook roots run **only** when they use the normal OpenClaw hook-pack layout:
+`HOOK.md` with `handler.ts` or `handler.js`. Today this is primarily the
+Codex-compatible case.
-- bundle hook roots work **only** when they use the normal OpenClaw hook-pack
- layout. Today this is primarily the Codex-compatible case:
- - `HOOK.md`
- - `handler.ts` or `handler.js`
+### MCP tools
-#### MCP for Pi
+Enabled bundles can contribute MCP server config to embedded Pi as `mcpServers`.
+Supported stdio and HTTP servers can expose tools during embedded Pi turns. The
+`coding` and `messaging` tool profiles include bundle MCP tools by default; use
+`tools.deny: ["bundle-mcp"]` to opt out for an agent or Gateway.
-- enabled bundles can contribute MCP server config
-- OpenClaw merges bundle MCP config into the effective embedded Pi settings as
- `mcpServers`
-- OpenClaw exposes supported bundle MCP tools during embedded Pi agent turns by
- launching stdio servers or connecting to HTTP servers
-- the `coding` and `messaging` tool profiles include bundle MCP tools by
- default; use `tools.deny: ["bundle-mcp"]` to opt out for an agent or gateway
-- project-local Pi settings still apply after bundle defaults, so workspace
- settings can override bundle MCP entries when needed
-- bundle MCP tool catalogs are sorted deterministically before registration, so
- upstream `listTools()` order changes do not thrash prompt-cache tool blocks
+### Embedded Pi settings
-##### Transports
+Claude `settings.json` imports as default embedded Pi settings when the bundle is
+enabled. OpenClaw removes shell override keys before applying them.
-MCP servers can use stdio or HTTP transport:
+### Embedded Pi LSP
-**Stdio** launches a child process:
+Claude `.lsp.json` and manifest-declared `lspServers` merge into embedded Pi LSP
+defaults. Supported stdio-backed LSP servers can run.
+
+### Detected but not executed
+
+OpenClaw reports these in diagnostics but does not run them:
+
+- Claude `agents`, `hooks/hooks.json`, `outputStyles`
+- Cursor `.cursor/agents`, `.cursor/hooks.json`, `.cursor/rules`
+- Codex app or inline metadata
+
+## Bundle formats and detection
+
+OpenClaw checks native plugin markers before bundle markers. A directory with
+`openclaw.plugin.json` or a valid `package.json` `openclaw.extensions` entry is
+treated as a native plugin, even if it also contains bundle files. This prevents
+dual-format packages from being partially loaded through the bundle path.
+
+After native detection, OpenClaw recognizes these bundle layouts:
+
+
+
+ Marker: `.codex-plugin/plugin.json`
+
+ Supported mapped content: `skills/`, `hooks/`, `.mcp.json`, and `.app.json`
+ capability reporting.
+
+ Codex bundles fit OpenClaw best when they use skill roots and OpenClaw-style
+ hook-pack directories.
+
+
+
+
+ Detection modes:
+
+ - **Manifest-based:** `.claude-plugin/plugin.json`
+ - **Manifestless:** default Claude layout with `skills/`, `commands/`,
+ `agents/`, `hooks/hooks.json`, `.mcp.json`, `.lsp.json`, or
+ `settings.json`
+
+ Supported mapped content: `skills/`, `commands/`, `settings.json`,
+ `.mcp.json`, `.lsp.json`, manifest-declared `mcpServers`, and
+ manifest-declared `lspServers`.
+
+ Detect-only content: `agents`, `hooks/hooks.json`, and `outputStyles`.
+
+
+
+
+ Marker: `.cursor-plugin/plugin.json`
+
+ Supported mapped content: `skills/`, `.cursor/commands/`, and `.mcp.json`.
+
+ Detect-only content: `.cursor/agents`, `.cursor/hooks.json`, and
+ `.cursor/rules`.
+
+
+
+
+Claude manifest component paths are additive. Declaring custom paths extends
+the default paths that exist in the bundle instead of replacing them.
+
+## MCP config reference
+
+Bundle MCP tools use the synthetic plugin key `bundle-mcp` for profile filtering.
+To opt out for an agent or Gateway, deny that key:
+
+```json5
+{
+ tools: {
+ deny: ["bundle-mcp"],
+ },
+}
+```
+
+Project-local embedded Pi settings still apply after bundle defaults, so
+workspace settings can override bundle MCP entries when needed.
+
+### MCP config shape
+
+Bundle MCP files can use either `mcpServers`, `servers`, or a top-level server
+map. Stdio servers launch a child process:
```json
{
- "mcp": {
- "servers": {
- "my-server": {
- "command": "node",
- "args": ["server.js"],
- "env": { "PORT": "3000" }
- }
+ "mcpServers": {
+ "my-server": {
+ "command": "node",
+ "args": ["server.js"],
+ "env": { "PORT": "3000" }
}
}
}
```
-**HTTP** connects to a running MCP server over `sse` by default, or `streamable-http` when requested:
+HTTP servers connect over `sse` by default, or `streamable-http` when requested:
```json
{
- "mcp": {
- "servers": {
- "my-server": {
- "url": "http://localhost:3100/mcp",
- "transport": "streamable-http",
- "headers": {
- "Authorization": "Bearer ${MY_SECRET_TOKEN}"
- },
- "connectionTimeoutMs": 30000
- }
+ "mcpServers": {
+ "my-server": {
+ "url": "http://localhost:3100/mcp",
+ "transport": "streamable-http",
+ "headers": {
+ "Authorization": "Bearer local-dev-token"
+ },
+ "connectionTimeoutMs": 30000
}
}
}
```
-- `transport` may be set to `"streamable-http"` or `"sse"`; when omitted, OpenClaw uses `sse`
-- `type: "http"` is a CLI-native downstream shape; use `transport: "streamable-http"` in OpenClaw config. `openclaw mcp set` and `openclaw doctor --fix` normalize the common alias.
-- only `http:` and `https:` URL schemes are allowed
-- `headers` values support `${ENV_VAR}` interpolation
-- a server entry with both `command` and `url` is rejected
-- URL credentials (userinfo and query params) are redacted from tool
- descriptions and logs
+Rules:
+
+- `transport` may be `"sse"` or `"streamable-http"`. When omitted, OpenClaw
+ uses `sse`.
+- `type: "http"` is a CLI-native downstream alias. Prefer
+ `transport: "streamable-http"` in bundle config; `openclaw mcp set` and
+ `openclaw doctor --fix` normalize the alias.
+- Only `http:` and `https:` URLs are supported.
+- `headers` must be a JSON object with string-compatible values.
+- A server entry with `command` is treated as stdio. A server entry with `url`
+ and no command is treated as HTTP.
+- URL credentials, including userinfo and query params, are redacted from tool
+ descriptions and logs.
- `connectionTimeoutMs` overrides the default 30-second connection timeout for
- both stdio and HTTP transports
+ stdio and HTTP transports.
-##### Tool naming
+For stdio startup safety, unsupported environment-variable entries are ignored
+with diagnostics instead of being passed through blindly.
-OpenClaw registers bundle MCP tools with provider-safe names in the form
-`serverName__toolName`. For example, a server keyed `"vigil-harbor"` exposing a
-`memory_search` tool registers as `vigil-harbor__memory_search`.
+### MCP paths and tool names
-- characters outside `A-Za-z0-9_-` are replaced with `-`
-- fragments that would start with a non-letter get a letter prefix, so numeric
- server keys such as `12306` become provider-safe tool prefixes
-- server prefixes are capped at 30 characters
-- full tool names are capped at 64 characters
-- empty server names fall back to `mcp`
-- colliding sanitized names are disambiguated with numeric suffixes
-- final exposed tool order is deterministic by safe name to keep repeated Pi
- turns cache-stable
-- profile filtering treats all tools from one bundle MCP server as plugin-owned
- by `bundle-mcp`, so profile allowlists and deny lists can include either
- individual exposed tool names or the `bundle-mcp` plugin key
+File-backed MCP config is resolved relative to the bundle file that declared
+it. Explicit relative `command`, `args`, `cwd`, and `workingDirectory` values
+are expanded against that file's directory. Claude bundle config can also use
+`${CLAUDE_PLUGIN_ROOT}` to refer to the bundle root.
-#### Embedded Pi settings
+OpenClaw registers bundle MCP tools with provider-safe names:
-- Claude `settings.json` is imported as default embedded Pi settings when the
- bundle is enabled
-- OpenClaw sanitizes shell override keys before applying them
+```text
+serverName__toolName
+```
+
+Naming rules:
+
+- Characters outside `A-Za-z0-9_-` become `-`.
+- Server prefixes must start with a letter; numeric server keys get an `mcp-`
+ prefix.
+- Empty server names fall back to `mcp`.
+- Server prefixes are capped at 30 characters.
+- Full tool names are capped at 64 characters.
+- Colliding sanitized names get numeric suffixes.
+- Exposed tools are sorted deterministically by safe name so repeated Pi turns
+ keep stable tool blocks.
+- Profile allowlists and denylists can name either individual exposed tools or
+ the `bundle-mcp` plugin key.
+
+## Embedded Pi settings and LSP defaults
+
+Enabled Claude bundles can contribute `settings.json` defaults to the embedded
+Pi runtime. OpenClaw applies those settings before project-local settings, then
+sanitizes shell override keys so bundle or workspace settings cannot change
+shell execution behavior.
Sanitized keys:
- `shellPath`
- `shellCommandPrefix`
-#### Embedded Pi LSP
-
-- enabled Claude bundles can contribute LSP server config
-- OpenClaw loads `.lsp.json` plus any manifest-declared `lspServers` paths
-- bundle LSP config is merged into the effective embedded Pi LSP defaults
-- only supported stdio-backed LSP servers are runnable today; unsupported
- transports still show up in `openclaw plugins inspect `
-
-### Detected but not executed
-
-These are recognized and shown in diagnostics, but OpenClaw does not run them:
-
-- Claude `agents`, `hooks.json` automation, `outputStyles`
-- Cursor `.cursor/agents`, `.cursor/hooks.json`, `.cursor/rules`
-- Codex inline/app metadata beyond capability reporting
-
-## Bundle formats
-
-
-
- Markers: `.codex-plugin/plugin.json`
-
- Optional content: `skills/`, `hooks/`, `.mcp.json`, `.app.json`
-
- Codex bundles fit OpenClaw best when they use skill roots and OpenClaw-style
- hook-pack directories (`HOOK.md` + `handler.ts`).
-
-
-
-
- Two detection modes:
-
- - **Manifest-based:** `.claude-plugin/plugin.json`
- - **Manifestless:** default Claude layout (`skills/`, `commands/`, `agents/`, `hooks/`, `.mcp.json`, `.lsp.json`, `settings.json`)
-
- Claude-specific behavior:
-
- - `commands/` is treated as skill content
- - `settings.json` is imported into embedded Pi settings (shell override keys are sanitized)
- - `.mcp.json` exposes supported stdio tools to embedded Pi
- - `.lsp.json` plus manifest-declared `lspServers` paths load into embedded Pi LSP defaults
- - `hooks/hooks.json` is detected but not executed
- - Custom component paths in the manifest are additive (they extend defaults, not replace them)
-
-
-
-
- Markers: `.cursor-plugin/plugin.json`
-
- Optional content: `skills/`, `.cursor/commands/`, `.cursor/agents/`, `.cursor/rules/`, `.cursor/hooks.json`, `.mcp.json`
-
- - `.cursor/commands/` is treated as skill content
- - `.cursor/rules/`, `.cursor/agents/`, and `.cursor/hooks.json` are detect-only
-
-
-
-
-## Detection precedence
-
-OpenClaw checks for native plugin format first:
-
-1. `openclaw.plugin.json` or valid `package.json` with `openclaw.extensions` — treated as **native plugin**
-2. Bundle markers (`.codex-plugin/`, `.claude-plugin/`, or default Claude/Cursor layout) — treated as **bundle**
-
-If a directory contains both, OpenClaw uses the native path. This prevents
-dual-format packages from being partially installed as bundles.
+Enabled Claude bundles can also contribute LSP server config through `.lsp.json`
+or manifest-declared `lspServers`. OpenClaw merges those entries into embedded
+Pi LSP defaults. Supported stdio-backed LSP servers can run; unsupported server
+entries still appear in `openclaw plugins inspect ` diagnostics.
## Runtime dependencies and cleanup
-- Third-party compatible bundles do not get startup `npm install` repair. They
- should be installed through `openclaw plugins install` and ship everything
- they need in the installed plugin directory.
-- OpenClaw-owned bundled plugins are either shipped lightweight in core or
- downloadable through the plugin installer. Gateway startup never runs a
- package manager for them.
-- `openclaw doctor --fix` removes legacy staged dependency directories and can
- recover downloadable plugins that are missing from the local plugin index when
- config references them.
+Third-party compatible bundles do not get startup `npm install` repair. Install
+them with `openclaw plugins install`, and ship every runtime file they need
+inside the installed plugin directory.
-## Security
+OpenClaw-owned bundled plugins are either shipped lightweight in core or
+downloadable through the plugin installer. Gateway startup does not run a
+package manager for them. `openclaw doctor --fix` can remove legacy staged
+dependency directories and recover downloadable plugins that config references
+but the local plugin index is missing.
-Bundles have a narrower trust boundary than native plugins:
+## Security boundary
-- OpenClaw does **not** load arbitrary bundle runtime modules in-process
-- Skills and hook-pack paths must stay inside the plugin root (boundary-checked)
-- Settings files are read with the same boundary checks
-- Supported stdio MCP servers may be launched as subprocesses
+Bundles have a narrower runtime boundary than native plugins:
-This makes bundles safer by default, but you should still treat third-party
-bundles as trusted content for the features they do expose.
+- OpenClaw does not load arbitrary bundle runtime modules in process.
+- Skill roots, hook-pack paths, settings files, MCP files, and LSP files are
+ read with plugin-root boundary checks.
+- OpenClaw-style hook packs must stay inside the plugin root.
+- Supported stdio MCP servers can still launch subprocesses.
+
+Treat third-party bundles as trusted content for the mapped features they
+expose, especially MCP servers and hook packs.
## Troubleshooting
-
-
- Run `openclaw plugins inspect `. If a capability is listed but marked as
- not wired, that is a product limit — not a broken install.
-
-
-
- Make sure the bundle is enabled and the markdown files are inside a detected
- `commands/` or `skills/` root.
-
-
-
- Only embedded Pi settings from `settings.json` are supported. OpenClaw does
- not treat bundle settings as raw config patches.
-
-
-
- `hooks/hooks.json` is detect-only. If you need runnable hooks, use the
- OpenClaw hook-pack layout or ship a native plugin.
-
-
+| Symptom | Check | Fix |
+| -------------------------------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
+| Capability is listed but does not run | Run `openclaw plugins inspect ` and check whether it is marked as not wired | This is a current product limit, not a broken install |
+| Claude command files do not appear as skills | Check that markdown files are inside `commands/` or a declared command path | Move the files under a detected `commands/` or `skills/` root, enable the bundle, and restart |
+| Claude `settings.json` does not apply | Check that the bundle is enabled and inspect diagnostics | Only embedded Pi settings are imported; shell override keys are removed |
+| Claude hooks do not execute | Check whether the bundle only has `hooks/hooks.json` | Use an OpenClaw hook-pack layout or ship a native plugin |
## Related
-- [Install and Configure Plugins](/tools/plugin)
-- [Building Plugins](/plugins/building-plugins) — create a native plugin
-- [Plugin Manifest](/plugins/manifest) — native manifest schema
+- [Plugins](/tools/plugin) - install, configure, and troubleshoot plugins
+- [Manage plugins](/plugins/manage-plugins) - common plugin CLI examples
+- [Plugin inventory](/plugins/plugin-inventory) - generated bundled and external plugin list
+- [Plugin manifest](/plugins/manifest) - native plugin manifest schema
+- [Building plugins](/plugins/building-plugins) - create a native plugin