2025-12-20 12:22:15 +01:00
---
summary: "Skills: managed vs workspace, gating rules, and config/env wiring"
read_when:
- Adding or modifying skills
- Changing skill gating or load rules
2026-01-31 16:04:03 -05:00
title: "Skills"
2025-12-20 12:22:15 +01:00
---
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
# Skills (OpenClaw)
2025-12-20 12:22:15 +01:00
2026-01-30 03:15:10 +01:00
OpenClaw uses ** [AgentSkills ](https://agentskills.io )-compatible** skill folders to teach the agent how to use tools. Each skill is a directory containing a `SKILL.md` with YAML frontmatter and instructions. OpenClaw loads **bundled skills** plus optional local overrides, and filters them at load time based on environment, config, and binary presence.
2025-12-20 12:22:15 +01:00
## Locations and precedence
2025-12-20 12:23:53 +00:00
Skills are loaded from **three** places:
2025-12-20 12:22:15 +01:00
2026-01-31 21:13:13 +09:00
1. **Bundled skills** : shipped with the install (npm package or OpenClaw.app)
2. **Managed/local skills** : `~/.openclaw/skills`
3. **Workspace skills** : `<workspace>/skills`
2025-12-20 12:22:15 +01:00
2025-12-20 12:23:53 +00:00
If a skill name conflicts, precedence is:
2026-01-30 03:15:10 +01:00
`<workspace>/skills` (highest) → `~/.openclaw/skills` → bundled skills (lowest)
2025-12-20 12:22:15 +01:00
2026-01-01 10:07:31 +01:00
Additionally, you can configure extra skill folders (lowest precedence) via
2026-01-30 03:15:10 +01:00
`skills.load.extraDirs` in `~/.openclaw/openclaw.json` .
2025-12-20 12:26:58 +00:00
2026-01-09 01:37:19 +01:00
## Per-agent vs shared skills
In **multi-agent** setups, each agent has its own workspace. That means:
- **Per-agent skills** live in `<workspace>/skills` for that agent only.
2026-01-30 03:15:10 +01:00
- **Shared skills** live in `~/.openclaw/skills` (managed/local) and are visible
2026-01-09 01:37:19 +01:00
to **all agents** on the same machine.
- **Shared folders** can also be added via `skills.load.extraDirs` (lowest
precedence) if you want a common skills pack used by multiple agents.
If the same skill name exists in more than one place, the usual precedence
applies: workspace wins, then managed/local, then bundled.
2026-01-11 12:11:12 +00:00
## Plugins + skills
2026-01-23 00:49:32 +00:00
Plugins can ship their own skills by listing `skills` directories in
2026-01-30 03:15:10 +01:00
`openclaw.plugin.json` (paths relative to the plugin root). Plugin skills load
2026-01-23 00:49:32 +00:00
when the plugin is enabled and participate in the normal skill precedence rules.
2026-01-30 03:15:10 +01:00
You can gate them via `metadata.openclaw.requires.config` on the plugin’ s config
2026-02-07 15:40:35 -05:00
entry. See [Plugins ](/tools/plugin ) for discovery/config and [Tools ](/tools ) for the
2026-01-23 00:49:32 +00:00
tool surface those skills teach.
2026-01-11 12:11:12 +00:00
2026-01-30 21:01:02 +01:00
## ClawHub (install + sync)
2026-01-09 01:38:19 +01:00
2026-01-30 21:01:02 +01:00
ClawHub is the public skills registry for OpenClaw. Browse at
2026-02-06 10:08:59 -05:00
[https://clawhub.com ](https://clawhub.com ). Use it to discover, install, update, and back up skills.
2026-01-30 21:01:02 +01:00
Full guide: [ClawHub ](/tools/clawhub ).
2026-01-09 01:38:19 +01:00
Common flows:
- Install a skill into your workspace:
2026-01-30 21:01:02 +01:00
- `clawhub install <skill-slug>`
2026-01-09 01:38:19 +01:00
- Update all installed skills:
2026-01-30 21:01:02 +01:00
- `clawhub update --all`
2026-01-09 01:38:19 +01:00
- Sync (scan + publish updates):
2026-01-30 21:01:02 +01:00
- `clawhub sync --all`
2026-01-09 01:38:19 +01:00
2026-01-30 21:01:02 +01:00
By default, `clawhub` installs into `./skills` under your current working
2026-01-30 03:15:10 +01:00
directory (or falls back to the configured OpenClaw workspace). OpenClaw picks
2026-01-13 06:04:45 +00:00
that up as `<workspace>/skills` on the next session.
2026-01-09 01:38:19 +01:00
2026-01-26 19:58:54 +00:00
## Security notes
2026-02-01 15:05:46 +00:00
- Treat third-party skills as **untrusted code** . Read them before enabling.
2026-01-26 19:58:54 +00:00
- Prefer sandboxed runs for untrusted inputs and risky tools. See [Sandboxing ](/gateway/sandboxing ).
2026-03-07 18:56:09 +00:00
- Workspace and extra-dir skill discovery only accepts skill roots and `SKILL.md` files whose resolved realpath stays inside the configured root.
2026-01-26 19:58:54 +00:00
- `skills.entries.*.env` and `skills.entries.*.apiKey` inject secrets into the **host** process
for that agent turn (not the sandbox). Keep secrets out of prompts and logs.
- For a broader threat model and checklists, see [Security ](/gateway/security ).
2025-12-20 12:22:15 +01:00
## Format (AgentSkills + Pi-compatible)
`SKILL.md` must include at least:
```markdown
---
name: nano-banana-pro
description: Generate or edit images via Gemini 3 Pro Image
---
```
Notes:
2026-01-31 21:13:13 +09:00
2025-12-20 12:22:15 +01:00
- We follow the AgentSkills spec for layout/intent.
- The parser used by the embedded agent supports **single-line** frontmatter keys only.
- `metadata` should be a **single-line JSON object** .
- Use `{baseDir}` in instructions to reference the skill folder path.
2025-12-20 17:31:09 +01:00
- Optional frontmatter keys:
2026-01-30 03:15:10 +01:00
- `homepage` — URL surfaced as “Website” in the macOS Skills UI (also supported via `metadata.openclaw.homepage` ).
2026-01-16 12:10:20 +00:00
- `user-invocable` — `true|false` (default: `true` ). When `true` , the skill is exposed as a user slash command.
- `disable-model-invocation` — `true|false` (default: `false` ). When `true` , the skill is excluded from the model prompt (still available via user invocation).
2026-01-19 13:11:25 +01:00
- `command-dispatch` — `tool` (optional). When set to `tool` , the slash command bypasses the model and dispatches directly to a tool.
- `command-tool` — tool name to invoke when `command-dispatch: tool` is set.
- `command-arg-mode` — `raw` (default). For tool dispatch, forwards the raw args string to the tool (no core parsing).
The tool is invoked with params:
`{ command: "<raw args>", commandName: "<slash command>", skillName: "<skill name>" }` .
2025-12-20 12:22:15 +01:00
## Gating (load-time filters)
2026-01-30 03:15:10 +01:00
OpenClaw **filters skills at load time** using `metadata` (single-line JSON):
2025-12-20 12:22:15 +01:00
```markdown
---
name: nano-banana-pro
description: Generate or edit images via Gemini 3 Pro Image
2026-01-31 21:13:13 +09:00
metadata:
{
"openclaw":
{
"requires": { "bins": ["uv"], "env": ["GEMINI_API_KEY"], "config": ["browser.enabled"] },
"primaryEnv": "GEMINI_API_KEY",
},
}
2025-12-20 12:22:15 +01:00
---
```
2026-01-30 03:15:10 +01:00
Fields under `metadata.openclaw` :
2026-01-31 21:13:13 +09:00
2025-12-20 12:22:15 +01:00
- `always: true` — always include the skill (skip other gates).
2025-12-20 17:23:45 +01:00
- `emoji` — optional emoji used by the macOS Skills UI.
2025-12-20 17:31:09 +01:00
- `homepage` — optional URL shown as “Website” in the macOS Skills UI.
2026-01-01 22:23:23 +01:00
- `os` — optional list of platforms (`darwin` , `linux` , `win32` ). If set, the skill is only eligible on those OSes.
2025-12-20 12:22:15 +01:00
- `requires.bins` — list; each must exist on `PATH` .
2026-01-02 15:40:03 -08:00
- `requires.anyBins` — list; at least one must exist on `PATH` .
2025-12-20 12:22:15 +01:00
- `requires.env` — list; env var must exist **or** be provided in config.
2026-01-30 03:15:10 +01:00
- `requires.config` — list of `openclaw.json` paths that must be truthy.
2026-01-01 10:07:31 +01:00
- `primaryEnv` — env var name associated with `skills.entries.<name>.apiKey` .
2026-01-21 00:12:54 +00:00
- `install` — optional array of installer specs used by the macOS Skills UI (brew/node/go/uv/download).
2025-12-20 13:33:06 +01:00
2026-01-15 04:41:38 +00:00
Note on sandboxing:
2026-01-31 21:13:13 +09:00
2026-01-15 04:41:38 +00:00
- `requires.bins` is checked on the **host** at skill load time.
- If an agent is sandboxed, the binary must also exist **inside the container** .
Install it via `agents.defaults.sandbox.docker.setupCommand` (or a custom image).
2026-01-19 01:35:17 +00:00
`setupCommand` runs once after the container is created.
Package installs also require network egress, a writable root FS, and a root user in the sandbox.
2026-01-15 04:41:38 +00:00
Example: the `summarize` skill (`skills/summarize/SKILL.md` ) needs the `summarize` CLI
in the sandbox container to run there.
2025-12-20 13:33:06 +01:00
Installer example:
```markdown
---
name: gemini
description: Use Gemini CLI for coding assistance and Google search lookups.
2026-01-31 21:13:13 +09:00
metadata:
{
"openclaw":
{
"emoji": "♊️",
"requires": { "bins": ["gemini"] },
"install":
[
{
"id": "brew",
"kind": "brew",
"formula": "gemini-cli",
"bins": ["gemini"],
"label": "Install Gemini CLI (brew)",
},
],
},
}
2025-12-20 13:33:06 +01:00
---
```
2025-12-20 12:22:15 +01:00
2025-12-20 17:23:45 +01:00
Notes:
2026-01-31 21:13:13 +09:00
2025-12-20 17:23:45 +01:00
- If multiple installers are listed, the gateway picks a **single** preferred option (brew when available, otherwise node).
2026-01-30 03:15:10 +01:00
- If all installers are `download` , OpenClaw lists each entry so you can see the available artifacts.
2026-01-21 00:12:54 +00:00
- Installer specs can include `os: ["darwin"|"linux"|"win32"]` to filter options by platform.
2026-01-30 03:15:10 +01:00
- Node installs honor `skills.install.nodeManager` in `openclaw.json` (default: npm; options: npm/pnpm/yarn/bun).
2026-01-13 07:58:47 +00:00
This only affects **skill installs** ; the Gateway runtime should still be Node
(Bun is not recommended for WhatsApp/Telegram).
2026-01-01 22:23:23 +01:00
- Go installs: if `go` is missing and `brew` is available, the gateway installs Go via Homebrew first and sets `GOBIN` to Homebrew’ s `bin` when possible.
2026-01-31 21:13:13 +09:00
- Download installs: `url` (required), `archive` (`tar.gz` | `tar.bz2` | `zip` ), `extract` (default: auto when archive detected), `stripComponents` , `targetDir` (default: `~/.openclaw/tools/<skillKey>` ).
2025-12-20 17:23:45 +01:00
2026-01-30 03:15:10 +01:00
If no `metadata.openclaw` is present, the skill is always eligible (unless
2026-01-01 10:07:31 +01:00
disabled in config or blocked by `skills.allowBundled` for bundled skills).
2025-12-20 12:22:15 +01:00
2026-01-30 03:15:10 +01:00
## Config overrides (`~/.openclaw/openclaw.json`)
2025-12-20 12:22:15 +01:00
2025-12-20 12:23:53 +00:00
Bundled/managed skills can be toggled and supplied with env values:
2025-12-20 12:22:15 +01:00
```json5
{
skills: {
2026-01-01 10:07:31 +01:00
entries: {
"nano-banana-pro": {
enabled: true,
2026-02-25 17:58:10 -06:00
apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string
2026-01-01 10:07:31 +01:00
env: {
2026-01-31 21:13:13 +09:00
GEMINI_API_KEY: "GEMINI_KEY_HERE",
2026-01-20 15:56:52 +00:00
},
config: {
endpoint: "https://example.invalid",
2026-01-31 21:13:13 +09:00
model: "nano-pro",
},
2026-01-01 10:07:31 +01:00
},
peekaboo: { enabled: true },
2026-01-31 21:13:13 +09:00
sag: { enabled: false },
},
},
2025-12-20 12:22:15 +01:00
}
```
Note: if the skill name contains hyphens, quote the key (JSON5 allows quoted keys).
2026-01-01 10:07:31 +01:00
Config keys match the **skill name** by default. If a skill defines
2026-01-30 03:15:10 +01:00
`metadata.openclaw.skillKey` , use that key under `skills.entries` .
2025-12-20 12:22:15 +01:00
Rules:
2026-01-31 21:13:13 +09:00
2025-12-20 12:23:53 +00:00
- `enabled: false` disables the skill even if it’ s bundled/installed.
2025-12-20 12:22:15 +01:00
- `env` : injected **only if** the variable isn’ t already set in the process.
2026-01-30 03:15:10 +01:00
- `apiKey` : convenience for skills that declare `metadata.openclaw.primaryEnv` .
2026-02-25 17:58:10 -06:00
Supports plaintext string or SecretRef object (`{ source, provider, id }` ).
2026-01-20 15:56:52 +00:00
- `config` : optional bag for custom per-skill fields; custom keys must live here.
2026-01-01 10:07:31 +01:00
- `allowBundled` : optional allowlist for **bundled** skills only. If set, only
bundled skills in the list are eligible (managed/workspace skills unaffected).
2025-12-20 12:22:15 +01:00
## Environment injection (per agent run)
2026-01-30 03:15:10 +01:00
When an agent run starts, OpenClaw:
2026-01-31 21:13:13 +09:00
1. Reads skill metadata.
2. Applies any `skills.entries.<key>.env` or `skills.entries.<key>.apiKey` to
2026-01-01 10:07:31 +01:00
`process.env` .
2026-01-31 21:13:13 +09:00
3. Builds the system prompt with **eligible** skills.
4. Restores the original environment after the run ends.
2025-12-20 12:22:15 +01:00
This is **scoped to the agent run** , not a global shell environment.
## Session snapshot (performance)
2026-01-30 03:15:10 +01:00
OpenClaw snapshots the eligible skills **when a session starts** and reuses that list for subsequent turns in the same session. Changes to skills or config take effect on the next new session.
2025-12-20 12:22:15 +01:00
2026-01-16 03:45:03 +00:00
Skills can also refresh mid-session when the skills watcher is enabled or when a new eligible remote node appears (see below). Think of this as a **hot reload** : the refreshed list is picked up on the next agent turn.
## Remote macOS nodes (Linux gateway)
2026-01-30 03:15:10 +01:00
If the Gateway is running on Linux but a **macOS node** is connected **with `system.run` allowed** (Exec approvals security not set to `deny` ), OpenClaw can treat macOS-only skills as eligible when the required binaries are present on that node. The agent should execute those skills via the `nodes` tool (typically `nodes.run` ).
2026-01-16 03:45:03 +00:00
This relies on the node reporting its command support and on a bin probe via `system.run` . If the macOS node goes offline later, the skills remain visible; invocations may fail until the node reconnects.
## Skills watcher (auto-refresh)
2026-01-30 03:15:10 +01:00
By default, OpenClaw watches skill folders and bumps the skills snapshot when `SKILL.md` files change. Configure this under `skills.load` :
2026-01-16 03:45:03 +00:00
```json5
{
skills: {
load: {
watch: true,
2026-01-31 21:13:13 +09:00
watchDebounceMs: 250,
},
},
2026-01-16 03:45:03 +00:00
}
```
2026-01-09 02:21:17 +00:00
## Token impact (skills list)
2026-01-30 03:15:10 +01:00
When skills are eligible, OpenClaw injects a compact XML list of available skills into the system prompt (via `formatSkillsForPrompt` in `pi-coding-agent` ). The cost is deterministic:
2026-01-09 02:21:17 +00:00
- **Base overhead (only when ≥1 skill):** 195 characters.
- **Per skill:** 97 characters + the length of the XML-escaped `<name>` , `<description>` , and `<location>` values.
Formula (characters):
```
total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(location_escaped))
```
Notes:
2026-01-31 21:13:13 +09:00
2026-01-09 02:21:17 +00:00
- XML escaping expands `& < > " '` into entities (`&` , `<` , etc.), increasing length.
- Token counts vary by model tokenizer. A rough OpenAI-style estimate is ~4 chars/token, so **97 chars ≈ 24 tokens** per skill plus your actual field lengths.
2025-12-20 12:22:15 +01:00
## Managed skills lifecycle
2026-01-30 03:15:10 +01:00
OpenClaw ships a baseline set of skills as **bundled skills** as part of the
install (npm package or OpenClaw.app). `~/.openclaw/skills` exists for local
2026-01-01 10:07:31 +01:00
overrides (for example, pinning/patching a skill without changing the bundled
copy). Workspace skills are user-owned and override both on name conflicts.
## Config reference
2026-01-10 14:51:21 -06:00
See [Skills config ](/tools/skills-config ) for the full configuration schema.
2025-12-20 12:22:15 +01:00
2026-01-06 23:51:01 +01:00
## Looking for more skills?
2026-02-06 10:08:59 -05:00
Browse [https://clawhub.com ](https://clawhub.com ).
2026-01-06 23:51:01 +01:00
2025-12-20 12:22:15 +01:00
---