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.mdCreating 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-sdkPlugin 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 testPublishing 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.comPlugin 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