Building a Plugin
This guide walks you through building a complete plugin that adds a new tool, a hook, and a skill to Mona.
What you'll build
A "weather" plugin that:
- Adds a
get_weathertool - Logs all weather queries via a hook
- Includes a skill for interpreting weather data
Step 1: Scaffold the plugin
mkdir -p ~/.monoclaw/plugins/weather-plugin
cd ~/.monoclaw/plugins/weather-plugin
Step 2: Create plugin.yaml
name: weather-plugin
version: 1.0.0
description: "Weather lookup tool for Mona"
author: "Your Name"
entrypoints:
tools: weather_plugin.tools:register_tools
hooks: weather_plugin.hooks:register_hooks
skills: weather_plugin.skills:register_skills
dependencies:
- httpx>=0.24.0
Step 3: Create the tool
# weather_plugin/tools.py
import httpx
from monoclaw.plugins import Tool
class GetWeatherTool(Tool):
name = "get_weather"
description = "Get current weather for a city"
parameters = {
"city": {
"type": "string",
"description": "City name, e.g. 'Hong Kong'"
}
}
async def run(self, city: str) -> str:
async with httpx.AsyncClient() as client:
# Using a free weather API
response = await client.get(
f"https://wttr.in/{city}?format=%C+%t"
)
return response.text
def register_tools():
return [GetWeatherTool()]
Step 4: Create the hook
# weather_plugin/hooks.py
from monoclaw.plugins import Hook
class WeatherLogHook(Hook):
event = "pre_tool_call"
async def run(self, tool_name: str, parameters: dict) -> None:
if tool_name == "get_weather":
print(f"[Weather Plugin] Looking up: {parameters.get('city')}")
def register_hooks():
return [WeatherLogHook()]
Step 5: Create the skill
# weather_plugin/skills.py
from monoclaw.plugins import Skill
class WeatherSkill(Skill):
name = "weather"
triggers = ["weather", "temperature", "forecast"]
content = """
# Weather Skill
## When to use
When the user asks about weather conditions.
## How to use the tool
- Call `get_weather` with the city name
- Interpret the result for the user
- Include temperature and conditions
## Examples
- User: "What's the weather in Tokyo?"
- Action: Call `get_weather(city="Tokyo")`
- Response: "It's partly cloudy and 24°C in Tokyo."
"""
def register_skills():
return [WeatherSkill()]
Step 6: Install the plugin
cd ~/.monoclaw/plugins/weather-plugin
monoclaw plugin link .
This installs in development mode so changes take effect immediately.
Step 7: Test
monoclaw
What's the weather in Hong Kong?
Mona should use your get_weather tool and respond with current conditions.
Step 8: Publish (optional)
- Push to GitHub:
git init
git add .
git commit -m "Initial weather plugin"
git remote add origin https://github.com/yourname/monoclaw-weather-plugin.git
git push -u origin main
- Others can install:
monoclaw plugin install yourname/monoclaw-weather-plugin
Plugin structure reference
my-plugin/
├── plugin.yaml # Manifest
├── __init__.py
├── tools.py # Tool definitions
├── hooks.py # Hook definitions
├── skills/ # Skill markdown files
│ └── my-skill.md
├── data/ # Static data files
│ └── cities.json
└── tests/ # Tests
└── test_tools.py
Best practices
- Keep tools focused — One tool per distinct action
- Document parameters — Help Mona use tools correctly
- Handle errors gracefully — Don't crash the agent
- Use async — All tools and hooks should be async
- Test thoroughly — Write tests for your tools