Building Custom Skills for OpenClaw
Introduction
OpenClaw's true power lies in its extensibility. If the Model is the brain, Skills are the hands. While the community registry on ClawdHub contains hundreds of ready-to-use skills, you might need internal integrations tied to your proprietary company APIs, database systems, or localized hardware.
This guide will walk you through building a "WeatherCheck" Skill in Node.js, exposing it to the OpenClaw Agent, and formatting the Model Context Protocol (MCP) correctly.
1. Understanding the Architecture (MCP)
OpenClaw supports Anthropic's open standard: the Model Context Protocol (MCP). This means you don't need to write brittle custom parsers. You build a standard JSON-RPC server (or an HTTP SSE stream) that exposes:
- Resources: Resources: Static context the model can choose to read (e.g., "Company API Docs").
- Tools: Tools: Actions the model can decide to execute (e.g., "fetch_weather_by_city").
2. Project Setup
Let's create a new Node.js package using the official MCP SDK.
mkdir my-first-skill && cd my-first-skill
npm init -y
npm install @modelcontextprotocol/sdk3. Writing the Skill Server
Create an index.js file. We will define an MCP server that uses the stdio transport (the simplest way for OpenClaw to spawn and talk to your local skill).
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Initialize the standard MCP server
const server = new McpServer({
name: "WeatherCheck-Skill",
version: "1.0.0"
});
// Register a Tool that the AI can call
server.tool("get_weather",
"Fetch current weather for a specific city",
{
city: z.string().describe("The name of the city (e.g. London, Beijing)")
},
async ({ city }) => {
console.error(`Fetching hardware sensor or API for: ${city}`);
const mockTemp = Math.floor(Math.random() * 30);
return {
content: [{ type: "text", text: `The weather in ${city} is ${mockTemp}Β°C and Sunny.` }]
};
}
);
// Connect via standard I/O pipes
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("WeatherCheck Skill is running on stdio!");4. Registering the Skill in OpenClaw
Open your ~/.openclaw/config.json (or skills.yml depending on your version), and tell OpenClaw how to boot your new MCP server.
{
"mcpServers": {
"weather_check": {
"command": "node",
"args": ["/absolute/path/to/my-first-skill/index.js"]
}
}
}5. Testing the Integration
Restart your OpenClaw daemon. Ask the AI:
Hey, do I need an umbrella in Paris today?
If properly configured, the LLM will see the get_weather tool in its context, generate the JSON calling arguments for "Paris", and your index.js will return the mock text. The LLM will then read the text and reply to you naturally.
Publishing to ClawdHub
Once your skill is polished and tested, package your repository and submit a Pull Request to the Starmadebydata/clawdhub-registry. Community adoption starts here! For more details, see the official publishing guidelinesγ