Building Custom OpenClaw Skills: Complete Developer Guide

OpenClaw's power comes from its skill system—modular tools that give your AI assistant new capabilities. While OpenClaw ships with built-in skills like browser control, message handling, and file operations, you can create custom skills to integrate any service, API, or automation workflow. This guide shows you how to build, test, and deploy your own OpenClaw skills.
Custom skills let you connect OpenClaw to specialized tools your business uses—whether that's a CRM, analytics platform, IoT devices, or proprietary APIs. Instead of building an entire AI integration from scratch, you create a single skill that plugs into OpenClaw's existing infrastructure.
Understanding the OpenClaw Skill Architecture
OpenClaw skills are isolated Node.js modules that expose tools to the agent
OpenClaw skills are Node.js modules that live in the ~/.openclaw/skills/ directory. Each skill is a self-contained package with its own package.json, dependencies, and configuration. When OpenClaw starts, it discovers and loads all enabled skills, making their tools available to the AI agent.
The skill system uses a standardized JSON Schema format to describe tools—what parameters they accept, what types of values are valid, and what the tool does. This schema lets Claude understand how to use your tools without additional training. When Claude decides a tool is needed, OpenClaw routes the request to your skill's implementation.
Skills can maintain their own state, store credentials securely, and interact with external services. They can also read from and write to the workspace, access environment variables, and call other skills' tools. This modularity means you can mix and match skills to build complex workflows.
Step 1: Create Your Skill Structure
Use the OpenClaw CLI to scaffold a new skill with the correct structure
Navigate to your OpenClaw skills directory and create a new folder for your skill. The naming convention is lowercase with hyphens (e.g., my-custom-skill).
cd ~/.openclaw/skills
mkdir my-custom-skill
cd my-custom-skill
npm init -y
Create the required files:
SKILL.md- Documentation for the skillindex.js- Main skill implementationpackage.json- Dependencies and metadata
Your skill must export a function that returns a skill definition object with name, description, tools, and handler functions.
Step 2: Define Your Tool Schema
Tool schemas use JSON Schema to describe parameters and validation rules
The tool schema tells Claude what your tool does and how to use it. Here's a complete example for a custom notification skill:
export default async function skill() {
return {
name: 'custom-notify',
description: 'Send notifications via custom service',
tools: [
{
name: 'send_notification',
description: 'Send notification to user device',
inputSchema: {
type: 'object',
properties: {
message: {
type: 'string',
description: 'Notification message body'
},
priority: {
type: 'string',
enum: ['low', 'normal', 'high'],
description: 'Notification priority level'
},
deviceId: {
type: 'string',
description: 'Optional specific device to notify'
}
},
required: ['message']
}
}
],
handler: async (toolName, params) => {
// Implementation goes here
}
};
}
Use descriptive names and clear parameter descriptions—Claude uses these to decide when to call your tool. Include examples in descriptions when parameter formats are specific.
Step 3: Implement the Handler Function
The handler function receives tool calls and returns results to the agent
The handler function is where your tool's logic lives. It receives the tool name and validated parameters, executes the requested action, and returns a result.
handler: async (toolName, params) => {
if (toolName === 'send_notification') {
try {
// Your implementation
const response = await fetch('https://api.notify-service.com/send', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.NOTIFY_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: params.message,
priority: params.priority || 'normal',
device: params.deviceId
})
});
const result = await response.json();
return {
success: true,
messageId: result.id,
deliveredAt: new Date().toISOString()
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
}
Always return structured data that Claude can interpret. Include success/failure status and relevant details. Handle errors gracefully—Claude can work around failures if you provide clear error messages.
Step 4: Add Configuration and Credentials
Store sensitive credentials in environment variables, not in code
Skills can read configuration from environment variables or the OpenClaw config file. Never hardcode API keys or secrets in your skill code.
Add credentials to ~/.openclaw/.env:
NOTIFY_API_KEY=your_api_key_here
NOTIFY_SERVICE_URL=https://api.notify-service.com
Access them in your skill:
const apiKey = process.env.NOTIFY_API_KEY;
const serviceUrl = process.env.NOTIFY_SERVICE_URL || 'https://api.notify-service.com';
For skills that need persistent state, store data in ~/.openclaw/workspace/skills-data/your-skill-name/. Create this directory in your skill's initialization if it doesn't exist.
Step 5: Document Your Skill
SKILL.md should include setup instructions, examples, and troubleshooting
Create a comprehensive SKILL.md file that explains how to install, configure, and use your skill. Include:
- What the skill does and why it's useful
- Installation steps and dependencies
- Required environment variables
- Example tool calls
- Common errors and solutions
- Links to external service documentation
Good documentation helps future you and anyone else who uses your skill. Include practical examples that show real-world usage patterns.
Step 6: Test Your Skill Locally
Test skills in isolation before enabling them in OpenClaw
Create a test file to validate your skill independently:
// test.js
import skill from './index.js';
async function test() {
const mySkill = await skill();
console.log('Testing notification skill...');
const result = await mySkill.handler('send_notification', {
message: 'Test notification',
priority: 'normal'
});
console.log('Result:', result);
}
test();
Run tests with:
node test.js
Verify that your tool handles valid inputs, rejects invalid inputs, manages errors gracefully, and returns the expected structure. Test edge cases like network failures, missing credentials, and malformed responses.
Step 7: Enable Your Skill in OpenClaw
Add your skill to the enabled skills list in OpenClaw config
Once tested, enable your skill in OpenClaw's configuration. Edit ~/.openclaw/config.json and add your skill to the enabledSkills array:
{
"enabledSkills": [
"built-in-skill-1",
"built-in-skill-2",
"my-custom-skill"
]
}
Restart OpenClaw to load the new skill:
openclaw gateway restart
Check the logs to confirm your skill loaded successfully:
openclaw gateway logs
Step 8: Test with Your AI Agent
Ask your agent to use the skill in natural language
Start a conversation with your OpenClaw agent and ask it to use your new tool. Claude will automatically invoke it when appropriate:
You: Send me a high-priority notification that dinner is ready
Agent: [Uses send_notification tool]
I've sent a high-priority notification to your device.
Monitor the skill's behavior in production. Check logs for errors, unexpected inputs, or performance issues. Iterate based on real-world usage patterns.
Advanced: Multi-Tool Skills
Skills can expose multiple related tools that work together
Skills can provide multiple tools that work together. For example, a database skill might offer query, insert, update, and delete tools:
tools: [
{
name: 'db_query',
description: 'Query database records',
inputSchema: { /* ... */ }
},
{
name: 'db_insert',
description: 'Insert new database record',
inputSchema: { /* ... */ }
},
{
name: 'db_update',
description: 'Update existing record',
inputSchema: { /* ... */ }
}
]
Group related functionality into a single skill to keep the skill directory organized and reduce duplication.
Best Practices for Production Skills
Follow best practices to build reliable, maintainable skills
Error Handling: Always catch and return errors instead of throwing. Claude can work around failures if you provide context.
Rate Limiting: If your skill calls external APIs, implement rate limiting and respect API quotas. Add retry logic with exponential backoff.
Logging: Use console.log or a proper logging library to track tool usage. This helps with debugging and monitoring.
Validation: Validate inputs beyond what JSON Schema provides. Check for business logic constraints, format requirements, and security issues.
Versioning: Add a version field to your skill definition. When making breaking changes, consider supporting both old and new parameter formats temporarily.
Security: Never expose credentials in error messages or logs. Sanitize outputs that might contain sensitive data.
Sharing Your Skills
Share skills as npm packages or GitHub repositories
Package your skill for others to use:
- Clean up the code and add comprehensive documentation
- Include a LICENSE file (MIT is common for community skills)
- Create a README.md with installation and usage instructions
- Publish to npm or share as a GitHub repository
- Submit to the OpenClaw community skills directory
When sharing skills, test on a fresh OpenClaw installation to catch missing dependencies or undocumented setup steps.
Conclusion
Custom skills unlock unlimited extensibility for your AI assistant
Building custom OpenClaw skills transforms your AI assistant from a general-purpose tool into a specialized powerhouse tailored to your exact needs. Whether you're integrating proprietary APIs, automating complex workflows, or connecting to services that don't have built-in support, skills give you complete control over your agent's capabilities.
Start with simple single-tool skills to learn the pattern, then expand to more complex multi-tool implementations as you identify opportunities. The best skills solve real problems you encounter daily—those are the ones you'll maintain and improve over time.
For more OpenClaw development tutorials, check out our guides on OpenClaw API integration, subagent delegation, and browser automation. Join the OpenClaw community to share your skills and discover what others have built.
Ready to extend your AI assistant? View the OpenClaw skills documentation to see built-in skills as examples and learn about advanced features like skill-to-skill communication and event handling.
More Articles
The Ultimate OpenClaw AWS Setup Guide

The definitive guide to setting up OpenClaw on AWS. Includes spot instance configuration, cost optimization, and step-by-step instructions.
Building AI Workflows with Tool Chaining in OpenClaw
Master the art of chaining tools and function calls to build powerful multi-step AI automation workflows—from data extraction to content generation and deployment.
Cost Optimization Guide for Self-Hosted AI Assistants: Run Claude on a Budget
Practical strategies to reduce API costs for self-hosted AI assistants—smart model routing, caching, batching, and OpenClaw-specific optimizations to run Claude affordably.