Multi-Channel Support
Use Matrix OS through the web workspace and connected messaging surfaces.
Headless Core, Multi-Shell
Matrix OS is headless by design. The web workspace is the primary shell, and the same AI can also be reached through connected channels such as Telegram, Discord, WhatsApp, Slack, Matrix protocol, and developer tools as those surfaces are enabled.
Web Workspace Telegram Bot Discord Bot Slack
| | | |
+--- WebSocket /ws ---+ | | |
| | | |
Matrix Gateway
|
Dispatcher -> KernelChannel Architecture
The ChannelManager in packages/gateway/src/channels/ manages the lifecycle of all channel adapters. Each adapter implements the ChannelAdapter interface:
start()-- begin listening (polling, webhooks, or WebSocket connections)stop()-- gracefully shut downsend()-- format and send a message to the channel
Messages from any channel flow through the dispatcher to the kernel. The kernel's response is formatted for the originating channel via formatForChannel().
Available Channels
| Channel | Status | Transport | Configuration |
|---|---|---|---|
| Web Desktop | Built-in | WebSocket | Automatic |
| Telegram | Adapter | Long polling | config.json -> channels.telegram.token |
| Discord | Adapter | Gateway WebSocket | config.json -> channels.discord.token |
| Slack | Adapter | Socket Mode | config.json -> channels.slack.token |
| Adapter | Baileys (Web) | config.json -> channels.whatsapp | |
| CLI | Built-in | stdin/stdout | bin/matrixos.ts |
Configuring Channels
Channel setup is handled from Matrix settings when available. Under the hood, channel configuration lives in the user's Matrix system configuration so it can be backed up and restored with the rest of the workspace.
{
"channels": {
"telegram": {
"token": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
"allowFrom": [123456789]
}
}
}The allowFrom field restricts which user IDs can interact with the bot, providing basic access control.
Hot reload
Channel config changes are detected by the file watcher. Add a new channel token and the adapter starts automatically -- no restart needed.
Channel-Aware Dispatch
The dispatcher uses a DispatchContext that includes the originating channel. This context flows through to the kernel, so agents can tailor their responses. For example, Telegram messages are formatted with Markdown, while Discord uses embeds.
The formatForChannel() function handles platform-specific formatting:
- Telegram: Markdown with inline code and bold
- Discord: Rich embeds with fields
- Slack: Block Kit with sections and actions
- WhatsApp: Plain text with limited formatting
Proactive Channels
Channels aren't just for receiving messages. The CronService and HeartbeatRunner can proactively send messages through any channel:
- Cron jobs defined in
~/matrixos/system/cron.jsontrigger kernel invocations on a schedule - Heartbeat periodically invokes the kernel during active hours to check for tasks, health, and notifications
- Proactive messages are sent back through the channel that the user most recently interacted with
How is this guide?