Complete reference for SKILL.md frontmatter and body conventions.
A SKILL.md file has two parts:
- Frontmatter (YAML) — Metadata, requirements, install instructions
- Body (Markdown) — Documentation and usage
---
name: my-skill
description: What this skill does
metadata:
openclaw:
emoji: 📦
---
# Skill Name
Body content goes here.| Field | Type | Required | Example |
|---|---|---|---|
name |
string | Yes | my-skill |
description |
string | Yes | Processes CSV files |
metadata |
object | No | See below |
version |
string | No | 1.0.0 |
author |
string | No | Jane Doe |
license |
string | No | MIT |
Unique identifier for the skill. Used in:
- Workspace path:
~/.openclaw/workspace/skills/{name}/ - ClawHub registry lookups
openclaw skill install {name}
Format: kebab-case, alphanumeric + hyphens
Example:
name: email-senderShort description of what the skill does. Used for:
- ClawHub search and discovery
- Vector embeddings (skills searchable by keywords in description)
- UI display in skill listings
Best practices:
- 2-3 sentences maximum
- Start with action verb: "Sends emails", "Processes CSV", "Checks weather"
- Mention key integrations: "Gmail integration", "Slack updates"
- Be specific: "Monitors GitHub repositories for new releases and sends Slack notifications"
Example:
description: Sends emails via SMTP or Gmail. Supports attachments and HTML templates.The metadata.openclaw section contains OpenClaw-specific metadata.
Single emoji representing the skill visually.
Type: string Optional: Yes Example:
metadata:
openclaw:
emoji: 📧Common choices:
- 📊 — Data/spreadsheet
- 🔐 — Security/authentication
- 🌐 — Web/API
- ⏰ — Scheduling/time
- 📱 — Mobile/messaging
- 🗄️ — Database/storage
- 🚀 — Deployment/automation
- 🔔 — Notifications
Declares what the skill needs to run.
Required system binaries.
Type: array of objects Optional: Yes
Fields per binary:
name(required): Binary name (e.g.,python3,node,curl)version(optional): Version constraint in semver format (e.g.,>=3.9,^18.0.0)
Example:
metadata:
openclaw:
requires:
bins:
- name: python3
version: ">=3.9"
- name: node
version: ">=18.0.0"
- name: curlRequired environment variables.
Type: array of objects Optional: Yes
Fields per variable:
name(required): Variable name (e.g.,AWS_ACCESS_KEY_ID)description(optional): What the variable is forsecret(optional): Boolean flag (true if sensitive data)
Example:
metadata:
openclaw:
requires:
env:
- name: AWS_ACCESS_KEY_ID
description: AWS access key for authentication
secret: true
- name: AWS_REGION
description: AWS region (e.g., us-east-1)
- name: SLACK_BOT_TOKEN
secret: trueConfiguration options the skill accepts.
Type: array of objects Optional: Yes
Fields per config:
name(required): Config keytype(optional):string,integer,boolean,floatdescription(optional): What it's forrequired(optional): Boolean, true if mandatorydefault(optional): Default value if not provided
Example:
metadata:
openclaw:
requires:
config:
- name: api_endpoint
type: string
description: API endpoint URL
required: true
- name: timeout
type: integer
description: Request timeout in seconds
required: false
default: 30
- name: debug_mode
type: boolean
description: Enable debug logging
default: falseInstallation instructions for dependencies.
Type: array of objects Optional: Yes
Common kind values:
brew— Homebrew (macOS)apt— APT (Debian/Ubuntu)yum— YUM (RHEL/CentOS)manual— Manual steps
Fields per install method:
id(required): Unique identifier (e.g.,homebrew,ubuntu,manual)kind(required): Installation systemformulaorpackage(for package managers): Package namebins(optional): Binaries that will be available after installlabel(required): Human-readable label for UIinstructions(for manual): Step-by-step installation text
Example:
metadata:
openclaw:
install:
- id: homebrew
kind: brew
formula: python@3.11
bins:
- python3.11
label: Install Python 3.11 via Homebrew
- id: ubuntu
kind: apt
package: python3.11
bins:
- python3.11
label: Install Python 3.11 via apt
- id: manual
kind: manual
label: Manual installation
instructions: |
1. Visit https://www.python.org/downloads/
2. Download the latest Python 3.11 installer
3. Run the installer
4. Verify: python3 --versionThe markdown body (after frontmatter) contains documentation.
Skill name, matching the name field:
# Email SenderOne-paragraph overview:
Send emails through SMTP, Gmail, or other mail providers. Supports attachments, HTML templates, and multiple recipients.Bullet list of key capabilities:
## Features
- Send to single or multiple recipients
- Support for attachments (PDF, images, etc.)
- HTML and plaintext bodies
- Template variables: {name}, {email}, etc.
- Retry on failureHow to invoke the skill:
## Usage
Invoke the skill with action `send`:
action: send to: user@example.com subject: Hello World body: This is my message
Required parameters:
- `to` (string or array): Recipient email(s)
- `subject` (string): Email subject
- `body` (string): Email body
Optional parameters:
- `html` (string): HTML body (overrides body if provided)
- `cc` (array): CC recipients
- `bcc` (array): BCC recipients
- `attachments` (array): Files to attach
Configuration requirements:
## Configuration
Set these environment variables:
- `SMTP_HOST` — SMTP server hostname
- `SMTP_PORT` — SMTP port (usually 587 for TLS or 465 for SSL)
- `SMTP_USER` — SMTP username
- `SMTP_PASS` — SMTP password
- `SMTP_FROM` — From address for emails
Or use OAuth2 with Gmail:
- `GMAIL_CLIENT_ID` — OAuth2 client ID
- `GMAIL_CLIENT_SECRET` — OAuth2 client secret
- `GMAIL_REFRESH_TOKEN` — OAuth2 refresh tokenReal-world usage examples:
## Examples
### Simple email
action: send to: alice@example.com subject: Meeting reminder body: Don't forget our 3pm call
### Multiple recipients with attachment
action: send to: [alice@example.com, bob@example.com] cc: [manager@example.com] subject: Report attached body: Please review the attached report attachments:
- path: /tmp/report.pdf name: Q1_Report.pdf
### HTML email with template
action: send to: user@example.com subject: Welcome, {name}! body: |
Hi {name}, thanks for signing up!
template_vars: name: Alice code: abc123xyz ``` ```System requirements:
## Requirements
- Node.js >= 18 or Python >= 3.9
- SMTP server access or Gmail API credentials
- Network access to mail serversWhat the skill doesn't do:
## Limitations
- Does not support IMAP (incoming mail)
- Cannot schedule emails for later delivery
- Attachments limited to 25MB per email
- No read receipts trackingCommon issues and solutions:
## Troubleshooting
### "Connection refused" error
Check that SMTP_HOST and SMTP_PORT are correct. Test with:
```bash
telnet $SMTP_HOST $SMTP_PORTVerify SMTP_USER and SMTP_PASS are correct. For Gmail, use an App Password, not your regular password.
Increase the timeout or check network connectivity to the SMTP server.
## Complete Example: CSV Processor
```markdown
---
name: csv-processor
version: 1.0.0
description: Parse, filter, and transform CSV files. Export to JSON, SQL, or send to external services.
author: Jane Doe
license: MIT
metadata:
openclaw:
emoji: 📊
requires:
bins:
- name: node
version: ">=18.0.0"
env:
- name: DATABASE_URL
description: PostgreSQL connection string for loading data
secret: true
config:
- name: output_format
type: string
description: Output format (json, sql, csv)
required: false
default: json
- name: delimiter
type: string
description: CSV delimiter character
required: false
default: ","
install:
- id: node
kind: manual
label: Install Node.js
instructions: |
Visit https://nodejs.org and download the LTS version (>= 18)
---
# CSV Processor
Parse, filter, and transform CSV files. Convert between formats and load into databases.
## Features
- Parse CSV files with auto-detection of delimiters
- Filter rows by column values
- Transform columns (rename, combine, extract)
- Export to JSON, SQL INSERT statements, or CSV
- Load directly into PostgreSQL
- Handles large files with streaming
## Usage
Invoke with action `process`:
action: process file: /path/to/data.csv output_format: json filter: status: active
## Configuration
Set optional environment variable:
DATABASE_URL=postgresql://user:pass@localhost/mydb
Configure output format:
```yaml
csv_processor:
output_format: json
delimiter: ","
action: process
file: /tmp/users.csv
output_format: json
output_file: /tmp/users.json
action: process
file: /tmp/sales.csv
filter:
region: "North America"
year: "2024"
output_format: csv
action: process
file: /tmp/customers.csv
action: load_database
table: customers
- Node.js >= 18
- For database loading: PostgreSQL connection string
- Large files (>1GB) require streaming mode
- Does not handle nested JSON in CSV cells
- Maximum column count: 10,000
## Discovery Best Practices
Your `description` and body content are indexed for ClawHub search. To improve discoverability:
1. **Use specific action verbs** in description: "Sends emails", "Processes CSV", "Monitors logs"
2. **Mention integrations** clearly: "Gmail", "Slack", "PostgreSQL"
3. **Include keywords** in description: "SMTP", "attachments", "templates"
4. **Good examples** in body help users understand what the skill does
Example with good discoverability:
```yaml
name: github-notifications
description: Monitor GitHub repositories for new releases and push notifications. Supports email, Slack, and webhooks.
This is discoverable by: "github", "notifications", "releases", "slack", "email", "webhooks", "monitor"
Skills are validated with:
openclaw skill validateChecks:
- SKILL.md exists and is valid YAML frontmatter
nameanddescriptionare presentemojiis a single character if provided- All config types are valid (
string,integer,boolean,float) - Install methods reference valid
kindvalues - Required fields are present
- Skill Development guide — full tutorial on building skills
- Getting Started — create your first skill in 10 minutes
- Architecture — understand OpenClaw's architecture