Skip to content

Plugin Development

Plugins extend Clawdbot’s capabilities beyond basic chat functionality.

my_plugin/
├── __init__.py
├── plugin.yaml
└── handlers.py
name: my_plugin
version: 1.0.0
description: My custom plugin
author: Your Name
# Dependencies
requires:
- requests>=2.28.0
# Configuration schema
config:
api_key:
type: string
required: true
description: API key for the service
from clawdbot import Plugin, command, tool
class MyPlugin(Plugin):
@command("weather")
async def weather_command(self, message, location: str):
"""Get weather for a location"""
data = await self.fetch_weather(location)
return f"Weather in {location}: {data['temp']}°C"
@tool("get_weather")
async def weather_tool(self, location: str) -> dict:
"""Tool for Claude to get weather data"""
return await self.fetch_weather(location)
  1. Create plugin directory

    Terminal window
    mkdir -p plugins/my_plugin
    cd plugins/my_plugin
  2. Create plugin.yaml

  3. Implement handlers

  4. Register plugin

    Terminal window
    # In .env
    PLUGINS=my_plugin
HookPurpose
on_loadPlugin initialization
on_unloadCleanup
pre_messageBefore processing
post_responseAfter response
import aiohttp
from clawdbot import Plugin, tool
class WeatherPlugin(Plugin):
async def on_load(self):
self.api_key = self.config.get("api_key")
@tool("get_current_weather")
async def get_weather(self, city: str) -> dict:
"""Get current weather for a city.
Args:
city: City name (e.g., "London")
Returns:
Weather data including temperature and conditions
"""
async with aiohttp.ClientSession() as session:
url = f"https://api.weather.com/..."
async with session.get(url) as resp:
return await resp.json()
  1. Handle errors gracefully
  2. Use async/await properly
  3. Document your tools
  4. Validate configuration
  5. Clean up resources in on_unload