✍️ Blog Post

Building Custom Skills: A Complete Guide

18 min read

Custom skills are how you extend OpenClaw beyond its bundled capabilities. Here's everything I've learned building 10+ skills—from SKILL.md format to progressive disclosure patterns.

What Are Skills?

Skills are modular, self-contained packages that teach an agent how to use tools. Each skill is a directory containing a SKILL.md file with YAML frontmatter and Markdown instructions, optionally accompanied by scripts, references, and assets.

Think of skills as "onboarding guides" for specific domains. They transform a general-purpose agent into a specialized agent equipped with procedural knowledge no model fully possesses.

Skill Anatomy

Every skill has this structure:

skill-name/
├── SKILL.md (required)
└── Bundled Resources (optional)
    ├── scripts/      - Executable code
    ├── references/   - Documentation loaded as needed
    └── assets/       - Files used in output

SKILL.md (Required)

The SKILL.md file has two parts:

1. YAML Frontmatter (Required)

---
name: my-skill
description: "What the skill does and when to use it"
metadata: { "openclaw": { "emoji": "🛠️" } }
---

The description is critical—it's the primary trigger mechanism. Include:

  • What the skill does
  • Specific contexts for when to use it
  • Key capabilities or features

2. Markdown Body

Instructions and guidance for using the skill. This is only loaded AFTER the skill triggers, so keep trigger information in the description, not the body.

Optional Resources

Scripts (scripts/)

Executable code (Python, Bash, etc.) for tasks requiring deterministic reliability or code that gets rewritten repeatedly.

  • When to include: Same code is being rewritten repeatedly or deterministic reliability is needed
  • Benefits: Token efficient, may be executed without loading into context
  • Example: A rotate_pdf.py script for PDF rotation tasks

References (references/)

Documentation and reference material loaded as needed to inform the agent's process.

  • Use cases: Database schemas, API docs, domain knowledge, company policies, workflow guides
  • Benefits: Keeps SKILL.md lean, loaded only when needed
  • Best practice: If files are large (>10k words), include grep search patterns in SKILL.md

Assets (assets/)

Files not loaded into context, but used within the output.

  • Use cases: Templates, images, boilerplate code, fonts, sample documents
  • Example: assets/frontend-template/ for HTML/React boilerplate

Core Design Principles

1. Concise is Key

The context window is a public good. Skills share it with system prompt, conversation history, other skills, and the actual user request.

Default assumption: The agent is already very smart. Only add context the agent doesn't already have. Challenge each piece of information: "Does the agent really need this explanation?"

Prefer concise examples over verbose explanations.

2. Progressive Disclosure

Skills use a three-level loading system:

  1. Metadata (name + description) — Always in context (~100 words)
  2. SKILL.md body — When skill triggers (<5k words)
  3. Bundled resources — As needed by the agent

Keep SKILL.md body under 500 lines. When approaching this limit, split content into separate reference files.

Pattern: High-level guide with references

# PDF Processing

## Quick start
Extract text with pdfplumber:
[code example]

## Advanced features
- **Form filling**: See [FORMS.md](FORMS.md) for complete guide
- **API reference**: See [REFERENCE.md](REFERENCE.md) for all methods

3. Set Appropriate Degrees of Freedom

Match the level of specificity to the task's fragility and variability:

  • High freedom (text-based instructions): When multiple approaches are valid, decisions depend on context
  • Medium freedom (pseudocode or scripts with parameters): When a preferred pattern exists, some variation is acceptable
  • Low freedom (specific scripts, few parameters): When operations are fragile, consistency is critical

Skill Creation Process

Step 1: Understand the Use Cases

Start with concrete examples. What will users ask? What tasks should the skill handle?

Example questions:

  • "What functionality should the skill support?"
  • "Can you give examples of how this skill would be used?"
  • "What would a user say that should trigger this skill?"

Step 2: Plan Reusable Contents

Analyze each example and identify what scripts, references, and assets would be helpful.

Example: For a pdf-editor skill:

  • Rotating a PDF requires re-writing the same code each time → Create scripts/rotate_pdf.py
  • Working with PDFs needs form field knowledge → Create references/form-fields.md

Step 3: Initialize the Skill

Use the init_skill.py script to generate the template:

scripts/init_skill.py my-skill --path skills/public --resources scripts,references

This creates:

  • Skill directory at the specified path
  • SKILL.md template with proper frontmatter and TODO placeholders
  • Resource directories based on --resources

Step 4: Implement the Skill

A. Write Bundled Resources

Start with scripts, references, and assets. Test scripts by actually running them.

B. Write SKILL.md Frontmatter

---
name: pdf-editor
description: "Edit, rotate, and manipulate PDF files. Use when working with PDF documents for: (1) Rotating pages, (2) Extracting text, (3) Filling forms, (4) Merging PDFs"
metadata: { "openclaw": { "emoji": "📄", "requires": { "bins": ["pdfplumber"] } } }
---

C. Write SKILL.md Body

Instructions for using the skill. Use imperative form:

  • ✓ "Use pdfplumber to extract text"
  • ✗ "You can use pdfplumber to extract text"

Step 5: Package the Skill

Run the packaging script to validate and create a distributable .skill file:

scripts/package_skill.py path/to/skill-folder

The script validates:

  • YAML frontmatter format and required fields
  • Skill naming conventions and directory structure
  • Description completeness and quality
  • File organization and resource references

Step 6: Iterate

Use the skill on real tasks. Notice struggles. Improve SKILL.md or bundled resources. Test again.

Skill Loading & Precedence

OpenClaw loads skills from three locations:

  1. Workspace skills: <workspace>/skills (highest precedence)
  2. Managed skills: ~/.openclaw/skills
  3. Bundled skills: Shipped with OpenClaw (lowest precedence)

If a skill name conflicts, workspace wins, then managed, then bundled.

Skill Gating (Load-Time Filters)

Skills can specify requirements using metadata:

metadata: {
  "openclaw": {
    "requires": {
      "bins": ["ffmpeg"],        // Must exist on PATH
      "anyBins": ["uv", "pip"],  // At least one must exist
      "env": ["API_KEY"],         // Env var must exist
      "config": ["browser.enabled"],  // Config path must be truthy
      "os": ["darwin", "linux"]   // Platform check
    },
    "primaryEnv": "API_KEY",     // Env var name for skill
    "always": true               // Skip all gates
  }
}

Publishing to ClawHub

Once your skill is tested and packaged, publish it to ClawHub:

  1. Create an account at clawhub.com
  2. Upload your .skill file
  3. Add description, tags, and examples
  4. Publish

Users can then install with:

clawhub install your-skill-slug

Real Example: video-frames Skill

Let's walk through a real skill I built:

SKILL.md:

---
name: video-frames
description: "Extract frames or short clips from videos using ffmpeg."
metadata: {
  "openclaw": {
    "emoji": "🎞️",
    "requires": { "bins": ["ffmpeg"] }
  }
}
---

# Video Frames (ffmpeg)

Extract a single frame from a video for inspection.

## Quick start

First frame:
```bash
{baseDir}/scripts/frame.sh /path/to/video.mp4 --out /tmp/frame.jpg
```

At a timestamp:
```bash
{baseDir}/scripts/frame.sh /path/to/video.mp4 --time 00:00:10 --out /tmp/frame-10s.jpg
```

## Notes
- Use .jpg for quick share; use .png for crisp UI frames.

scripts/frame.sh:

#!/usr/bin/env bash
# Extract frame from video using ffmpeg

VIDEO="$1"
TIME="${2:-00:00:00}"
OUT="${3:-/tmp/frame.jpg}"

ffmpeg -ss "$TIME" -i "$VIDEO" -vframes 1 -q:v 2 "$OUT"

Why it works:

  • Simple SKILL.md with clear examples
  • Script handles the ffmpeg complexity
  • Gates on ffmpeg binary
  • Under 100 lines total

Common Mistakes

1. Verbose SKILL.md Body

Problem: 2000-line SKILL.md that explains basic concepts the agent already knows.

Fix: Challenge every paragraph. Move detailed docs to references files. Keep SKILL.md under 500 lines.

2. Poor Description

Problem: Description doesn't include trigger contexts, so skill never activates.

Fix: Include "Use when..." phrases in description with specific scenarios.

3. Missing Gating

Problem: Skill loads but fails because dependencies aren't installed.

Fix: Add requires.bins and requires.env to metadata.

4. Creating Auxiliary Files

Problem: Adding README.md, CHANGELOG.md, etc. that clutter the skill.

Fix: Skills are for agents, not humans. Only include SKILL.md and resources needed for the task.

Best Practices I Follow

  1. Test with real tasks: Don't fake it. Use the skill for actual work.
  2. Start small: Build a minimal skill first. Add complexity only when needed.
  3. Use init_skill.py: Don't hand-write templates. Use the generator.
  4. Reference don't duplicate: If information exists elsewhere, link to it.
  5. Gate appropriately: Check requirements at load time, fail fast.
  6. Version bundled scripts: Scripts can evolve. Note versions in comments.
  7. Document the trigger: Make it obvious when the skill should activate.

Advanced Patterns

Conditional References

For skills supporting multiple frameworks:

# Cloud Deploy Skill

## Choose your provider
- AWS: See [AWS.md](references/AWS.md)
- GCP: See [GCP.md](references/GCP.md)
- Azure: See [AZURE.md](references/AZURE.md)

Agent reads only the relevant reference file.

Multi-Domain Skills

For skills covering multiple domains, organize by domain:

bigquery-skill/
├── SKILL.md (overview and navigation)
└── references/
    ├── finance.md
    ├── sales.md
    ├── product.md
    └── marketing.md

When user asks about sales metrics, agent reads only sales.md.

The Bottom Line

Skills are how you teach OpenClaw your workflows. Good skills are concise, well-gated, and progressively disclose information.

Start with init_skill.py. Write a clear description. Keep SKILL.md lean. Test with real tasks. Package and iterate.

The best skills feel invisible—they just work. And when they work, they transform what your agent can do.

For a deeper dive into TypeScript-based skills with production patterns, see Building Custom OpenClaw Skills: Complete Developer Guide.

Ready to build?

Get the OpenClaw Starter Kit — config templates, 5 production-ready skills, deployment checklist. Go from zero to running in under an hour.

$14 $6.99

Get the Starter Kit →

Also in the OpenClaw store

🗂️
Executive Assistant Config
Buy
Calendar, email, daily briefings on autopilot.
$6.99
🔍
Business Research Pack
Buy
Competitor tracking and market intelligence.
$5.99
Content Factory Workflow
Buy
Turn 1 post into 30 pieces of content.
$6.99
📬
Sales Outreach Skills
Buy
Automated lead research and personalized outreach.
$5.99

Get the free OpenClaw quickstart guide

Step-by-step setup. Plain English. No jargon.