AURA uses a plugin architecture that lets you add new capabilities without
modifying any core code. Drop a Python module into aura_mcp/plugins/ and
the plugin manager discovers it automatically at startup.
| Plugin | File | Capabilities |
|---|---|---|
| notion | notion_plugin.py |
Read tasks, update status |
| scaffolder | scaffolder_plugin.py |
Generate React / Node / FastAPI projects |
| github | github_plugin.py |
Create repos, push files |
| docker | docker_plugin.py |
Generate Dockerfiles |
| filesystem | filesystem_plugin.py |
Create files/folders, list directories |
Create aura_mcp/plugins/my_plugin.py:
from __future__ import annotations
from typing import Any
from aura_mcp.plugins.base import BasePlugin
from aura_mcp.utils.logger import get_logger
class MyPlugin(BasePlugin):
@property
def name(self) -> str:
return "my_plugin"
async def execute(self, intent: dict[str, Any]) -> dict[str, Any]:
logger = get_logger()
action = intent.get("action", "")
if action == "greet":
logger.info("Hello from my plugin!")
return {"status": "ok", "message": "Hello!"}
raise ValueError(f"Unknown action: {action}")
def describe(self) -> str:
return "My custom plugin"
The plugin manager scans every module in aura_mcp/plugins/ (skipping
base.py and manager.py), finds classes that inherit from BasePlugin,
and registers an instance automatically.
Verify with:
aura plugins
BasePlugin (abstract)| Method | Required | Purpose |
|---|---|---|
name (property) |
Yes | Unique string identifier |
execute(intent) |
Yes | Dispatch on intent["action"] |
describe() |
No | One-line description for aura plugins |
intent dictEvery call to execute receives an intent dict. The only mandatory key is
action — additional keys are action-specific.
intent = {
"action": "create_file",
"path": "/tmp/hello.txt",
"content": "Hello, world!",
}
Return a dict with at least {"status": "ok"} on success.
result = await plugin_manager.execute("my_plugin", {"action": "greet"})