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/weather
2

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_now
3

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 weather

Verify it's recognised — you should see weather in the list with status enabled.

bash
flowly plugins list
5

Restart the gateway

Plugin discovery runs at startup. Restart Flowly so your plugin loads.

bash
flowly service restart
If 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°C

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

Next steps