The meta-skill. This skill teaches AI agents how to build, validate, and publish skills on ClawHub. If you're creating a new skill, this is your blueprint.
Every skill is a directory containing at minimum a SKILL.md file. The directory name should be kebab-case and match the skill name.
text
skills/
my-skill-name/
SKILL.md # Required: the skill definition
references/ # Optional: supplementary material
api-docs.md
examples.md
cheatsheet.md
scripts/ # Optional: automation scripts
validate.sh
install.sh
markdown
---
name: my-skill-name
description: 'One paragraph. What it does. When to trigger. When NOT to trigger.'
license: MIT
metadata:
openclaw:
emoji: '🔧'
---
# Skill Title
[Brief overview — 2-3 sentences max]
## When to Use
[Bulleted list of trigger conditions]
## When NOT to Use
[Bulleted list of exclusion conditions — REQUIRED]
---
## Section 1: [Topic]
[Content with examples]
## Section 2: [Topic]
[Content with examples]
...
The frontmatter block is the machine-readable identity of the skill. It must be valid YAML between --- delimiters.
FieldTypeDescriptionExamplenamestringKebab-case identifier, unique on ClawHubfinancial-analysis-agent``descriptionstringSingle-quoted paragraph. Must include trigger AND exclusion.See belowlicensestringSPDX identifierMIT, Apache-2.0, CC-BY-4.0
FieldTypeDescriptionExampleversionstringSemver1.0.0``authorstringCreator name or handle@openclaw``tagslistDiscovery tags[finance, analysis, cfp]``dependslistOther skills this depends on[agent-memory-architecture]``metadata.openclaw.emojistringDisplay emoji on ClawHub'💰'``metadata.openclaw.tierstringComplexity tierfoundational, intermediate, advanced``metadata.openclaw.modelslistModels this skill works best with[claude-opus-4-6, claude-sonnet-4-6]
The description field is the most important field. It's what agents use to decide whether to load the skill. It must be:
Good:
yaml
description: 'Financial analysis skill for AI agents. Covers variance analysis, cash flow forecasting, month-end close automation, CFO commentary generation. Do NOT use for tax preparation, audit opinions, or regulatory filings.'
Bad:
yaml
description: 'A skill for finance stuff.'
Bad:
yaml
description: 'Comprehensive enterprise-grade financial analysis solution leveraging AI-powered insights for transformative business intelligence.'
The references/ directory holds supplementary material that the skill can point to but that shouldn't be in the main SKILL.md (to keep it focused).
references/file.md is fine. references/sub/file.md is not.api-authentication.md not ref1.md.Content TypeLocationRationaleCore methodologySKILL.mdAgent needs this to executeQuick reference tablesSKILL.mdFrequently accessedDetailed API docsreferences/Only needed for specific tasksExtended examplesreferences/Useful but not essentialCheat sheetsreferences/Quick lookup, not learningHistorical contextreferences/Background, not action
text
skills/financial-analysis-agent/
SKILL.md
references/
gaap-ifrs-differences.md # Detailed comparison table
ratio-benchmarks-by-industry.md # Industry-specific ratio ranges
asc-606-checklist.md # Revenue recognition deep dive
sample-board-package.md # Example board reporting package
Every skill MUST define what it does NOT do. This is not optional — it's the most important part of skill design after the core content.
Without negative boundaries:
For every skill, explicitly answer:
markdown
## When NOT to Use
- [Adjacent skill 1] — use [other-skill-name] instead
- [Adjacent skill 2] — use [other-skill-name] instead
- [Common misconception] — this skill does not cover [X]
- Tasks requiring [thing above scope ceiling] — escalate to [human/specialist]
- Simple [thing below scope floor] — just do it directly, no skill needed
markdown
## When NOT to Use
- Tax preparation or tax advisory — use crypto-tax-agent or consult a CPA
- Audit opinions or attestation — requires human CPA, not an agent skill
- Regulatory filings (SEC 10-K, etc.) — use a compliance-specific skill
- Simple arithmetic or unit conversions — just calculate directly
- Investment advice or stock picks — this is analysis, not advisory
When building a new skill, interview yourself (or the skill author) with these questions to produce a high-quality description.
text
Q: What specific phrases would someone say that should activate this skill?
A: List 5-10 trigger phrases.
Example:
- "Analyze the variance between budget and actual"
- "Generate a 13-week cash flow forecast"
- "Write CFO commentary for the board package"
- "Review the financial statements before close"
text
Q: What phrases sound similar but should NOT activate this skill?
A: List 5-10 exclusion phrases.
Example:
- "File our tax return" → tax skill, not this one
- "Should we invest in X stock?" → not advisory
- "Audit the financial statements" → requires CPA
text
Q: What other skills or knowledge does this skill assume?
A: List prerequisites.
Example:
- Basic accounting knowledge (debits/credits)
- Access to financial data (GL, subledger)
- Familiarity with Excel/Sheets for output formatting
Combine triggers, exclusions, and dependencies into a single paragraph:
yaml
description: '[What it does — 1 sentence]. Covers [trigger keywords]. Assumes [dependencies]. Do NOT use for [exclusions].'
Ask: "If an agent read only this description, would it correctly decide to load or skip this skill for these 10 test queries?"
Test with 5 queries that SHOULD trigger and 5 that should NOT.
The scripts/ directory holds automation for skill lifecycle operations.
bash
# scripts/validate.sh — Check skill quality
#!/bin/bash
set -euo pipefail
SKILL_DIR="$(dirname "$0")/.."
SKILL_FILE="$SKILL_DIR/SKILL.md"
# Check SKILL.md exists
[[ -f "$SKILL_FILE" ]] || { echo "FAIL: SKILL.md not found"; exit 1; }
# Check frontmatter exists
head -1 "$SKILL_FILE" | grep -q "^---$" || { echo "FAIL: Missing frontmatter"; exit 1; }
# Check required fields
grep -q "^name:" "$SKILL_FILE" || { echo "FAIL: Missing name field"; exit 1; }
grep -q "^description:" "$SKILL_FILE" || { echo "FAIL: Missing description field"; exit 1; }
grep -q "^license:" "$SKILL_FILE" || { echo "FAIL: Missing license field"; exit 1; }
# Check negative boundaries exist
grep -q "When NOT to Use" "$SKILL_FILE" || { echo "FAIL: Missing negative boundaries"; exit 1; }
# Check description includes exclusions
DESC=$(grep "^description:" "$SKILL_FILE")
echo "$DESC" | grep -qi "not\|don't\|do not\|except\|exclud" || {
echo "WARN: Description may lack exclusion language"
}
# Check references depth
if [[ -d "$SKILL_DIR/references" ]]; then
DEPTH=$(find "$SKILL_DIR/references" -mindepth 2 -type f | wc -l)
[[ "$DEPTH" -eq 0 ]] || { echo "FAIL: References nested >1 level deep"; exit 1; }
fi
echo "PASS: Skill validation complete"
bash
# scripts/install.sh — Install skill into agent workspace
#!/bin/bash
set -euo pipefail
SKILL_NAME="$(basename "$(dirname "$0")/..")"
TARGET="${1:-$HOME/.openclaw/workspace/skills}"
echo "Installing $SKILL_NAME to $TARGET/$SKILL_NAME"
cp -r "$(dirname "$0")/.." "$TARGET/$SKILL_NAME"
echo "Done. Skill available at $TARGET/$SKILL_NAME/SKILL.md"
ClawHub is the registry for discovering, installing, and publishing skills.
bash
# Search for skills
clawhub search "financial analysis"
clawhub search --tag finance
clawhub search --emoji 💰
# View skill details
clawhub info financial-analysis-agent
clawhub info financial-analysis-agent --versions
# Install a skill
clawhub install financial-analysis-agent
clawhub install financial-analysis-agent@1.2.0
clawhub install financial-analysis-agent --path ./my-skills/
# Publish a skill
clawhub publish ./skills/my-skill/
clawhub publish ./skills/my-skill/ --dry-run # Validate without publishing
# Update skills
clawhub update # Update all installed skills
clawhub update financial-analysis-agent # Update specific skill
clawhub outdated # List skills with available updates
# List installed skills
clawhub list
clawhub list --format json
Before running clawhub publish:
scripts/validate.sh passestext
1. Author creates skill locally
2. Run: clawhub publish ./skills/my-skill/ --dry-run
3. Fix any validation errors
4. Run: clawhub publish ./skills/my-skill/
5. ClawHub assigns a unique ID and indexes the skill
6. Skill appears in search results within 5 minutes
7. Other agents can install via: clawhub install my-skill
Score every skill against these 10 criteria before publishing.
#CriterionPass/FailNotes1SKILL.md exists with valid YAML frontmatterRequiredMust parse without errors2Name is kebab-case and uniqueRequiredCheck clawhub search first3Description is specific with triggers AND exclusionsRequired>50 chars, <500 chars4**"When to Use" section** with 3+ bullet pointsRequiredConcrete, not vague5**"When NOT to Use" section** with 3+ bullet pointsRequiredNames alternative skills6Actionable content — agent can execute, not just readRequiredInclude templates, formulas, steps7Examples for every major conceptRecommendedShow input → output8References one level deep (if references/ exists)RequiredNo nested references9No secrets or credentials in any fileRequiredScan before publish10License specified and SPDX-validRequiredMIT, Apache-2.0, etc.
text
10/10 — Ready to publish
8-9/10 — Minor fixes needed, publishable
6-7/10 — Needs work, don't publish yet
<6/10 — Fundamental issues, redesign needed
text
MAJOR.MINOR.PATCH
MAJOR — Breaking changes to skill structure or content that would change agent behavior
MINOR — New content sections, expanded examples, new references
PATCH — Typo fixes, clarifications, formatting improvements
ChangeBumpExampleFix a typo in an examplePATCH1.0.0 → 1.0.1Add a new section on ratio analysisMINOR1.0.1 → 1.1.0Restructure from 5 sections to 10MAJOR1.1.0 → 2.0.0Change the description triggersMAJOR2.0.0 → 3.0.0Add a reference fileMINOR1.0.0 → 1.1.0Update examples for new API versionMINOR1.1.0 → 1.2.0
Add a ## Changelog section at the bottom of SKILL.md for significant versions:
markdown
## Changelog
### 2.0.0 (2026-03-15)
- Restructured from 5 to 9 sections
- Added aging analysis and bank reconciliation
- Breaking: removed deprecated ratio shortcuts
### 1.1.0 (2026-03-01)
- Added CFO commentary templates
- New reference: sample-board-package.md
### 1.0.0 (2026-02-15)
- Initial release
When your skill library grows past ~50 skills, you need a way to discover relationships between skills. Skill graphs solve this.
Each skill can declare relationships to other skills using two mechanisms:
depends field — hard dependencies (skill won't work without these)yaml
depends:
- agent-memory-architecture # Required: this skill uses memory patterns
- agent-orchestration # Required: this skill uses orchestration patterns
Use [[skill-name]] syntax to create soft links:
markdown
For memory patterns used in financial analysis workflows, see [[agent-memory-architecture]].
When orchestrating multiple financial analysis agents, apply the patterns in [[agent-orchestration]].
With a skill graph, you can answer:
text
"What skills does financial-analysis-agent depend on?"
→ agent-memory-architecture, agent-orchestration
"What skills reference financial-analysis-agent?"
→ eigenskill-builder (as example), cfo-reporting-agent
"What's the shortest path from crypto-tax-agent to agent-orchestration?"
→ crypto-tax-agent → financial-analysis-agent → agent-orchestration
"What are the foundational skills (most depended on)?"
→ agent-memory-architecture (12 dependents)
→ agent-orchestration (8 dependents)
→ eigenskill-builder (6 dependents)
python
import yaml
import re
from pathlib import Path
def build_skill_graph(skills_dir: Path) -> dict:
"""Build a dependency graph from all skills."""
graph = {"nodes": {}, "edges": []}
for skill_dir in skills_dir.iterdir():
skill_file = skill_dir / "SKILL.md"
if not skill_file.exists():
continue
content = skill_file.read_text()
# Parse frontmatter
fm_match = re.search(r'^---\n(.*?)\n---', content, re.DOTALL)
if not fm_match:
continue
fm = yaml.safe_load(fm_match.group(1))
name = fm.get("name", skill_dir.name)
graph["nodes"][name] = {
"description": fm.get("description", ""),
"emoji": fm.get("metadata", {}).get("openclaw", {}).get("emoji", ""),
}
# Hard dependencies (YAML)
for dep in fm.get("depends", []):
graph["edges"].append({
"from": name, "to": dep, "type": "depends"
})
# Soft references (wikilinks)
for link in re.findall(r'\[\[([\w-]+)\]\]', content):
if link != name: # No self-links
graph["edges"].append({
"from": name, "to": link, "type": "references"
})
return graph
For small libraries (<20), a simple ASCII graph works:
text
eigenskill-builder ──depends──▶ agent-orchestration
│ ▲
│ │
▼ │
financial-analysis-agent ──references─┘
│
▼
crypto-tax-agent
For larger libraries, export to DOT format and render with Graphviz, or use a JSON graph viewer.