Plugins
Plugins are the most powerful way to extend Mona. They can add new tools, hooks, memory providers, and even custom CLI commands.
Plugin structure
A plugin is a Python package with a plugin.yaml manifest:
my-plugin/
├── plugin.yaml
├── __init__.py
├── tools.py
├── hooks.py
└── skills/
└── my-skill.md
plugin.yaml
name: my-plugin
version: 1.0.0
description: "My custom MonoClaw plugin"
author: "Your Name"
entrypoints:
tools: my_plugin.tools:register_tools
hooks: my_plugin.hooks:register_hooks
skills: my_plugin.skills:register_skills
dependencies:
- requests>=2.28.0
Installing plugins
Local plugins
monoclaw plugin install /path/to/my-plugin
GitHub plugins
monoclaw plugin install github.com/user/my-plugin
PyPI plugins
monoclaw plugin install monoclaw-plugin-example
Creating tools
# my_plugin/tools.py
from monoclaw.plugins import Tool
class MyTool(Tool):
name = "my_tool"
description = "Does something useful"
parameters = {
"input": {"type": "string", "description": "Input to process"}
}
async def run(self, input: str) -> str:
return f"Processed: {input}"
def register_tools():
return [MyTool()]
Creating hooks
Hooks run at key lifecycle points:
# my_plugin/hooks.py
from monoclaw.plugins import Hook
class PreMessageHook(Hook):
event = "pre_message"
async def run(self, message: str) -> str:
# Modify or log messages before processing
print(f"User said: {message}")
return message
class PostResponseHook(Hook):
event = "post_response"
async def run(self, response: str) -> str:
# Modify or log responses
return response
def register_hooks():
return [PreMessageHook(), PostResponseHook()]
Available hook events
| Event | When it fires |
|---|---|
pre_message | Before Mona processes a user message |
post_response | After Mona generates a response |
pre_tool_call | Before a tool is executed |
post_tool_call | After a tool returns |
session_start | When a new session begins |
session_end | When a session ends |
gateway_message | When a gateway receives a message |
Plugin permissions
Plugins run with the same permissions as MonoClaw. They can:
- Execute arbitrary Python code
- Access the filesystem
- Make network requests
- Read configuration and secrets
Only install plugins from trusted sources.
Plugin development
Local development
# Link your plugin for development
monoclaw plugin link /path/to/my-plugin
This installs the plugin in editable mode so changes take effect immediately.
Testing
# Run plugin tests
monoclaw plugin test my-plugin
Publishing
- Push to GitHub
- Tag a release
- Users can install with
monoclaw plugin install github.com/user/repo
Best practices
- Keep plugins focused — One domain per plugin
- Handle errors gracefully — Don't crash the agent
- Document parameters — Clear descriptions help Mona use tools correctly
- Version carefully — Breaking changes affect users
- Respect privacy — Don't exfiltrate data without consent
Example: HTTP request plugin
# tools.py
import httpx
from monoclaw.plugins import Tool
class HttpRequestTool(Tool):
name = "http_request"
description = "Make HTTP requests"
parameters = {
"url": {"type": "string", "description": "URL to request"},
"method": {"type": "string", "enum": ["GET", "POST"], "default": "GET"}
}
async def run(self, url: str, method: str = "GET") -> str:
async with httpx.AsyncClient() as client:
response = await client.request(method, url)
return response.text
def register_tools():
return [HttpRequestTool()]