Skip to Content
SkillsCreating Skills

Creating Skills

Build custom skills to extend OpenClaw’s capabilities.

Custom skills require a Business plan or self-hosted deployment.

Skill Structure

A skill is a JavaScript/TypeScript module with this structure:

// skills/my-skill/index.ts import { Skill, SkillContext } from '@openclaw/sdk'; export default class MySkill extends Skill { name = 'my-skill'; description = 'Description of what this skill does'; triggers = [ 'my skill command', /regex pattern/i, ]; async execute(context: SkillContext) { const { message, user } = context; // Your skill logic here const result = await this.doSomething(message); return { response: `Here's the result: ${result}`, }; } }

Skill Properties

name

Unique identifier for the skill.

description

Human-readable description shown in skill listings.

triggers

Array of strings or regex patterns that activate the skill.

permissions

Required permissions:

permissions = ['web', 'files', 'database'];

Skill Context

The context object contains:

interface SkillContext { message: string; // User's message user: User; // User information conversation: Message[]; // Recent conversation files: File[]; // Uploaded files config: Config; // Skill configuration }

Example Skills

Simple Skill

export default class GreetingSkill extends Skill { name = 'greeting'; description = 'Greets the user'; triggers = ['hello', 'hi', 'hey']; async execute(context: SkillContext) { return { response: `Hello, ${context.user.name}!`, }; } }

API Integration

export default class WeatherSkill extends Skill { name = 'weather'; description = 'Gets weather information'; triggers = [/weather in (.+)/i, /what's the weather/i]; permissions = ['web']; async execute(context: SkillContext) { const location = this.extractLocation(context.message); const weather = await this.fetchWeather(location); return { response: `The weather in ${location}: ${weather.temp}°F, ${weather.conditions}`, }; } private async fetchWeather(location: string) { const response = await fetch( `https://api.weather.com/v1?q=${location}&key=${this.config.apiKey}` ); return response.json(); } }

Installing Custom Skills

Local Development

# Place skill in skills directory cp -r my-skill /path/to/openclaw/skills/ # Restart OpenClaw

Via Configuration

CUSTOM_SKILLS_PATH=/path/to/custom/skills

Testing Skills

// skills/my-skill/my-skill.test.ts import { TestContext } from '@openclaw/sdk/testing'; import MySkill from './index'; describe('MySkill', () => { it('responds correctly', async () => { const skill = new MySkill(); const context = new TestContext({ message: 'test command', user: { name: 'Test User' }, }); const result = await skill.execute(context); expect(result.response).toContain('expected text'); }); });

Publishing Skills

Share your skills with the community:

  1. Create a GitHub repository
  2. Add openclaw-skill topic
  3. Include README with installation instructions
  4. Submit to the skill registry (coming soon)