OpenClaw Skill: How to Create Your First Custom Skill From Scratch
Step-by-step guide to creating a custom OpenClaw skill — skill anatomy, SKILL.md structure, scripts, local testing, and publishing to ClawHub.
OpenClaw Skill: How to Create Your First Custom Skill From Scratch
OpenClaw skills are how you extend your agent's capabilities beyond what ships out of the box. A skill can give your agent the ability to check a weather API, control a smart home device, query a database, or follow a specific workflow — anything you can code or describe in a Markdown file.
This guide walks through the complete process: skill anatomy, the discovery mechanism, writing your first skill step by step, testing it locally, and publishing it to ClawHub.
What Is an OpenClaw Skill?
A skill is a directory that contains two things:
- A
SKILL.mdfile that describes what the skill does and when to use it - Optional supporting files (scripts, reference data, templates)
The agent reads SKILL.md at startup and uses the description to decide whether a given user request should trigger that skill. When a match occurs, the agent follows the instructions in SKILL.md.
This design means skills can be purely instructional (no code required) or code-backed (with scripts the agent can execute). Both are valid. A skill that tells the agent "when asked about weather, do X" with no code is just as legitimate as one that runs a Python script against a live API.
Skill Anatomy
Here's the structure of a minimal skill:
my-skill/
├── SKILL.md ← required: instructions + trigger description
├── scripts/ ← optional: executable scripts
│ └── fetch-data.sh
└── references/ ← optional: static reference data
└── config.json
SKILL.md
This is the core of every skill. It must contain two things:
A description that tells the agent when to trigger this skill. This description is injected into the agent's context at startup (as part of available_skills). It needs to be precise enough that the agent selects this skill correctly, but not so broad that it fires on unrelated requests.
Instructions for what the agent should do when the skill is triggered. These can reference scripts in the scripts/ directory, data in references/, or describe a pure reasoning/workflow process.
A minimal SKILL.md:
# My Skill Name
## Description
Use this skill when the user asks about [specific topic]. Triggers on phrases like "check X", "what is the current X", or "get X status".
## Instructions
1. Run `scripts/fetch-data.sh` with the user's input as an argument
2. Parse the output and format it as a summary
3. Return the summary to the user
## Notes
- The script requires the environment variable `API_KEY` to be set
- If the API is down, return a cached result from `references/fallback.json`
scripts/
Place executable scripts here. The agent can invoke these via exec tool calls. Scripts can be bash, Python, Node.js — whatever your environment supports.
Name scripts descriptively. fetch-data.sh is better than run.sh. The agent reads the skill's file structure, so clear naming helps it reason about which script to use for which purpose.
Make scripts executable:
chmod +x scripts/fetch-data.sh
references/
Static data the skill needs — JSON configs, lookup tables, template strings, API endpoint lists. The agent can read these files directly.
Keep this lean. References are loaded into the agent's context when the skill is active, so large files increase token usage. If you need large datasets, have a script fetch them dynamically rather than storing them here.
How Skill Discovery Works
When OpenClaw starts, it scans configured skill directories and reads every SKILL.md it finds. The <description> content from each skill is injected into the agent's system prompt as part of available_skills.
The agent then uses this list to decide which skill (if any) to trigger for a given request. It reads the description, matches it against the user's intent, and if a match is found, reads the full SKILL.md before responding.
Default skill discovery paths:
- Built-in skills:
/usr/lib/node_modules/openclaw/skills/ - User skills:
~/.openclaw/skills/ - Project skills:
./skills/(relative to your workspace)
You can add custom paths in your OpenClaw config:
{
"skills": {
"paths": [
"/usr/lib/node_modules/openclaw/skills/",
"/home/user/.openclaw/skills/",
"/path/to/your/custom/skills/"
]
}
}
Skills in custom paths are discovered the same way as built-in skills. There's no registration step — drop the folder in the right place and it's live on next startup.
Writing Your First Skill: Step by Step
Let's build a real skill: one that fetches the current price of a cryptocurrency when asked.
Step 1: Create the Skill Directory
mkdir -p ~/.openclaw/skills/crypto-price/scripts
Step 2: Write the Fetch Script
cat > ~/.openclaw/skills/crypto-price/scripts/get-price.sh << 'EOF'
#!/bin/bash
# Usage: ./get-price.sh BTC
COIN="${1:-BTC}"
COIN_LOWER=$(echo "$COIN" | tr '[:upper:]' '[:lower:]')
RESPONSE=$(curl -s "https://api.coingecko.com/api/v3/simple/price?ids=${COIN_LOWER}&vs_currencies=usd")
echo "$RESPONSE"
EOF
chmod +x ~/.openclaw/skills/crypto-price/scripts/get-price.sh
Test the script directly:
~/.openclaw/skills/crypto-price/scripts/get-price.sh bitcoin
# Should output: {"bitcoin":{"usd":67432}}
Step 3: Write SKILL.md
cat > ~/.openclaw/skills/crypto-price/SKILL.md << 'EOF'
# crypto-price
## Description
Use this skill when the user asks about cryptocurrency prices. Triggers on phrases like "what's the price of", "how much is [coin]", "bitcoin price", "eth price", or any request for current crypto valuations.
## Instructions
1. Extract the cryptocurrency name or ticker from the user's request
2. Convert ticker symbols to CoinGecko IDs (BTC → bitcoin, ETH → ethereum, SOL → solana)
3. Run `scripts/get-price.sh <coin-id>` with the resolved coin ID
4. Parse the JSON response and extract the USD price
5. Return a clean response: "[Coin] is currently $[price] USD"
## Common Ticker Mappings
- BTC → bitcoin
- ETH → ethereum
- SOL → solana
- ADA → cardano
- DOT → polkadot
## Error Handling
- If the coin is not found, tell the user the ticker might be incorrect and suggest checking CoinGecko
- If the API is unreachable, say so clearly rather than returning stale data
EOF
Step 4: Restart OpenClaw
Skill discovery runs at startup. Restart to pick up the new skill:
openclaw gateway restart
Step 5: Test It
Send a message to your agent:
"What's the price of bitcoin right now?"
The agent should recognize this matches the crypto-price skill description, read the SKILL.md, execute the script, and return the current price.
Debugging a Skill That Isn't Triggering
If your skill isn't firing, check these in order:
1. Verify the skill directory is in a discovered path:
openclaw skills list
Your skill should appear in the output. If it doesn't, the path isn't configured or the SKILL.md file is missing/malformed.
2. Check the description is specific enough: A description that's too vague will get ignored in favor of built-in skills. A description that's too narrow will miss legitimate triggers. Test different phrasings of your request.
3. Look at agent reasoning: Enable reasoning output in your OpenClaw config to see why the agent is or isn't selecting your skill:
{
"agents": {
"defaults": {
"reasoning": "stream"
}
}
}
4. Test the script in isolation: Run your script directly from the terminal before expecting the agent to run it. If it fails with a permission error or missing dependency, the agent will fail too.
Adding a References File
If your skill needs static data — a list of supported currencies, API endpoint URLs, or fallback values — add it to references/:
cat > ~/.openclaw/skills/crypto-price/references/supported-coins.json << 'EOF'
{
"supported": ["bitcoin", "ethereum", "solana", "cardano", "polkadot"],
"note": "Use CoinGecko IDs, not ticker symbols"
}
EOF
Reference the file in your SKILL.md:
## References
- `references/supported-coins.json` — list of validated coin IDs
The agent will read this file when executing the skill.
Publishing to ClawHub
Once your skill works locally, you can publish it to ClawHub so other OpenClaw users can install it.
Install the ClawHub CLI
npm install -g clawhub
Log In
clawhub login
Publish
Navigate to your skill directory and publish:
cd ~/.openclaw/skills/crypto-price
clawhub publish
The CLI prompts you for:
- Skill name (slug, lowercase, hyphens)
- Version (semver:
1.0.0) - Tags (for discovery:
crypto,finance,api)
After publishing, your skill is searchable on ClawHub and installable by anyone:
clawhub install crypto-price
Versioning and Updates
When you update a skill, bump the version before publishing:
clawhub publish --version 1.1.0
Users with auto-update configured will get the new version on their next OpenClaw restart.
Skill Best Practices
Keep SKILL.md focused. One skill, one purpose. Don't try to make a skill that handles five unrelated tasks — split those into separate skills.
Make scripts idempotent. If the agent retries a script, it shouldn't break anything. Write scripts that are safe to run multiple times.
Handle failures explicitly. If your script can fail (API down, bad input, missing env var), document the failure behavior in SKILL.md so the agent can explain it clearly to the user.
Use environment variables for secrets. Never hardcode API keys in scripts. Reference $API_KEY in your script and document that the variable needs to be set.
Test the description. The most common skill problem is a description that doesn't match the agent's trigger logic. Test it with multiple phrasings. If the agent is triggering the wrong skill, or not triggering yours, the description needs refinement.
For an overview of built-in skills and how they work, see OpenClaw Skills. To understand the broader architecture, OpenClaw Architecture covers how skills fit into the agent system.
Custom skills are how you make OpenClaw yours. Once you understand the pattern, building new capabilities takes minutes, not days.
Custom skills are what let an OpenClaw setup handle everything from SEO research to content publishing at scale.