Prerequisites
- hirocli set up and running (
hirocli setup,hirocli start) - uv installed — docs.astral.sh/uv
- Python ≥ 3.11
Quick start — clone the echo plugin
The fastest way to start is to copy the reference implementation:hiro-channel-<yourname>/ and follow the steps below.
1. Package structure
2. pyproject.toml
[tool.uv.sources] is required for uv to resolve hiro-channel-sdk from the local workspace instead of PyPI.3. Implement ChannelPlugin
Open plugin.py and subclass hiro_channel_sdk.ChannelPlugin:
Methods you must implement
| Method | Called when | What to do |
|---|---|---|
info (property) | registration | Return ChannelInfo(name=..., version=..., description=...) |
on_configure(config) | hirocli pushes credentials | Store API keys, tokens, etc. |
on_start() | plugin connects to hirocli | Start polling / set up webhooks |
on_stop() | hirocli sends stop signal | Cancel tasks, close connections |
send(message) | hirocli wants to send a message | Translate UnifiedMessage → third-party API call |
The emit method
await self.emit(unified_message) is inherited — call it whenever an inbound message arrives from the third party. The transport layer forwards it to hirocli as a channel.receive JSON-RPC notification automatically.
4. Write main.py
--hiro-ws argument is automatically appended by ChannelManager when spawning the subprocess. The envvar="HIRO_WS" allows overriding it in development without CLI args.
5. Install and configure
- Development (workspace member)
- Published package
Add the channel to the uv workspace and install it in-place:
Store credentials
Edit~/.hirocli/channels/telegram.json and add your credentials to the config field:
config dict to your plugin via on_configure() automatically each time the plugin connects.
6. Run and verify
7. Sending events back to hirocli
Beyond inbound messages you can emit structured events usingchannel.event for delivery receipts, errors, or status changes. Currently, log them via the standard logger:
Full
channel.event support — arbitrary structured events passed upstream to hirocli handlers — is on the roadmap.Reference
UnifiedMessage fields
| Field | Type | Required | Notes |
|---|---|---|---|
id | str | auto | UUID hex, auto-generated |
channel | str | yes | Plugin name, e.g. "telegram" |
direction | str | yes | "inbound" or "outbound" |
sender_id | str | yes | Channel-native user identifier |
recipient_id | str | None | no | Channel-native target identifier |
content_type | str | default "text" | "text" | "image" | "audio" | "video" | "location" | "command" | "file" |
body | str | default "" | Text content or caption |
metadata | dict | default {} | Channel-specific extras — free-form |
timestamp | datetime | auto | UTC, auto-generated |
hirocli channel commands
| Command | Description |
|---|---|
hirocli channel list | List all configured plugins and their status |
hirocli channel install <name> | Install via uv tool install hiro-channel-<name> |
hirocli channel setup <name> | Configure command and credentials interactively |
hirocli channel enable <name> | Enable a disabled plugin |
hirocli channel disable <name> | Disable without removing config |
hirocli channel remove <name> | Delete the plugin’s config file |
hirocli channel status | Show currently connected plugins (live query) |
Troubleshooting
Plugin not connecting
Plugin not connecting
- Check the subprocess is running:
hirocli status - Check the plugin logs (stdout/stderr of the subprocess)
- Verify the command in
~/.hirocli/channels/<name>.jsonis onPATH - Try running the plugin manually:
hiro-channel-telegram --hiro-ws ws://127.0.0.1:18081
Credentials not reaching on_configure
Credentials not reaching on_configure
- Make sure the
configkey in the JSON file is populated (not{}) - Config is pushed immediately after
channel.register— check your logs
Testing without a real third-party account
Testing without a real third-party account
Use the echo channel:
hirocli channel setup echo — it reflects any outbound message back as inbound, letting you verify the full round-trip pipeline.