Skills: Teach Your Agent to Use Tools Effectively
Learn how skills work in OpenClaw, including loading order, precedence, and configuration. This page is for developers who need to manage, gate, or inject environment settings for agent skills.
Read this when
- Adding or modifying skills
- Changing skill gating, allowlists, or load rules
- Understanding skill precedence and snapshot behavior
Skills are markdown instruction files that show the agent when and how to employ tools. Each skill resides in its own directory that holds a SKILL.md file containing YAML frontmatter plus a markdown body. OpenClaw loads bundled skills along with any local overrides, and applies filtering during load time based on environment, configuration, and binary availability.
-
Creating skills, Develop and test a new custom skill from scratch.
-
Skill Workshop, Examine and approve skill proposals drafted by the agent.
-
Skills config, Complete
skills.*config schema and agent allowlists. -
ClawHub, Explore and install skills from the community.
Loading order
OpenClaw pulls from these sources, ordered by highest precedence first. If the same skill name shows up in multiple locations, the highest source takes priority.
| Priority | Source | Path |
|---|---|---|
| 1, highest | Workspace skills | <workspace>/skills |
| 2 | Project agent skills | <workspace>/.agents/skills |
| 3 | Personal agent skills | ~/.agents/skills (default state only) |
| 4 | Managed / local skills | <state-dir>/skills |
| 5 | Bundled skills | shipped with the install |
| 6, lowest | Extra directories | skills.load.extraDirs + plugin skills |
Skill roots accommodate grouped layouts. OpenClaw detects a skill whenever SKILL.md is found anywhere beneath a configured root (up to 6 levels deep):
<workspace>/skills/research/SKILL.md ✓ found as "research"
<workspace>/skills/personal/research/SKILL.md ✓ also found as "research"
The folder path only serves organizational purposes. The skill's name and slash command derive from the name frontmatter field (or the directory name when name is absent). Agent allowlists (below) also use this name for matching.
Note
Codex CLI's native
$CODEX_HOME/skillsdirectory is not treated as an OpenClaw skill root. Useopenclaw migrate plan codexto take inventory of those skills, thenopenclaw migrate codexto copy them into your OpenClaw workspace.
Node-hosted skills
A connected headless node can publish skills installed in its active OpenClaw skills directory (~/.openclaw/skills by default; profile environment overrides apply). While the node stays connected, these skills show up in the standard agent skill list, and they vanish once it disconnects. On a collision, a local or Gateway skill keeps its name; the node skill gets a deterministic node-prefixed name. Node-hosted v1 requires the directory name to match the skill's name frontmatter field.
The skill entry carries the node locator. Its files, relative references, and binaries reside on the node, so load and execute it with exec host=node node=<node-id>. After changing the node's skill files, restart the node host. See Nodes for pairing and off-switches.
Per-agent vs shared skills
In multi-agent setups, each agent gets its own workspace. Pick the path that matches the visibility you want:
| Scope | Path | Visible to |
|---|---|---|
| Per-agent | <workspace>/skills | Only that agent |
| Project-agent | <workspace>/.agents/skills | Only that workspace's agent |
| Personal-agent | ~/.agents/skills | Agents using the default state |
| Shared managed | <state-dir>/skills | All agents using that state |
| Extra dirs | skills.load.extraDirs | All agents using that config |
When OPENCLAW_STATE_DIR points somewhere other than the default ~/.openclaw, session skill indexes leave out home-scoped personal or compatibility skill roots such as ~/.agents/skills. Workspace, project, bundled, extra, and state-owned managed skills still load as usual.
Agent allowlists
Skill location (precedence) and skill visibility (which agent can use it) are separate controls. Use allowlists to restrict which skills an agent sees, regardless of where they are loaded from.
{
agents: {
defaults: {
skills: ["github", "weather"], // shared baseline
},
list: [
{ id: "writer" }, // inherits github, weather
{ id: "docs", skills: ["docs-search"] }, // replaces defaults entirely
{ id: "locked-down", skills: [] }, // no skills
],
},
}
Allowlist rules
- Omit
agents.defaults.skillsto leave all skills unrestricted by default. - Omit
agents.entries.*.skillsto inheritagents.defaults.skills. - Set
agents.entries.*.skills: []to expose no skills for that agent. - A non-empty
agents.entries.*.skillslist is the final set, it does not merge with defaults. - The effective allowlist applies across prompt building, slash-command discovery, sandbox sync, and skill snapshots.
- This is not a host shell authorization boundary. If the same agent can use
exec, constrain that shell separately with sandboxing, OS-user isolation, exec deny/allowlists, and per-resource credentials.
Plugins and skills
Plugins can ship their own skills by listing skills directories in openclaw.plugin.json (paths relative to the plugin root). Plugin skills load when the plugin is enabled, for example, the browser plugin ships a browser-automation skill for multi-step browser control.
Plugin skill directories merge at the same low-precedence level as skills.load.extraDirs, so a same-named bundled, managed, agent, or workspace skill overrides them. Gate a plugin skill's own eligibility via metadata.openclaw.requires in its frontmatter, same as any other skill.
See Plugins and Tools for the full plugin system.
Reference a skill in a prompt
Type $ in the Control UI composer to search the skills available to the current agent. Selecting a result inserts its stable command name, for example $release_notes, without replacing the rest of your message. A prompt can reference more than one skill:
Use $github and $release_notes to summarize this change for the release.
OpenClaw checks these references against the skills that the current agent can use, invoke, and see in its model context, then instructs the model to load each referenced SKILL.md before taking any action. Up to eight different skills can be cited in a single message; if more are present, OpenClaw raises a visible error rather than silently discarding the extras. The $ variant works as composable prompt text, while /release_notes ... stays the standalone command form and can trigger direct tool dispatch when the skill sets command-dispatch: tool. Uppercase shell variables that are common, such as $HOME, $PATH, and $EDITOR, are treated as plain text; to reference skills with those names, use lowercase $home, $path, or $editor.
Skills marked with disable-model-invocation: true are excluded from the $ picker because their instructions are deliberately left out of the model's prompt. To run those, call them explicitly with their standalone slash command.
On WebChat/Control UI turns, $ references are interpreted. Other messaging channels treat $name as ordinary text; there, use the skill's slash command.
Skill Workshop
Skill Workshop acts as a proposal queue sitting between the agent and your active skill files. When the agent finds reusable work, it creates a proposal rather than writing straight to SKILL.md. You review and approve before any changes take effect.
openclaw skills workshop list
openclaw skills workshop inspect <proposal-id>
openclaw skills workshop evaluate <proposal-id>
openclaw skills workshop apply <proposal-id>
For the complete lifecycle, CLI reference, and configuration, see Skill Workshop.
Installing from ClawHub
ClawHub serves as the public skills registry. Use openclaw skills commands for install and update operations, or turn to the clawhub CLI for publish and sync tasks.
| Action | Command |
|---|---|
| Install a skill into the workspace | openclaw skills install @owner/<slug> |
| Install an external skills.sh ref | openclaw skills install skills-sh:owner/repo/slug |
| Install from a Git repository | openclaw skills install git:owner/repo@ref |
| Install a local skill directory | openclaw skills install ./path/to/skill --as my-tool |
| Install for all local agents | openclaw skills install @owner/<slug> --global |
| Update all workspace skills | openclaw skills update --all |
| Update a shared managed skill | openclaw skills update @owner/<slug> --global |
| Update all shared managed skills | openclaw skills update --all --global |
| Verify a skill's trust envelope | openclaw skills verify @owner/<slug> |
| Print the generated Skill Card | openclaw skills verify @owner/<slug> --card |
| Publish / sync via ClawHub CLI | clawhub sync --all |
Install details
By default, openclaw skills install places the skill in the active workspace's skills/ directory. Adding --global switches the target to the shared ~/.openclaw/skills directory, which every local agent can see unless agent allowlists restrict it.
Git and local installs require SKILL.md at the source root. The slug is derived from SKILL.md frontmatter name when that is valid, otherwise it falls back to the directory or repository name. Override this with --as <slug>. Only ClawHub installs are tracked by openclaw skills update; reinstall Git or local sources to bring them up to date.
Verification and security scanning
openclaw skills verify @owner/<slug> requests the skill's clawhub.skill.verify.v1 trust envelope from ClawHub. Installed ClawHub skills verify against the version and registry recorded in .clawhub/origin.json. Bare slugs are still accepted for skills that are already installed or unambiguous, but owner-qualified refs prevent publisher confusion.
ClawHub skill pages show the latest security scan status before installation, with detail pages covering VirusTotal, ClawScan, and static analysis. When ClawHub marks verification as failed, the command exits with a non-zero status. Publishers can address false positives through the ClawHub dashboard or clawhub skill rescan @owner/<slug>.
Private archive installs
Gateway clients that need delivery outside ClawHub can prepare a zip skill archive using skills.upload.begin, skills.upload.chunk, and skills.upload.commit, then install it with skills.install({ source: "upload", ... }). This route is disabled by default and needs skills.install.allowUploadedArchives: true set in openclaw.json. Standard ClawHub installs never require that setting.
Security
Warning
Treat third-party skills as untrusted code. Read them before enabling. Prefer sandboxed runs for untrusted inputs and risky tools. See Sandboxing for agent-side controls.
Path containment
Workspace, project-agent, and extra-dir skill discovery will only accept skill roots when the resolved realpath of that root remains within the configured root directory, unless skills.load.allowSymlinkTargets has been set to explicitly trust a given target root. Writes through those trusted targets from Skill Workshop happen only when skills.workshop.allowSymlinkTargetWrites is turned on. Managed ~/.openclaw/skills and personal ~/.agents/skills can include symlinked skill folders, but each SKILL.md realpath still has to remain inside its own resolved skill directory.
Operator install policy
Set security.installPolicy to execute a trusted local policy command before skill installs are allowed to proceed. That policy receives metadata along with the staged source path, applies to ClawHub, uploaded, Git, local, update, and dependency-installer paths, and fails closed whenever the command cannot produce a valid decision.
Secret injection scope
Secrets get injected by skills.entries.*.env and skills.entries.*.apiKey into the host process for that agent turn only, never into the sandbox. Prompts and logs must not contain secrets.
The broader threat model and security checklists are covered in Security.
SKILL.md format
A skill requires at minimum a name and a description in the frontmatter:
---
name: image-lab
description: Generate or edit images via a provider-backed image workflow
---
When the user asks to generate an image, use the `image_generate` tool...
Note
The AgentSkills spec is what OpenClaw follows. Frontmatter gets parsed as YAML first; when that fails, a single-line-only parser takes over. Nested
metadatablocks, including multi-line YAML mappings, are flattened into a JSON string and re-parsed as JSON5, which is why the block form shown under Gating works. To reference the skill folder path from the body, use{baseDir}.
Optional frontmatter keys
-
homepage(string), URL that shows up as "Website" in the macOS Skills UI.metadata.openclaw.homepagealso supports it. -
user-invocable(boolean, default: true), Withtrue, the skill appears as a slash command users can invoke. -
disable-model-invocation(boolean, default: false), Whentrueis set, OpenClaw keeps the skill's instructions out of the agent's regular prompt. The skill still works as a slash command ifuser-invocableis alsotrue. -
command-dispatch(tool), Setting this totoolmakes the slash command skip the model and go straight to a registered tool. -
command-tool(string), The tool name called whencommand-dispatch: toolis set. -
command-arg-mode(raw, default: raw), For tool dispatch, passes the raw args string to the tool without core parsing. The tool gets{ command: "<raw args>", commandName: "<slash command>", skillName: "<skill name>" }.
Gating
At load time, OpenClaw filters skills with metadata.openclaw (a JSON5 object embedded in the frontmatter, see the parsing note above). A skill without an metadata.openclaw block is always eligible unless it has been explicitly disabled.
---
name: image-lab
description: Generate or edit images via a provider-backed image workflow
metadata:
{
"openclaw":
{
"requires": { "bins": ["uv"], "env": ["GEMINI_API_KEY"], "config": ["browser.enabled"] },
"primaryEnv": "GEMINI_API_KEY",
},
}
---
-
always(boolean), Whentrue, the skill is always included and every other gate is skipped. -
emoji(string), Optional emoji displayed in the macOS Skills UI. -
homepage(string), Optional URL shown as "Website" in the macOS Skills UI. -
os(("darwin" | "linux" | "win32")[]), Platform filter. When present, the skill is eligible only on one of the listed OSes. -
requires.bins(string[]), Every binary has to exist onPATH. -
requires.anyBins(string[]), At least one binary must exist onPATH. -
requires.env(string[]), Each env var has to exist in the process or come from config. -
requires.config(string[]), Eachopenclaw.jsonpath must be truthy. -
primaryEnv(string), Env var name tied toskills.entries.<name>.apiKey. -
install(object[]), Optional installer specs for the macOS Skills UI (brew / node / go / uv / download).
Note
Legacy
metadata.clawdbotblocks remain accepted whenmetadata.openclawis missing, so older installed skills keep their dependency gates and installer hints. New skills should go withmetadata.openclaw.
Installer specs
Installer specs tell the macOS Skills UI how a dependency gets installed:
---
name: gemini
description: Use Gemini CLI for coding assistance and Google search lookups.
metadata:
{
"openclaw":
{
"emoji": "♊️",
"requires": { "bins": ["gemini"] },
"install":
[
{
"id": "brew",
"kind": "brew",
"formula": "gemini-cli",
"bins": ["gemini"],
"label": "Install Gemini CLI (brew)",
},
],
},
}
---
Installer selection rules
- When several installers appear in the list, the gateway selects a single preferred one (brew if present, otherwise node).
- Should every installer be
download, OpenClaw displays each entry so that all available artifacts are visible. - Platform filtering is possible through
os: ["darwin"|"linux"|"win32"]within specs. - Node-based installs respect
skills.install.nodeManagerinsideopenclaw.json(default: npm; options: npm / pnpm / yarn / bun). This setting applies solely to skill installations; the Gateway runtime must remain Node. - Installer priority for the gateway: Homebrew → uv → configured node manager → go → download.
Per-installer details
- Homebrew: OpenClaw never installs Homebrew automatically, nor does it
convert brew formulas into system package commands. In Linux containers
lacking
brew, installers that rely solely on brew are hidden; either use a custom image or manually install the dependency. - Go: Automatic skill installation demands Go 1.21 or later. When
gois absent but Homebrew exists, OpenClaw first installs Go via Homebrew; on Linux without Homebrew, it may fall back toapt-getas root or through passwordlesssudoprovided the refreshedgolang-gocandidate satisfies the minimum version. The actualgo installfor the dependency always points to a dedicated bin directory managed by OpenClaw (Homebrew'sbinon a fresh install, otherwise~/.local/bin) rather than your configuredGOBIN. Your ownGOBIN,GOPATH, andGOTOOLCHAINenvironment variables are read but never modified. - Download:
url(mandatory),archive(tar.gz|tar.bz2|zip),extract(default: auto when an archive is detected),stripComponents,targetDir(default:~/.openclaw/tools/<skillKey>).
Sandboxing notes
At skill load time, requires.bins is verified on the host. For an agent
operating inside a sandbox, the binary must additionally be present
within the container. Install it through agents.defaults.sandbox.docker.setupCommand or a custom
image. setupCommand executes once after container creation, needing network
egress, a writable root filesystem, and a root user inside the sandbox.
Config overrides
Under skills.entries in ~/.openclaw/openclaw.json, you can toggle and configure bundled or
managed skills:
{
skills: {
entries: {
"image-lab": {
enabled: true,
apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" },
env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" },
config: {
endpoint: "https://example.invalid",
model: "nano-pro",
},
},
peekaboo: { enabled: true },
sag: { enabled: false },
},
},
}
-
enabled(boolean), Settingfalsedisables the skill even if it is bundled or installed. Thecoding-agentbundled skill is opt-in: configureskills.entries.coding-agent.enabled: trueand confirm that one ofclaude,codex,opencode, or another supported CLI is installed and authenticated. -
apiKey(string | { source, provider, id }), A shortcut for skills that declaremetadata.openclaw.primaryEnv. Accepts either a plaintext string or a SecretRef object. -
env(true), "> Environment variables injected for the agent run. Injection happens only when the variable is not already set in the process. -
config(object), Optional container for custom per-skill configuration fields. -
allowBundled(string[]), Optional allowlist limited to bundled skills. When defined, only bundled skills on that list become eligible. Managed and workspace skills remain unaffected.
Note
By default, config keys correspond to the skill name. If a skill specifies
metadata.openclaw.skillKey, use that key underskills.entriesinstead. Quote hyphenated names: JSON5 permits quoted keys.
Environment injection
At the start of an agent run, OpenClaw:
Reads skill metadata
The effective skill list for the agent is resolved, with gating rules, allowlists, and config overrides applied.
Injects env and API keys
For the duration of the run, skills.entries.<key>.env and skills.entries.<key>.apiKey are applied to
process.env.
Builds the system prompt
Eligible skills are packed into a compact XML block and placed into the system prompt.
Restores the environment
Once the run finishes, the original environment is brought back.
Warning
Env injection applies only to the host agent run, not the sandbox. Within a sandbox,
envandapiKeydo nothing. Refer to Skills config for guidance on passing secrets into sandboxed runs.
For the bundled claude-cli backend, OpenClaw also converts the same eligible skill snapshot into a temporary Claude Code plugin and hands it over through --plugin-dir. Every other CLI backend relies solely on the prompt catalog.
Snapshots and refresh
OpenClaw captures eligible skills when a session begins and keeps using that same list for every turn within the session. Any modifications to skills or configuration only show up once a fresh session starts.
Two situations trigger a mid-session skill refresh:
- The skills watcher notices a
SKILL.mdchange. - A new eligible remote node joins.
The updated list becomes active on the next agent turn. When the effective agent allowlist shifts, OpenClaw refreshes the snapshot so the visible skills stay in sync.
Skills watcher
Out of the box, OpenClaw monitors skill folders and updates the snapshot whenever SKILL.md files change. Set this up under skills.load:
{
skills: {
load: {
extraDirs: ["~/Projects/agent-scripts/skills"],
allowSymlinkTargets: ["~/Projects/manager/skills"],
watch: true, // default
},
},
}
Watcher events come with a built-in 250 ms debounce. For intentional symlinked layouts where a skill root symlink points outside the configured root, for instance <workspace>/skills/manager -> ~/Projects/manager/skills, use allowSymlinkTargets. Turn on skills.workshop.allowSymlinkTargetWrites only when Skill Workshop should also push proposals through those trusted symlinked paths.
Remote macOS nodes (Linux gateway)
When the Gateway runs on Linux but a macOS node is attached with system.run permitted, OpenClaw may treat macOS-only skills as eligible provided the required binaries exist on that node. The agent should execute those skills with the exec tool using host=node.
Offline nodes do not expose remote-only skills. If a node stops responding to bin probes, OpenClaw clears its cached bin matches.
Token impact
When skills qualify, OpenClaw inserts a compact XML block into the system prompt. The cost is predictable and grows linearly per skill:
- Base overhead (only when 1+ skills qualify): a fixed block of intro text plus the
<available_skills>wrapper. - Per skill: ~97 characters plus the lengths of your
name,description, andlocationfields. - XML escaping turns
& < > " 'into entities, adding a few characters for each occurrence. - At ~4 chars/token, 97 chars ≈ 24 tokens per skill before field lengths.
If the rendered block would go over the configured prompt budget (skills.limits.maxSkillsPromptChars), OpenClaw first keeps as many skill identities (name, location, and version) as the description-free compact format allows. Whatever budget remains goes to shortened descriptions. When no description budget is left, descriptions are dropped entirely. The prompt carries a note pointing at openclaw skills check whenever compact formatting or list truncation kicks in.
Keep descriptions brief and clear to cut down on prompt overhead.
Related
-
Creating skills, Walkthrough for building a custom skill from scratch.
-
Skill Workshop, Queue for reviewing skills drafted by the agent.
-
Skills config, Complete
skills.*config schema and agent allowlists. -
Slash commands, How skill slash commands get registered and routed.
-
ClawHub, Find and share skills on the public registry.
-
Plugins, Plugins can bundle skills alongside the tools they cover.