Your first plugin in 5 minutes
/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
Create the plugin directory
Plugins live under ~/.flowly/plugins/. Each plugin is its own folder.
mkdir -p ~/.flowly/plugins/weather
cd ~/.flowly/plugins/weatherWrite the manifest
Every plugin needs a plugin.yaml at its root. The manifest tells Flowly the plugin's name, version, and what it provides.
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_nowWrite the plugin code
The entry point is __init__.py. It must define a register(ctx) function. Flowly calls it once at startup.
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>",
)Enable the plugin
User plugins are opt-in. Tell Flowly to load it:
flowly plugins enable weatherVerify it's recognised β you should see weather in the list with status enabled.
flowly plugins listRestart the gateway
Plugin discovery runs at startup. Restart Flowly so your plugin loads.
flowly service restartTry it out
From any channel β Telegram, Web, Desktop β invoke the slash command:
/weather Berlin
β Berlin: β
οΈ +14Β°COr let the agent decide to call it on its own:
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.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.