Guide

OpenClaw Plugin Development: Extending Functionality

February 23, 202610 min readReviewed March 8, 2026
Guide
Plugin Development: Create powerful plugins to extend OpenClaw's functionality, add custom commands, and integrate with any external service.

Understanding OpenClaw Plugins

OpenClaw plugins are modules that can:

  • Add new commands to the CLI
  • Extend the agent system with custom capabilities
  • Integrate with external APIs and services
  • Modify request/response handling
  • Add new output formats

Plugin Structure

my-plugin/ ├── plugin.yaml # Plugin manifest ├── package.json # Node.js dependencies ├── src/ │ ├── index.ts # Main plugin file │ ├── commands/ # Custom commands │ ├── agents/ # Custom agents │ └── utils/ # Helper functions └── README.md

Creating Your First Plugin

# Scaffold a new plugin openclaw plugin create my-plugin --template=typescript # Or manually mkdir my-plugin && cd my-plugin npm init -y npm install @openclaw/plugin-sdk

Plugin Manifest (plugin.yaml)

name: my-plugin version: 1.0.0 description: My custom OpenClaw plugin author: Your Name license: MIT openclaw: ">=2.0.0" commands: - name: my-command handler: src/commands/my-command.ts agents: - name: my-agent handler: src/agents/my-agent.ts hooks: on-init: src/hooks/on-init.ts on-request: src/hooks/on-request.ts on-response: src/hooks/on-response.ts

Creating Custom Commands

// src/commands/my-command.ts import { Command, CommandContext } from '@openclaw/plugin-sdk'; export class MyCommand implements Command { name = 'my-command'; description = 'Does something cool'; aliases = ['mc', 'my-cmd']; async execute(context: CommandContext): Promise { const { args, config, logger } = context; logger.info('Executing my command'); // Your command logic here const result = processData(args); console.log(JSON.stringify(result, null, 2)); } }

Creating Custom Agents

// src/agents/my-agent.ts import { Agent, AgentContext, AgentResponse } from '@openclaw/plugin-sdk'; export class MyAgent implements Agent { name = 'my-agent'; description = 'Specialized agent for specific tasks'; async execute(context: AgentContext): Promise { const { prompt, memory, tools } = context; // Custom agent logic const result = await this.analyze(prompt); return { content: result.explanation, confidence: result.confidence, sources: result.sources }; } private async analyze(prompt: string) { // Your analysis logic } }

Using Hooks

// src/hooks/on-request.ts import { RequestContext } from '@openclaw/plugin-sdk'; export async function onRequest(context: RequestContext): Promise { // Modify request before sending to LLM context.request.metadata.startTime = Date.now(); context.request.metadata.pluginVersion = '1.0.0'; // Add custom headers context.request.headers['X-Custom-Header'] = 'value'; } // src/hooks/on-response.ts import { ResponseContext } from '@openclaw/plugin-sdk'; export async function onResponse(context: ResponseContext): Promise { // Process response from LLM const duration = Date.now() - context.request.metadata.startTime; console.log(`Request completed in ${duration}ms`); // Log to external service await logToAnalytics(context); }

Adding Configuration Options

// src/config.ts import { ConfigSchema } from '@openclaw/plugin-sdk'; export const config: ConfigSchema = { apiKey: { type: 'string', description: 'API key for external service', required: true, envVar: 'MY_PLUGIN_API_KEY' }, maxRetries: { type: 'number', description: 'Maximum number of retries', default: 3, minimum: 0, maximum: 10 }, debugMode: { type: 'boolean', description: 'Enable debug logging', default: false } };

Plugin Development Best Practices

  • Type safety: Use TypeScript for better development experience
  • Error handling: Gracefully handle failures and provide helpful error messages
  • Logging: Use OpenClaw's logger, not console.log
  • Testing: Write unit tests for your plugin logic
  • Documentation: Document all commands and configuration options
  • Version compatibility: Specify compatible OpenClaw versions

Testing Your Plugin

# Test plugin locally openclaw plugin link ./my-plugin # Test your command openclaw my-command --help # Run plugin in development mode openclaw plugin dev ./my-plugin # Run tests npm test

Publishing Your Plugin

# Build for distribution npm run build # Publish to npm npm publish # Or distribute as a GitHub package npm publish --registry=https://npm.pkg.github.com

Plugin Discovery

# Install a plugin openclaw plugin install my-plugin # List installed plugins openclaw plugin list # Search for plugins openclaw plugin search "database"

Example: Database Plugin

// src/agents/database-agent.ts export class DatabaseAgent implements Agent { name = 'database-agent'; description = 'Executes SQL queries safely'; async execute(context: AgentContext): Promise { const query = this.extractSQL(prompt); // Validate query for safety if (!this.isSafeQuery(query)) { return { content: 'Query blocked for safety reasons', confidence: 1 }; } // Execute query const results = await this.db.execute(query); return { content: this.formatResults(results), confidence: 1 }; } private isSafeQuery(query: string): boolean { // Only allow SELECT queries return query.trim().toUpperCase().startsWith('SELECT'); } }

Debugging Plugins

# Enable debug logging openclaw config set logging.level=debug # View plugin logs openclaw logs --plugin=my-plugin # Inspect plugin configuration openclaw plugin inspect my-plugin

Build Custom Integrations

API Development Guide
Back to ArchiveMore: GuidesNext: OpenClaw for Design Systems: Building Consistent Interfaces