Create Your Own Skill

Build custom skills for OpenClaw. Learn the skill structure, write SKILL.md, add scripts and references, test locally, and publish to ClawHub.

Platform: Any
Cost: Free
Time: 30 minutes
Difficulty: Intermediate

Create Your Own OpenClaw Skill

Skills are the building blocks that give OpenClaw new capabilities. This guide walks you through creating, testing, and publishing your own custom skill.

What Are Skills?

Skills are small, focused packages that teach OpenClaw how to do specific tasks. They contain:

  • Instructions (SKILL.md) — What the skill does and how to use it
  • Scripts (optional) — Executable code for complex operations
  • References (optional) — Documentation the agent can consult
  • Assets (optional) — Templates, images, or other files

When you ask OpenClaw something, it scans available skills and loads the relevant one based on its description. The skill's instructions then guide the agent through the task.

Why Create a Skill?

  • Consistency — Encode your workflows so OpenClaw follows them every time
  • Domain knowledge — Teach OpenClaw about your company's APIs, schemas, or processes
  • Reusable tools — Package scripts that would otherwise be rewritten repeatedly
  • Share with others — Publish to ClawHub for the community

Skill Structure

Every skill follows this structure:

my-skill/
├── SKILL.md          # Required: Instructions and metadata
├── scripts/          # Optional: Executable code
│   └── process.py
├── references/       # Optional: Documentation to load as needed
│   └── api-docs.md
└── assets/           # Optional: Templates, images, etc.
    └── template.html

The only required file is SKILL.md. Everything else is optional.


Step 1: Plan Your Skill

Before writing code, answer these questions:

  1. What task does this skill help with?

    • Be specific: "Rotate PDF pages" not "Work with PDFs"
  2. What triggers should activate this skill?

    • Think about what users will say: "rotate this PDF", "flip the page", "turn PDF sideways"
  3. What resources does it need?

    • Scripts for deterministic operations?
    • Reference docs for complex domains?
    • Templates or assets for output?

Example: Weather Alert Skill

Let's build a skill that checks weather and sends alerts:

  • Task: Check weather for a location and alert if conditions are severe
  • Triggers: "weather alert", "storm warning", "check for severe weather"
  • Resources: A script to fetch weather data

Step 2: Create the SKILL.md

The SKILL.md file has two parts:

  1. YAML frontmatter — Metadata that's always in context
  2. Markdown body — Instructions loaded when the skill triggers

Frontmatter (Required)

---
name: weather-alert
description: Check weather conditions and send alerts for severe weather. Use when asked to monitor weather, check for storms, set up weather alerts, or get severe weather warnings for any location.
---

The description is critical — it determines when OpenClaw uses your skill. Include:

  • What the skill does
  • Specific phrases that should trigger it
  • When NOT to use it (if relevant)

Body (Required)

Write clear, concise instructions:

# Weather Alert

Check weather conditions and alert on severe weather.

## Usage

1. Get the location from the user (city, zip code, or coordinates)
2. Fetch current conditions using the weather API
3. Check for severe weather indicators:
   - Wind speed > 50 mph
   - Tornado watch/warning
   - Flash flood warning
   - Extreme temperatures (<0°F or >100°F)
4. If severe conditions found, send an alert via the user's preferred channel

## API

Use wttr.in for weather data:

```bash
curl "wttr.in/Denver?format=j1"

Alert Format

Keep alerts brief and actionable:

⚠️ WEATHER ALERT: Denver, CO
Condition: High winds (65 mph gusts)
Action: Secure outdoor items, avoid travel if possible
Valid until: 6:00 PM MST

### Writing Tips

- **Be concise** — The context window is shared with everything else
- **Use examples** — Show don't tell
- **Assume intelligence** — OpenClaw is smart; only explain non-obvious things
- **Imperative mood** — "Check the weather" not "You should check the weather"

---

## Step 3: Add Scripts (Optional)

For tasks that need deterministic reliability, add scripts:

my-skill/ ├── SKILL.md └── scripts/ └── fetch_weather.py


**scripts/fetch_weather.py:**

```python
#!/usr/bin/env python3
"""Fetch weather data from wttr.in"""

import sys
import json
import urllib.request

def get_weather(location: str) -> dict:
    """Fetch weather for a location."""
    url = f"https://wttr.in/{location}?format=j1"
    with urllib.request.urlopen(url) as response:
        return json.loads(response.read())

def check_severe(data: dict) -> list:
    """Check for severe weather conditions."""
    alerts = []
    current = data["current_condition"][0]
    
    # Check wind speed
    wind_mph = int(current.get("windspeedMiles", 0))
    if wind_mph > 50:
        alerts.append(f"High winds: {wind_mph} mph")
    
    # Check temperature
    temp_f = int(current.get("temp_F", 70))
    if temp_f < 0:
        alerts.append(f"Extreme cold: {temp_f}°F")
    elif temp_f > 100:
        alerts.append(f"Extreme heat: {temp_f}°F")
    
    return alerts

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: fetch_weather.py <location>")
        sys.exit(1)
    
    location = sys.argv[1]
    data = get_weather(location)
    alerts = check_severe(data)
    
    if alerts:
        print("⚠️ SEVERE WEATHER ALERTS:")
        for alert in alerts:
            print(f"  - {alert}")
    else:
        print("✓ No severe weather conditions")

Reference it in SKILL.md:

## Checking Weather

Run the weather script:

```bash
python scripts/fetch_weather.py "Denver, CO"

The script returns alerts for:

  • Wind > 50 mph
  • Temperature < 0°F or > 100°F

---

## Step 4: Add References (Optional)

For complex domains, add reference documentation:

my-skill/ ├── SKILL.md └── references/ └── weather-codes.md


Reference docs are loaded **only when needed**, keeping the context lean.

In SKILL.md, tell OpenClaw when to use them:

```markdown
## Weather Codes

For interpreting weather condition codes, see [references/weather-codes.md](references/weather-codes.md).

Step 5: Test Locally

Install Your Skill

Copy your skill to the OpenClaw skills directory:

# Find your workspace
cd ~/.openclaw/workspace

# Create skills directory if needed
mkdir -p skills

# Copy your skill
cp -r /path/to/my-skill skills/

Verify It's Loaded

openclaw skills list

Your skill should appear in the list.

Test It

Start a conversation with OpenClaw and try phrases that should trigger your skill:

You: Check the weather alerts for Denver
OpenClaw: [Should use your weather-alert skill]

Debug Tips

If your skill isn't triggering:

  1. Check the description — Does it include the phrases you're using?
  2. Check for errors — Run openclaw logs | grep -i "skill"
  3. Restart the gatewayopenclaw gateway restart

If your skill triggers but doesn't work:

  1. Test scripts manually — Run them outside OpenClaw first
  2. Check file paths — Use relative paths from the skill directory
  3. Simplify — Start with minimal instructions, add complexity gradually

Step 6: Publish to ClawHub

Ready to share? Publish to ClawHub so others can install your skill with one command.

Prerequisites

  1. Create a ClawHub account at clawhub.com
  2. Install the ClawHub CLI:
    npm install -g clawhub
    
  3. Log in:
    clawhub login
    

Prepare for Publishing

Add a clawhub.json to your skill:

{
  "name": "weather-alert",
  "version": "1.0.0",
  "description": "Check weather and alert on severe conditions",
  "author": "your-username",
  "license": "MIT",
  "keywords": ["weather", "alerts", "notifications"],
  "repository": "https://github.com/you/weather-alert-skill"
}

Publish

cd my-skill
clawhub publish

Others Can Install

npx clawhub install weather-alert

Best Practices

Keep It Focused

One skill = one job. Don't create a "do everything" skill.

❌ Bad: office-tools — handles PDFs, spreadsheets, docs, and presentations ✅ Good: pdf-rotate — rotates PDF pages

Write Good Descriptions

The description determines when your skill triggers. Be comprehensive:

# ❌ Bad - too vague
description: Work with weather data

# ✅ Good - specific triggers included
description: Check weather conditions and send alerts for severe weather. Use when asked to monitor weather, check for storms, set up weather alerts, or get severe weather warnings for any location.

Use Progressive Disclosure

Don't dump everything in SKILL.md. Use the three-level system:

  1. Frontmatter (~100 words) — Always loaded
  2. SKILL.md body (<500 lines) — Loaded when triggered
  3. References (unlimited) — Loaded on demand

Test with Real Users

The best skills come from iteration:

  1. Build a minimal version
  2. Use it on real tasks
  3. Notice what's missing or confusing
  4. Improve and repeat

Example Skills

Minimal Skill (Instructions Only)

git-commit-message/
└── SKILL.md
---
name: git-commit-message
description: Generate conventional commit messages. Use when asked to write a commit message, format a commit, or follow conventional commits.
---

# Git Commit Message

Generate commit messages following the Conventional Commits spec.

## Format

<type>(<scope>): <subject>

<body> <footer> ```

Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation only
  • style: Formatting, no code change
  • refactor: Code change that neither fixes nor adds
  • test: Adding tests
  • chore: Maintenance

Examples

feat(auth): add OAuth2 login support

Implements Google and GitHub OAuth providers.
Closes #123
fix(api): handle null response from payment gateway

### Script-Heavy Skill

image-resize/ ├── SKILL.md └── scripts/ └── resize.py


### Reference-Heavy Skill

company-api/ ├── SKILL.md └── references/ ├── endpoints.md ├── authentication.md └── error-codes.md


---

## Troubleshooting

### Skill Not Appearing in List

- Check the SKILL.md has valid YAML frontmatter
- Ensure `name` and `description` fields exist
- Verify the skill is in `~/.openclaw/workspace/skills/`

### Skill Not Triggering

- Review the `description` — does it match what users say?
- Check for typos in the skill name
- Restart the gateway: `openclaw gateway restart`

### Scripts Not Running

- Check file permissions: `chmod +x scripts/*.py`
- Verify the shebang line: `#!/usr/bin/env python3`
- Test the script directly: `python scripts/myscript.py`

### "File Not Found" Errors

- Use relative paths from the skill directory
- Don't use absolute paths or `~/`
- Check the file actually exists

---

## What's Next?

- **[Browse Skills](/skills)** — See what others have built
- **[Post-Install Setup](/guides/post-install)** — Make sure OpenClaw is configured
- **[ClawHub](https://clawhub.com)** — Publish and discover skills

### Community

Share your skills and get feedback:

- **Discord**: [discord.gg/clawd](https://discord.gg/clawd)
- **GitHub**: [github.com/openclaw/openclaw](https://github.com/openclaw/openclaw)

Get More OpenClaw Tips

Weekly guides, new skills, and workflow recipes. No spam.