MonoClaw

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_weather tool
  • 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)

  1. 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
  1. 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