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 OpenClawVia Configuration
CUSTOM_SKILLS_PATH=/path/to/custom/skillsTesting 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:
- Create a GitHub repository
- Add
openclaw-skilltopic - Include README with installation instructions
- Submit to the skill registry (coming soon)