Skip to content

Extend OpenClaw: Build and Manage Custom Agent Skills

OpenClaw picks up skills from several different spots on your machine. It starts looking in your local workspace and works its way down to the default bundled skills. Here is the order of where it looks:

  1. Extra skill folders: these are folders you configure manually with skills.load.extraDirs
  2. Bundled skills: these are the ones that come pre-installed with the npm package or the OpenClaw.app
  3. Managed/local skills: located at ~/.openclaw/skills
  4. Personal agent skills: located at ~/.agents/skills
  5. Project agent skills: located at <workspace>/.agents/skills
  6. Workspace skills: located at <workspace>/skills

If you happen to have two skills with the same name in different places, OpenClaw uses a specific priority to decide which one to use. The workspace always wins:

<workspace>/skills (highest) → <workspace>/.agents/skills → ~/.agents/skills → ~/.openclaw/skills → bundled skills → skills.load.extraDirs (lowest)

If you are running a multi-agent setup, you should know that every agent operates in its own workspace. This changes how you organize your skills:

  • Per-agent skills stay inside <workspace>/skills and only that specific agent can see them.
  • Project agent skills live in <workspace>/.agents/skills. OpenClaw checks these before looking in the standard workspace skills/ folder.
  • Personal agent skills are stored in ~/.agents/skills. These are available to every workspace you use on that specific machine.
  • Shared skills live in ~/.openclaw/skills. These are managed/local skills that every agent on your machine can access.
  • Shared folders can be added through skills.load.extraDirs. This is the best way to use a common skills pack across multiple agents, though it has the lowest priority.

When the same skill name exists in multiple locations, the standard priority applies: your workspace version is used first, followed by project agent skills, personal agent skills, managed/local, bundled, and finally any extra directories.

Plugins can also bring their own skills to your setup. They do this by defining skills directories inside the openclaw.plugin.json file, using paths relative to the plugin root. These skills become available as soon as you enable the plugin.

Currently, these plugin skill directories are treated with the same low priority as skills.load.extraDirs. This means if you have a bundled, managed, agent, or workspace skill with the same name, it will take priority over the plugin’s skill. You can also gate these skills using metadata.openclaw.requires.config within the plugin configuration. For more details on how to find and configure these, check out Plugins and the Tools documentation.

ClawHub is the public registry for OpenClaw skills. You can browse through available skills at https://clawhub.com. To manage them, you can use the built-in openclaw skills commands to find and install what you need. If you are looking to publish your own skills or need more advanced sync workflows, you can use the standalone clawhub CLI. You can find the full guide at ClawHub.

Here are the common flows you will use:

  • Install a skill into your workspace:
    • openclaw skills install <skill-slug>
  • Update all installed skills:
    • openclaw skills update --all
  • Sync (scan + publish updates):
    • clawhub sync --all

When you use the native openclaw skills install command, it places the skill directly into your active workspace skills/ directory. The clawhub CLI also defaults to installing into ./skills in your current directory. OpenClaw will automatically pick these up as <workspace>/skills the next time you start a session.

You should treat third-party skills as untrusted code. It is a good practice to read through them before you enable anything. If you are dealing with untrusted inputs or risky tools, you should prefer sandboxed runs. You can find more details in Sandboxing.

Workspace and extra-dir skill discovery is strict. It only accepts skill roots and SKILL.md files where the resolved realpath stays inside your configured root. When you use Gateway-backed skill dependency installs (like skills.install, onboarding, or the Skills settings UI), the system runs a built-in dangerous-code scanner before it executes installer metadata. If it finds critical issues, it blocks the install by default unless you explicitly set a dangerous override. Suspicious findings will still trigger a warning.

Keep in mind that openclaw skills install <slug> works differently. This command downloads a ClawHub skill folder into your workspace and does not use the installer-metadata path mentioned above. Also, skills.entries.*.env and skills.entries.*.apiKey inject secrets into the host process for that specific agent turn, not the sandbox. You should keep your secrets out of prompts and logs. For a broader threat model and checklists, check out Security.

Your SKILL.md file must include at least this frontmatter:

---
name: image-lab
description: Generate or edit images via a provider-backed image workflow
---

Here are a few things you should know:

  • The layout and intent follow the AgentSkills spec.
  • The parser used by the embedded agent only supports single-line frontmatter keys.
  • If you use metadata, it should be a single-line JSON object.
  • You can use {baseDir} in your instructions to reference the skill folder path.

You also have several optional frontmatter keys:

  • homepage: A URL that appears as “Website” in the macOS Skills UI. You can also support this via metadata.openclaw.homepage.
  • user-invocable: Set this to true or false (it defaults to true). When it is true, the skill is exposed as a user slash command.
  • disable-model-invocation: Set this to true or false (it defaults to false). When true, the skill is hidden from the model prompt but remains available via user invocation.
  • command-dispatch: You can set this to tool. When you do, the slash command bypasses the model and goes directly to a tool.
  • command-tool: The name of the tool to invoke when command-dispatch: tool is active.
  • command-arg-mode: This defaults to raw. For tool dispatch, it forwards the raw args string to the tool without core parsing.

When a tool is invoked this way, it receives these params: { command: "<raw args>", commandName: "<slash command>", skillName: "<skill name>" }.

OpenClaw filters skills at load time using the metadata field, which must be a single-line JSON object:

---
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",
},
}
---

You can use these fields under metadata.openclaw:

  • always: true: This always includes the skill and skips other gates.
  • emoji: An optional emoji for the macOS Skills UI.
  • homepage: An optional URL for the macOS Skills UI.
  • os: An optional list of platforms like darwin, linux, or win32. If you set this, the skill is only eligible on those operating systems.
  • requires.bins: A list of binaries that must exist on your PATH.
  • requires.anyBins: A list where at least one binary must exist on your PATH.
  • requires.env: A list of environment variables that must exist or be provided in your config.
  • requires.config: A list of openclaw.json paths that must be truthy.
  • primaryEnv: The environment variable name associated with skills.entries.<name>.apiKey.
  • install: An optional array of installer specs for the macOS Skills UI, supporting brew, node, go, uv, or download.

If you are using sandboxing, remember that requires.bins is checked on the host when the skill loads. If an agent is sandboxed, the binary must also exist inside the container. You can install it via agents.defaults.sandbox.docker.setupCommand or a custom image. The setupCommand runs once after the container is created. Package installs also need network egress, a writable root FS, and a root user in the sandbox. For example, the summarize skill needs the summarize CLI in the sandbox container to run there.

Here is an installer example:

---
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)",
},
],
},
}
---

If you list multiple installers, the gateway picks a single preferred option, usually brew when available, otherwise node. If all installers are set to download, OpenClaw lists each entry so you can see the available artifacts. Node installs follow the skills.install.nodeManager in your openclaw.json (npm, pnpm, yarn, or bun). This only affects skill installs; the Gateway runtime should still be Node. For Go installs, if go is missing and brew is available, the gateway installs Go via Homebrew first. Download installs require a url and support archive types like zip or tar.gz.

If no metadata.openclaw is present, the skill is always eligible unless you disable it in your config.

Config overrides (~/.openclaw/openclaw.json)

Section titled “Config overrides (~/.openclaw/openclaw.json)”

You can toggle bundled or managed skills and supply environment values in your config:

{
skills: {
entries: {
"image-lab": {
enabled: true,
apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string
env: {
GEMINI_API_KEY: "GEMINI_KEY_HERE",
},
config: {
endpoint: "https://example.invalid",
model: "nano-pro",
},
},
peekaboo: { enabled: true },
sag: { enabled: false },
},
},
}

If a skill name contains hyphens, you need to quote the key. If you want standard image generation or editing inside OpenClaw, you should use the core image_generate tool with agents.defaults.imageGenerationModel instead of a bundled skill.

For native image analysis, use the image tool with agents.defaults.imageModel. For native generation, use image_generate. If you choose a provider-specific model like openai/* or google/*, make sure to add that provider’s API key.

Config keys match the skill name by default. If a skill defines metadata.openclaw.skillKey, you should use that key under skills.entries.

Follow these rules:

  • enabled: false: This disables the skill even if it is bundled or installed.
  • env: These are injected only if the variable is not already set in the process.
  • apiKey: This is a convenience for skills that declare a primaryEnv. It supports a plaintext string or a SecretRef object.
  • config: This is an optional bag for custom per-skill fields.
  • allowBundled: This is an optional allowlist for bundled skills only. If you set this, only the bundled skills in the list are eligible.

When you start an agent run, OpenClaw handles the environment setup for you. It follows a specific sequence:

  1. It reads the skill metadata.
  2. It applies any skills.entries.<key>.env or skills.entries.<key>.apiKey settings to process.env.
  3. It builds the system prompt using the skills that are eligible.
  4. It restores your original environment after the run finishes.

This process is scoped specifically to the agent run. It is not a global shell environment change.

OpenClaw snapshots the eligible skills when a session starts to keep performance high. It reuses that list for every turn in the same session. If you make changes to your skills or configuration, those will take effect when you start a new session.

Skills can also refresh while a session is active if you have the skills watcher enabled or if a new eligible remote node appears (see below). This works like a hot reload, where the refreshed list is picked up on the next agent turn.

If you run your Gateway on Linux but have a macOS node connected with system.run allowed (make sure Exec approvals security is not set to deny), you can still use macOS-only skills. OpenClaw identifies these skills as eligible as long as the necessary binaries are present on that node. The agent then runs those skills through the exec tool using host=node.

This process works because the node reports its command support and undergoes a bin probe via system.run. If your macOS node goes offline later, the skills stay visible in the interface, but any attempts to call them will fail until the node reconnects.

You don’t need to manually refresh your setup every time you make a change. By default, OpenClaw monitors your skill folders and updates the skills snapshot when SKILL.md files are modified. You can configure this behavior under skills.load:

{
skills: {
load: {
watch: true,
watchDebounceMs: 250,
},
},
}

When your skills are eligible for use, OpenClaw puts a compact XML list of available skills into the system prompt. This happens via the formatSkillsForPrompt function in pi-coding-agent. The cost is deterministic, so you can calculate exactly how it affects your prompt size.

If you have one or more skills, you start with a base overhead of 195 characters. For each individual skill, you add 97 characters plus the length of the XML-escaped values for <name>, <description>, and <location>.

You can use this formula to find the total character count:

total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(location_escaped))

You should remember that XML escaping expands characters like & < > " ' into entities such as &amp; or &lt;, which increases the total length. Token counts change depending on the model tokenizer. A rough estimate for OpenAI-style models is about 4 characters per token. This means you are looking at roughly 24 tokens per skill plus the actual length of your fields.

OpenClaw comes with a baseline set of bundled skills as part of the installation, whether you use the npm package or OpenClaw.app.

If you need to handle local overrides, you can use the ~/.openclaw/skills directory. This is useful if you want to pin or patch a skill without modifying the bundled copy. Workspace skills are owned by you and will override both local and bundled skills if there is a name conflict.

You should check out the Skills config for the full configuration schema. It is the best place to look when you need to get your settings exactly right.

If you want to find more options, go ahead and browse https://clawhub.com.

OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.