AI Engineering Curriculum
Phase 4: OpenClaw Mastery·7 min read

Module 4.2

Custom Skills

What Is a Skill?

A skill is a folder containing a single Markdown file that teaches your agent how to do something new.

That's it. No compiled code. No API registration. No plugin manifest in some proprietary format. You write a SKILL.md in plain English, drop it in the right directory, and the agent reads it — and follows the instructions.

The mental model: skills are training documents for a specific capability. Think of onboarding a new employee. You don't wire their brain with a USB cable. You hand them a document: "Here's how we handle client emails. When you see X, do Y. When you see Z, escalate to me." The agent works the same way. A skill is that document.

Real-World Use Cases

Skills power everything you'll want OpenClaw to do beyond basic conversation:

  • Daily briefing skill — pulls calendar, todos, weather, news. Triggered by "morning briefing" or /briefing.
  • Todoist skill — adds, completes, and lists tasks via the Todoist API. Triggered by "add to my list" or "what's on my list".
  • GitHub PR review skill — fetches a PR, runs a review checklist, posts a verdict. "Review PR #142."
  • Research + save skill — searches the web, synthesizes findings, saves to a file in your workspace. "Research X and save to notes."
  • Email digest skill — processes your inbox on heartbeat, categorizes by urgency, drafts replies.

The community ClawHub registry has 100+ skills covering everything from crypto trading to media control to home automation. Most of what you'll want already exists.

Key Terms

SKILL.md — the single file that defines a skill. YAML frontmatter at the top (metadata), Markdown instructions below (behavior). The agent reads both.

Frontmatter — the YAML metadata block at the very top of SKILL.md, wrapped in --- delimiters. Defines name, description, and configuration options. The agent reads this to decide whether to use the skill. The instructions below tell it how.

ClawHub — the public skills registry at clawhub.com. Browse, install, and share skills. The GitHub org is github.com/openclaw/clawhub.

User-invocable — a skill that can be triggered directly with a slash command: /skill-name. Bypasses the model's judgment about whether to use it — you're explicitly calling it.


The SKILL.md Format

Every skill is a folder with one required file inside it:

~/.openclaw/skills/
└── my-skill/
    └── SKILL.md

The SKILL.md has two parts: frontmatter (metadata) on top, instructions (behavior) below.

markdown
--- name: my-skill description: What this skill does and when to use it homepage: https://github.com/you/my-skill user-invocable: true metadata: {"openclaw": {"requires": {"bins": ["jq"]}, "os": "darwin"}} --- ## Instructions Write in natural language exactly what the agent should do. When to activate. What inputs to expect. What output to produce. What to do when things go wrong.

Required frontmatter:

name — the skill's identifier. Used as the slash command if user-invocable: true. Keep it short, lowercase, hyphenated.

description — the single most important field. More on this in a moment.

Key optional frontmatter:

user-invocable: true — exposes this skill as a /name slash command. User can trigger it directly.

disable-model-invocation: true — hides the skill from the model entirely. Only reachable via slash command. Use for skills you never want the agent to auto-invoke.

command-dispatch: tool — for slash commands, bypasses the model completely and calls a tool directly. Zero inference cost, instant execution.

metadata.openclaw.requires.bins — list of executables that must exist on PATH for this skill to load. If jq isn't installed, the skill won't appear. Clean failure instead of a broken runtime error.

metadata.openclaw.requires.env — environment variables the skill needs. If they're not set, the skill silently doesn't load.

metadata.openclaw.os — platform filter: darwin, linux, or win32. A macOS-only skill won't load on Linux.


The Description Field Is the Most Important Thing

Here's something that surprises most people: the description isn't for you. It's for the model.

OpenClaw loads skill metadata at session start and gives the model a list of available skills with their descriptions. When you send a message, the model reads that list and decides which skills are relevant to invoke. The description is how the model decides whether to use your skill.

A vague description gets ignored:

markdown
description: Helps with tasks

The model can't tell from this whether to invoke it for "add to my list" or "check the weather" or anything else. It won't gamble. It'll skip it.

A specific description gets selected:

markdown
description: Manages Todoist tasks — add, complete, list, and prioritize. Triggered by phrases like "add to my list", "check my todos", "what's due today", "mark X as done".

Now the model has signal. It knows the use cases. It knows the trigger phrases. It'll invoke reliably.

The agent implication: Write your description from the perspective of the user's actual language. How do you naturally say "I want to use this"? Use those words in the description. The model matches against them.


Where Skills Load From

OpenClaw looks for skills in three locations, in this priority order:

  1. <workspace>/skills/ — project-specific skills, highest priority
  2. ~/.openclaw/skills/ — your personal skill library, available to all agents
  3. Bundled skills — shipped with OpenClaw, lowest priority

If two skills have the same name, the one higher in the list wins. This means you can override a bundled skill by dropping a folder with the same name in ~/.openclaw/skills/.

You can also add extra directories via skills.load.extraDirs in config — useful if you keep skills in a separate git repo.

One critical behavior: skills are snapshotted when a session starts. If you add or edit a skill while a session is active, nothing changes until you start a new session. The agent isn't reloading files mid-conversation.


Installing from ClawHub

ClawHub is the community skill registry. Browse at clawhub.com. Each skill is a GitHub repo you can clone directly.

Installing is just copying:

Bash
# Clone the skill into your personal skill directory git clone https://github.com/openclaw/skill-todoist ~/.openclaw/skills/todoist # Or install multiple at once from an awesome-skills list git clone https://github.com/VoltAgent/awesome-openclaw-skills ~/skills-repo # then symlink or copy the ones you want

Start a new session. The skill is loaded.

Before installing any skill from ClawHub: read the SKILL.md. Read any scripts it runs. Understand what it does and what permissions it needs. Skills that use exec tools or external APIs need environment variables and potentially broad tool access. Know what you're installing.


Writing Your Own Skill: Step by Step

Building a custom skill is five steps:

1. Create the folder:

Bash
mkdir -p ~/.openclaw/skills/daily-briefing

2. Write the SKILL.md. Start with frontmatter, then instructions:

markdown
--- name: daily-briefing description: Generates a morning briefing with calendar events, open todos, and top news. Triggered by phrases like "morning briefing", "what's my day look like", "daily summary", "morning update". Also runs on /briefing command. user-invocable: true --- ## Daily Briefing Instructions When asked for a morning briefing or daily summary: 1. Check today's calendar events using the calendar tool. List them chronologically with time and title. 2. List open Todoist tasks due today or overdue. Show title and priority. 3. Fetch the top 3 headlines from Hacker News using web_fetch. 4. Format the output as three sections: **📅 Today's Calendar** **✅ Tasks** **📰 News** Keep the whole briefing under 400 words. Lead with the date. If a tool fails (calendar unreachable, etc.), note the failure and continue with the rest.

3. Start a new session. Skills load at session start, not mid-session.

4. Test it:

You: morning briefing
Agent: [runs the skill]

Or directly:

You: /daily-briefing

5. Iterate. If the agent doesn't invoke it when you expect, the description is the problem. Make it more specific. Add more trigger phrases. If the output isn't right, refine the instructions — be more explicit about format, edge cases, what to do when tools fail.


A Pattern That Always Works

The most reliable skills follow this instruction structure:

markdown
## When to Activate [Explicit triggers — user phrases, conditions, commands] ## What To Do [Numbered steps, specific tools, exact output format] ## Edge Cases [What to do if X fails, Y is missing, Z is ambiguous] ## Output Format [Exact structure of the response — headers, length, tone]

The model is not psychic. Vague instructions produce vague behavior. Specific instructions produce reliable behavior. Every ambiguity in your SKILL.md is a potential for the agent to do something surprising.


Gotchas

The parser only supports single-line frontmatter values. No multi-line YAML. If you write:

YAML
description: | This is a long multi-line description

It will break. Keep every frontmatter value on a single line, no matter how long.

Environment variables in requires.env must also be in ~/.openclaw/.env. Declaring them in frontmatter tells OpenClaw the skill needs them — but you still have to actually set them. The skill won't load if a required env var is missing. Check your .env first if a skill isn't appearing.

Adding a skill while a session is active does nothing. You must start a new session. If you're in a Telegram conversation and you add a skill, that conversation won't see it. Send /restart or start a new chat to reload.

Skills interact with tools — and tools need permissions. A skill that calls exec (shell commands) requires the exec tool to be in the agent's allowed tool profile. If you've locked the agent down to profile: "messaging", skills that use file or shell tools won't work. Either loosen the profile or create a dedicated agent with the right permissions for that skill.


Sources