Quickstart
Your first plugin in 5 minutes
We'll build a plugin that adds a
/weather slash command and a weather_now tool the agent can call. By the end you will have a working plugin you can extend.Walkthrough
1
Create the plugin directory
Plugins live under ~/.flowly/plugins/. Each plugin is its own folder.
bash
mkdir -p ~/.flowly/plugins/weather
cd ~/.flowly/plugins/weather2
Write the manifest
Every plugin needs a plugin.yaml at its root. The manifest tells Flowly the plugin's name, version, and what it provides.
yaml
name: weather
version: 0.1.0
manifest_version: 1
description: "Look up current weather for any city."
author: "you@example.com"
kind: standalone
provides_tools:
- weather_now3
Write the plugin code
The entry point is __init__.py. It must define a register(ctx) function. Flowly calls it once at startup.
python
import asyncio
import httpx
async def weather_handler(city: str) -> str:
"""Fetch a one-line weather string for *city* using wttr.in."""
async with httpx.AsyncClient(timeout=10) as client:
r = await client.get(f"https://wttr.in/{city}?format=3")
r.raise_for_status()
return r.text.strip()
def slash_handler(args: str) -> str:
"""Synchronous wrapper for /weather <city>."""
city = args.strip() or "Istanbul"
return asyncio.run(weather_handler(city))
def register(ctx):
# Tool the agent can call autonomously.
ctx.register_tool(
name="weather_now",
schema={
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name (e.g. 'Istanbul', 'New York')",
},
},
"required": ["city"],
},
},
handler=weather_handler,
description="Look up current weather for a city.",
)
# Slash command the user types directly: /weather Berlin
ctx.register_command(
"weather",
handler=slash_handler,
description="Show current weather for a city",
args_hint="<city>",
)4
Enable the plugin
User plugins are opt-in. Tell Flowly to load it:
bash
flowly plugins enable weatherVerify it's recognised — you should see weather in the list with status enabled.
bash
flowly plugins list5
Restart the gateway
Plugin discovery runs at startup. Restart Flowly so your plugin loads.
bash
flowly service restartIf you're running Flowly through the desktop app, just quit and reopen it — the gateway restarts automatically.
6
Try it out
From any channel — Telegram, Web, Desktop — invoke the slash command:
text
/weather Berlin
→ Berlin: ⛅️ +14°COr let the agent decide to call it on its own:
text
You: What's the weather like in Tokyo right now?
Agent: Let me check...
[calls weather_now(city="Tokyo")]
Tokyo is 🌧️ +18°C with light rain.That's it!
Your plugin is live. The agent can call
weather_now whenever it makes sense, and users can manually trigger /weather at any time. Three things to explore next: add a hook that logs every weather lookup, register a SKILL.md template for weather-related queries, and publish to GitHub so others can install it with one command.