Skip to main content

Build an OpenClaw Skill

An OpenClaw skill is a folder containing a SKILL.md file. The frontmatter needs three fields to publish — name, description, version — and the Markdown body is the instruction text the agent reads. There is no scaffolding command: you create the folder by hand, confirm OpenClaw sees it with openclaw skills list, and publish with clawhub skill publish ./my-skill.

:::note Corrected 2026-09-09

An earlier version of this page documented clawhub init, clawhub eval, a bare clawhub publish, and triggers / capabilities / tools frontmatter blocks. None of those exist in OpenClaw's documentation. Every command, field and limit below was re-read from docs.openclaw.ai on 2026-09-09. Where the docs are silent, this page says so instead of guessing.

:::

What is an OpenClaw skill, exactly?​

A skill is instruction text, not code. OpenClaw compiles the eligible skills into a compact block injected into the system prompt, and the agent opens the body of one when the description looks relevant. The body tells the model how and when to use tools it already has.

What a skill is not: it is not a sandbox and not a permission system. SKILL.md has no field that restricts what a tool may do — the gating fields under metadata.openclaw decide whether a skill loads, not what it is allowed to touch once loaded. Restriction is a separate layer; see the NemoClaw policy cookbook.

A skill is also not a plugin. ClawHub hosts three things: skills (versioned text bundles built around SKILL.md), code plugins, and bundle plugins. If you need to ship executable plugin code, you are publishing a package, not a skill, and the command is clawhub package publish.

What does SKILL.md actually require?​

Three required fields, per ClawHub's skill format page. The optional top-level keys and the 160-character description rule come from OpenClaw's skills reference and Creating skills; ClawHub's format page documents neither, and its own field table lists only metadata.openclaw keys.

FieldRequiredRule as documented
nameYes1-64 lowercase letters, numbers or hyphens. Should match the parent directory.
descriptionYesOne line, under 160 characters. This is the only text the model reads before opening the skill.
versionNoSemver, and ClawHub fills it in for you: a new skill starts at 1.0.0 and later changes publish the next patch version automatically. Pass --version only when you need an explicit one.
homepageNoURL shown as "Website" in the macOS Skills UI. Works top-level; metadata.openclaw.homepage is also supported, and the example below uses the nested form.
user-invocableNoBoolean. Controls whether it appears as a slash command. Default true.
disable-model-invocationNoBoolean. Hides the skill from the model's normal prompt.
metadata.openclawNoGating and install block. Fields below.

The metadata.openclaw block is where runtime requirements go. requires.env lists environment variables, requires.bins lists binaries that must all be present, requires.anyBins needs at least one, requires.config names openclaw.json paths the skill reads. os restricts by platform, primaryEnv names the main credential variable, install declares dependency installers, and always: true keeps the skill active without an explicit install.

Here is the example ClawHub's own format page publishes, which is worth copying rather than inventing:

---
name: todoist-cli
description: Manage Todoist tasks, projects, and labels from the command line.
version: 1.2.0
metadata:
openclaw:
requires:
env:
- TODOIST_API_KEY
bins:
- curl
primaryEnv: TODOIST_API_KEY
envVars:
- name: TODOIST_API_KEY
required: true
description: Todoist API token.
- name: TODOIST_PROJECT_ID
required: false
description: Optional default project ID.
emoji: "✅"
homepage: https://github.com/example/todoist-cli
---

Everything after the closing --- is the instruction body. OpenClaw's guidance for it is short: "Be concise — instruct the model on what to do, not how to be an AI", and if the skill shells out, make sure the prompt cannot be turned into arbitrary command injection. Use the {baseDir} placeholder rather than hardcoding paths.

How do you create and test a skill locally?​

There is no clawhub init and no openclaw skills create. The documented process is four steps:

  1. Create the directory under ~/.openclaw/workspace/skills/. Subfolders are allowed — skills/personal/hello-world/SKILL.md works, because the skill is named by the frontmatter, not the path.
  2. Write SKILL.md: name, description, then the instruction body.
  3. Run openclaw skills list to confirm it loaded. Run openclaw skills check if it loaded but is not eligible.
  4. Test it with openclaw agent --message "give me a greeting", or just talk to the agent.

OpenClaw watches SKILL.md files under the skill roots by default, and a file-backed skill you edit mid-session refreshes on its own: the watcher detects the change and the refreshed list is picked up on the next agent turn. What is snapshotted at session start is which skills are eligible, so adding or enabling a new skill is the case that needs a fresh session — /new, or openclaw gateway restart if the gateway itself is not picking up the root. If you run the gateway in Docker using the OpenClaw Compose stack, run that restart inside the container.

Most fixes belong in the instruction body, not in the metadata:

SymptomWhere the fix goes
The agent never opens the skillThe description. It is the only thing the model sees first.
The agent does work the skill should not doAn explicit "What this skill does NOT do" section in the body.
The agent stops to ask for clarificationA "if the user does not specify X, default to Y" line in the body.
The agent ignores API errorsAn "Error handling" section naming the status codes and the response.
The skill never loads at allmetadata.openclaw.requires — a missing binary or env var.

What does each installed skill cost you in context?​

This is the part the vendor docs state precisely and almost nobody repeats. OpenClaw documents the per-skill prompt overhead as "~97 characters + your name, description, and location field lengths", which it puts at roughly 24 tokens per skill before the field content. That cost is linear, and OpenClaw's Token impact section states no ceiling on how many file-backed skills a session can load. What it does document is a character budget: when the rendered block would exceed skills.limits.maxSkillsPromptChars, OpenClaw keeps as many skill identities (name and location) as the compact, description-free format allows, spends what is left on shortened descriptions, and omits descriptions entirely if nothing remains. A 64-skill figure does exist in the docs, but only for one feature: on a shared Gateway, "a new session selects up to 64 enabled library skills, with personal skills first". That is the Personal Skill Library, not the Docker-mounted SKILL.md folders this page is about — so treat 64 below as a worked example, not a limit you will hit.

The arithmetic below is ours, applied to OpenClaw's documented figures at their own implied rate of about 4 characters per token:

InputDisciplined skillSloppy skill
Fixed overhead97 chars97 chars
name20 chars64 chars (the maximum)
description100 chars159 chars (just under the limit)
location50 chars50 chars
Per skill~267 chars, ~67 tokens~370 chars, ~93 tokens
Across 64 skills (worked example)~4,300 tokens~5,900 tokens

Trimming descriptions from 159 characters to 100 across a 64-skill set saves roughly 3,800 characters, about 950 tokens, on every session start. That is the argument for writing a tight description, and it is a stronger argument than style.

The description still has to earn its place, though: it is what the model matches on. Under-describing to save tokens gets you a skill that never fires. Aim for the shortest sentence that names the verbs and the domain.

Where does OpenClaw load skills from, and which one wins?​

Skills come from seven sources. When the same skill name appears in more than one, the highest wins:

  1. Workspace skills — <workspace>/skills
  2. Project agent skills — <workspace>/.agents/skills
  3. Personal agent skills — ~/.agents/skills
  4. Managed / local skills — <state-dir>/skills
  5. Workshop skills
  6. Bundled skills, shipped with the install
  7. Extra directories and plugin skills

The practical consequence: a workspace copy silently shadows an installed ClawHub skill of the same name. That is useful when you want to fork someone else's skill and test a change, and confusing when you have forgotten you did it. openclaw skills info <name> will tell you which one is live.

How do you publish to ClawHub?​

  1. Sign in: clawhub login. Publishing requires a GitHub account old enough to pass ClawHub's upload gate.
  2. Publish the folder. The path is positional and must contain SKILL.md:
clawhub skill publish ./my-skill \
--slug my-skill \
--name "My Skill" \
--owner your-org

Drop --owner to publish as yourself. Documented options include --slug, --name, --version, --changelog and --tags (comma-separated, defaulting to latest).

  1. Let it version itself. A new skill starts at 1.0.0 and later changes publish the next patch version automatically; pass --version only when you need to force one. Publishing skips unchanged content.

clawhub skill publish accepts --dry-run, which resolves the publish without uploading anything — the ClawHub publishing guide shows it as clawhub skill publish ./my-skill --slug my-skill --name "My Skill" --owner <owner> --dry-run. Run that first and read what it says it would do.

After publish, ClawHub checks your token can publish for that owner, validates the metadata, name, version, files and source, stores the release, then starts automated security checks. If validation fails, nothing is published. New releases may stay out of normal install and download surfaces until review finishes, so do not treat a successful publish as immediate availability.

Two limits worth knowing before you build: total bundle size is 50 MB, and the embedding text covers SKILL.md plus up to about 40 bounded UTF-8 files. Use .clawhubignore to keep the rest out of the bundle.

To check what the registry thinks of a release, openclaw skills verify @owner/<slug> prints ClawHub's verification envelope and exits non-zero when the decision is a fail.

Should you publish at all?​

Read this before you run clawhub login. All skills published on ClawHub are licensed under MIT-0. Anyone may use, modify and redistribute them, commercially, without attribution. ClawHub does not support paid skills, per-skill pricing, paywalls or revenue sharing.

That is a reasonable deal for a Todoist wrapper. It is a bad deal for a skill that encodes how your company qualifies leads or runs an incident review. Publishing is irreversible in the way that matters: you cannot re-license what people have already downloaded.

A private skill costs nothing and loses nothing. Put the folder in <workspace>/skills, and OpenClaw loads it at the highest precedence with no registry involvement. Publish when you want other people to have the thing; keep it local when the value is that other people do not.

The registry is open by default — anyone can upload, subject to the account-age gate — and moderators act on reports rather than pre-approving uploads. Automated checks run on published releases, and scan-held or blocked releases can vanish from the public catalogue. Treat an installed third-party skill as instruction text a stranger wrote and your agent will follow. Install prompts warn you for a reason: --acknowledge-install-policy-warning exists for automation, and per the docs neither it nor --force overrides a block or a policy failure. If you are running OpenClaw anywhere near regulated data, read the HIPAA deployment notes before installing community skills at all.

When is a skill the wrong tool?​

You want toUse
Teach the agent a new procedure or domainA skill
Ship executable plugin codeA ClawHub code plugin (clawhub package publish)
Stop the agent doing something, or log what it didA NemoClaw policy, not SKILL.md
Guarantee a deterministic sequence every timeNeither. A skill is a prompt; the model can still deviate.

The third row is the one that catches people. SKILL.md has no restriction primitive at all — the fields that look like guardrails are load-time gates. If your requirement is "this must never touch the internet", that requirement lives in NemoClaw policies or in the network configuration of the host, not in the skill.

If you have not picked a platform yet and skill portability matters to you, compare how the assistants handle this in OpenClaw vs the alternatives before writing anything. Hermes Agent's learning loop treats skills as something the agent writes for itself, which is a genuinely different model and a better fit if you want the system to accumulate its own procedures rather than curate a hand-written set.

Running skills on a production VPS​

Keep skills outside the Docker volumes so they survive docker compose down -v, and back up that directory — a skill you iterated on for a week is the one thing in the stack you cannot regenerate.

mkdir -p /home/youruser/openclaw-skills
scp -r ./my-skill yourserver:/home/youruser/openclaw-skills/

Then mount it into the gateway container alongside the data volume:

volumes:
- openclaw_data:/data
- /home/youruser/openclaw-skills:/data/skills:ro

Read-only is deliberate. It stops the agent editing its own instructions, which is a failure mode you only enjoy once.

For latency and error-rate visibility once skills are live, see monitoring and observability for OpenClaw.

Frequently Asked Questions

OpenClaw's docs set no ceiling on ordinary file-backed skills. The cost is linear per skill, and the only documented limit is the prompt-character budget skills.limits.maxSkillsPromptChars, which shortens or drops descriptions rather than dropping skills. One 64 figure does appear, and it is narrower than it looks: on a shared Gateway a new session selects up to 64 enabled Personal Skill Library skills, personal skills first, with stable ID ordering within each group. Either way the eligible list is snapshotted at session start, so changes take effect on the next new session, not the next message.

No. Neither appears in OpenClaw's documented CLI as of 2026-09-09. The documented clawhub commands are login, whoami, search, skill publish, package explore, package inspect, package publish, install, update and list. You create a skill folder by hand and test it with openclaw agent --message.

Yes, and often you should. A folder in the workspace skills directory loads at the highest precedence with no registry involvement. Publishing to ClawHub licenses the skill under MIT-0, which lets anyone reuse or resell it without attribution, and ClawHub does not support paid skills at all.

OpenClaw watches SKILL.md files under the skill roots, but the eligible-skill list is snapshotted at session start. Run /new to start a fresh session, or openclaw gateway restart. If the skill is listed and the session is new, the description is usually the problem rather than the body.

OpenClaw documents roughly 97 characters of fixed overhead per skill, about 24 tokens at their own ~4 chars per token, plus the length of the name, description and location fields. Sixty-four sloppy skills with 159-character descriptions work out near 5,900 tokens injected at session start; sixty-four disciplined ones near 4,300. That arithmetic is ours, applied to their figures, and 64 is an example count rather than a documented cap.

Common mistakes and fixes

The skill does not appear in `openclaw skills list`.

Check the name first. OpenClaw's docs require lowercase letters, digits and hyphens, and the skill is named by the `name` frontmatter field, not the folder. Discovery finds `SKILL.md` up to 6 levels deep inside a skill root, so nesting is fine but the file must be named `SKILL.md`.

The skill is listed, but the agent never uses it.

OpenClaw snapshots eligible skills when a session starts and reuses that list for the whole session. Start a fresh session with `/new`, or run `openclaw gateway restart`. Then check the description: it is the only text the model sees before deciding to open the skill.

The skill is listed but shows as ineligible.

Run `openclaw skills check`. It reports missing prerequisites separately from agent-allowlist exclusion, so you can tell a missing binary or environment variable in `metadata.openclaw.requires` apart from a skill the agent is simply not allowed to load.

`clawhub skill publish` fails and nothing lands in the registry.

Publishing validates metadata, name, version, files and source before storing anything, and if validation fails nothing is published. Confirm you are signed in with `clawhub login`, that the folder contains `SKILL.md`, and that `name` is 1-64 lowercase letters, numbers or hyphens.