Building OpenClaw Skills: A Complete Developer Guide to ClawHub
OpenClaw skills extend what your assistant can do. Weather, GitHub automation, email management, calendar integration. Skills are self-contained packages that add new capabilities without modifying OpenClaw core. This guide walks you through creating a skill from scratch and publishing it to ClawHub.
What is a Skill?
A skill is a folder containing:
- SKILL.md — usage guide loaded by the assistant when the skill is needed
- scripts/ — executable scripts (bash, Python, Node.js, etc.)
- config/ — optional config files or templates
- README.md — documentation for humans
- package.json or requirements.txt — dependencies (if needed)
Anatomy of SKILL.md
SKILL.md is the core of every skill. It tells the assistant:
- What the skill does
- When to use it (and when NOT to use it)
- What commands to run
- Required setup or dependencies
Minimal Example
---
name: hello
description: Simple greeting skill that says hello
---
# Hello Skill
Greet the user with a friendly message.
## Usage
Run:bash
echo "Hello from the Hello skill!"
That's it.
Full Example with Metadata
---
name: weather
description: Get current weather and forecasts via wttr.in. Use when user asks about weather, temperature, or forecasts for any location.
homepage: https://wttr.in/:help
metadata:
openclaw:
emoji: 🌤️
requires:
bins: ["curl"]
---
# Weather Skill
Get current weather conditions and forecasts.
## When to Use
✅ **USE this skill when:**
- "What's the weather?"
- "Will it rain today/tomorrow?"
- "Temperature in [city]"
## When NOT to Use
❌ **DON'T use this skill when:**
- Historical weather data (use weather archives instead)
- Severe weather alerts (check official NWS sources)
## Commands
### Current Weatherbash
curl "wttr.in/London?format=3"
### 3-Day Forecastbash
curl "wttr.in/London"
Key sections:
- Frontmatter (YAML between
---) — skill metadata - When to Use — helps the assistant decide when this skill applies
- When NOT to Use — prevents misuse
- Commands — exact commands to run
Creating Your First Skill
Let's build a skill that fetches cryptocurrency prices.
Step 1: Create the Skill Folder
mkdir -p ~/skills/crypto-price
cd ~/skills/crypto-price
Step 2: Write SKILL.md
---
name: crypto-price
description: Fetch real-time cryptocurrency prices via CoinGecko API. Use when user asks about crypto prices, Bitcoin, Ethereum, or token values.
metadata:
openclaw:
emoji: 💰
requires:
bins: ["curl", "jq"]
---
# Crypto Price Skill
Fetch current cryptocurrency prices.
## When to Use
✅ **USE when:**
- "What's the price of Bitcoin?"
- "Check Ethereum price"
- "How much is BTC worth?"
## Commands
### Get Pricebash
curl -s "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd" | jq -r .bitcoin.usd
### Multiple Coinsbash
curl -s "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,solana&vs_currencies=usd" | jq
## Notes
- Free API, no key needed
- Rate limit: ~50 requests/minute
Save as SKILL.md.
Step 3: Test It
Install the skill locally:
clawhub install ~/skills/crypto-price --local
Verify it's installed:
clawhub list
Now ask your assistant:
"What's the Bitcoin price?"
The assistant should:
curl command from SKILL.mdStep 4: Add a Script (Optional)
For more complex logic, add a script:
scripts/get-price.sh:
#!/usr/bin/env bash
set -euo pipefail
COIN=${1:-bitcoin}
VS_CURRENCY=${2:-usd}
URL="https://api.coingecko.com/api/v3/simple/price"
RESP=$(curl -s "$URL?ids=$COIN&vs_currencies=$VS_CURRENCY")
PRICE=$(echo "$RESP" | jq -r ".$COIN.$VS_CURRENCY")
echo "$COIN: \$PRICE $VS_CURRENCY"
Make it executable:
chmod +x scripts/get-price.sh
Update SKILL.md:
## Commands
### Get Pricebash
./scripts/get-price.sh bitcoin usd
./scripts/get-price.sh ethereum usd
Step 5: Publish to ClawHub
Create an account:
clawhub login
Publish:
clawhub publish ~/skills/crypto-price \
--slug crypto-price \
--name "Crypto Price" \
--version 1.0.0 \
--changelog "Initial release"
Your skill is now on ClawHub! Others can install it:
clawhub install crypto-price
Advanced: Dependencies
Node.js Dependencies
If your skill needs npm packages, include package.json:
{
"name": "my-skill",
"version": "1.0.0",
"dependencies": {
"axios": "^1.6.0"
}
}
During installation, ClawHub runs npm install automatically.
Python Dependencies
Include requirements.txt:
requests==2.31.0
beautifulsoup4==4.12.2
ClawHub runs pip install -r requirements.txt on install.
System Binaries
Declare required binaries in frontmatter:
metadata:
openclaw:
requires:
bins: ["curl", "jq", "ffmpeg"]
OpenClaw checks for these and warns if missing.
Best Practices
1. Write Clear When to Use Sections
Help the assistant decide when your skill applies:
## When to Use
✅ **USE when:**
- Specific, concrete examples
- Trigger phrases users would actually say
## When NOT to Use
❌ **DON'T use when:**
- Cases where a different skill or tool is better
2. Provide Exact Commands
Don't say "use curl to fetch...". Show the exact command:
## Fetch GitHub Issuesbash
gh issue list --repo owner/repo --json number,title --jq .[] | "\(.number): \(.title)"
3. Include Error Handling
If a command can fail, show how to handle it:
if ! command -v gh &>/dev/null; then
echo "Error: gh CLI not installed. Run: brew install gh"
exit 1
fi
4. Keep Skills Focused
One skill = one capability. Don't bundle weather + crypto + calendar into "utils".
Good:
- weather
- crypto-price
- github-issues
- utils (does everything)
5. Test Before Publishing
Run through the commands manually:
cd ~/skills/my-skill
bash -x scripts/my-script.sh # Debug mode
Ask your assistant to use the skill. Does it work as expected?
ClawHub CLI Reference
Install
npm install -g clawhub
Login
clawhub login
clawhub whoami
Search
clawhub search "postgres backups"
Install
clawhub install my-skill
clawhub install my-skill --version 1.2.3
clawhub install ~/local/skill --local
Update
clawhub update my-skill
clawhub update --all
Publish
clawhub publish ./my-skill \
--slug my-skill \
--name "My Skill" \
--version 1.2.0 \
--changelog "Added X, fixed Y"
List Installed Skills
clawhub list
Skill Discovery
How does OpenClaw know when to load a skill?
Automatic (Recommended)
OpenClaw scans installed skills and loads the SKILL.md when:
description matches the user's queryNo manual skill loading needed. It just works.
Manual (Advanced)
You can force-load a skill:
/skills load weather
Or check what skills are available:
/skills list
Publishing Updates
When you fix bugs or add features, publish a new version:
clawhub publish ./my-skill \
--slug my-skill \
--version 1.1.0 \
--changelog "Fixed API endpoint, added error handling"
Users can update:
clawhub update my-skill
Versioning
Use semantic versioning:
- 1.0.0 — initial release
- 1.0.1 — bug fixes
- 1.1.0 — new features, backward compatible
- 2.0.0 — breaking changes
Example: Full-Featured Skill
Here's a production-ready skill structure:
my-skill/
SKILL.md
README.md
LICENSE
package.json
scripts/
main.sh
lib/
helpers.sh
tests/
test.sh
examples/
example1.sh
SKILL.md:
---
name: my-skill
description: Does something useful
homepage: https://github.com/user/my-skill
metadata:
openclaw:
emoji: ⚡
requires:
bins: ["curl", "jq"]
install:
- id: brew
kind: brew
formula: my-tool
bins: ["my-tool"]
---
# My Skill
[Full documentation here]
Troubleshooting
Skill Not Loading
Verify it's installed:
clawhub list | grep my-skill
Check OpenClaw skills directory:
ls ~/.openclaw/skills/
Commands Failing
Run the command manually:
cd ~/.openclaw/skills/my-skill
bash scripts/main.sh
Check for missing dependencies:
command -v curl jq ffmpeg
Conclusion
Skills are the building blocks of an extensible AI assistant. Create focused, well-documented skills, publish them to ClawHub, and help the entire community. Start with SKILL.md, add scripts as needed, test thoroughly, and publish.
Extend the platform. 🦞