Channels
Riverdesk
RiverDesk channel plugin for OpenClaw โ connect your agent to the RiverDesk task app over an E2EE dial-out WebSocket. Pair with a one-time code from web.riverdesk.ai.
Install
openclaw plugins install openclaw-riverdesk
Configuration Example
{
"channels": {
"riverdesk": {
"serverUrl": "wss://api.riverdesk.ai/plugin",
"pairingCode": "<your one-time code>",
"agents": ["youragent"],
"agentMap": { "youragent": "main" }
}
}
}
README
# openclaw-riverdesk
OpenClaw channel plugin for [RiverDesk](https://riverdesk.ai) โ chat with your
OpenClaw agents from the RiverDesk app, with end-to-end encryption.
- **Dial-out WebSocket** โ the plugin connects *out* to the RiverDesk server
(`wss://api.riverdesk.ai/plugin`). No inbound ports, NAT/firewall friendly.
- **E2EE** โ messages are encrypted with a locally minted keypair
(libsodium). The server relays ciphertext only.
- **Self-serve pairing** โ a one-time pairing code from the RiverDesk web app
is exchanged for a persistent plugin token on first boot. No manual token
handling.
- **Managed lifecycle** โ runs inside the OpenClaw gateway; starts, stops, and
reconnects with it.
## Requirements / Compatibility
- **OpenClaw gateway `>= 2026.6.5`** โ the first release with the channel
plugin SDK surface this plugin targets. Check yours with:
```bash
openclaw --version
```
The same minimum is declared in three consistent places in `package.json`:
`peerDependencies.openclaw`, `openclaw.compat.minGatewayVersion`, and
`openclaw.compat.pluginApi`.
- **Node.js 22+** โ the plugin runs inside the OpenClaw gateway process, and
the gateway itself requires Node 22 or newer.
- A RiverDesk account at [web.riverdesk.ai](https://web.riverdesk.ai).
## Install
```bash
openclaw plugins install openclaw-riverdesk
```
Or from a local tarball:
```bash
openclaw plugins install npm-pack:/path/to/openclaw-riverdesk-0.1.0.tgz
```
## Setup (pairing code โ recommended)
1. **Get a pairing code.** Sign in at [web.riverdesk.ai](https://web.riverdesk.ai),
open your agent's settings, and generate a pairing code. Codes are one-time
and expire after ~10 minutes, so do this right before the next step.
2. **Configure the channel.** Add to your OpenClaw config
(`~/.openclaw/openclaw.json`):
```json
{
"channels": {
"riverdesk": {
"serverUrl": "wss://api.riverdesk.ai/plugin",
"pairingCode": "<your one-time code>",
"agents": ["youragent"],
"agentMap": { "youragent": "main" }
}
}
}
```
- `agents` โ the RiverDesk agent id(s) this gateway serves.
- `agentMap` โ maps each RiverDesk agent id to a local gateway agent id
(most installs map to `"main"`).
3. **Restart the gateway.**
```bash
openclaw gateway restart
```
On first boot the plugin mints an E2EE keypair
(`~/.riverdesk/plugin-keypair.json`), exchanges the pairing code for a
persistent plugin token, and stores it in a state file next to the keypair
(`chmod 600`). The pairing code is ignored from then on โ you can delete it
from the config.
4. **Verify it's online.** In the RiverDesk app your agent should show as
online; send it a message and it should reply. From the shell:
```bash
curl -s https://api.riverdesk.ai/health
# "agentsOnline" should list your agent as true
```
## Configuration reference
| Key | Required | Description |
| --- | --- | --- |
| `serverUrl` | yes | RiverDesk `/plugin` WS endpoint. Production: `wss://api.riverdesk.ai/plugin` |
| `pairingCode` | first boot | One-time code from the web app. Used only when no stored token exists. |
| `agents` | yes | RiverDesk agent ids this plugin serves. |
| `agentMap` | recommended | RiverDesk agent id โ local gateway agent id, e.g. `{"youragent":"main"}`. |
| `apiUrl` | no | REST base for media endpoints. Default derives from `serverUrl`. |
| `keyFile` | no | Path to the plugin keypair JSON. Default `~/.riverdesk/plugin-keypair.json`, auto-minted. |
| `stateFile` | no | Where the issued plugin token persists. Default `keyFile + ".rd-state.json"`. |
| `pluginToken` | no | Legacy explicit token (pre-pairing deployments). Prefer the pairing flow. |
| `pubkeyId` | no | E2EE pubkey id override. Derived from the keypair when omitted. |
| `stream` | no | Typewriter streaming: `{"mode":"typewriter","chunk":6,"delayMs":45}` or `{"mode":"off"}`. |
| `allowFrom` | no | DM allowlist (participant/pubkey ids). |
| `agentConcurrency` | no | Max concurrent agent turns (default 2). |
| `agentQueueMax` | no | Max queued turns before rejection (default 20). |
| `agentTurnTimeoutSec` | no | Max seconds per agent turn (default 1800). |
| `mediaMaxMb` | no | Media size cap in MB. |
| `tickMs` | no | Reconnect tick interval in ms (default 20000). |
| `dmSecurity` | no | DM policy override (default `allowlist`). |
Environment variable equivalents: `RIVERDESK_SERVER`,
`RIVERDESK_PLUGIN_TOKEN`, `RIVERDESK_PLUGIN_KEYFILE`,
`RIVERDESK_PLUGIN_PUBKEY_ID`, `RIVERDESK_PLUGIN_AGENTS`,
`RIVERDESK_LOCAL_AGENT_MAP`.
## Migrating from a standalone connector
If you previously ran the standalone RiverDesk connector process for the same
agent, stop it after the plugin connects โ two clients serving one agent will
fight over the connection. Point `keyFile` (and `pubkeyId`) at the existing
connector's keypair to keep your E2EE identity, or pair fresh with a new code.
## Troubleshooting
- **Agent not online after restart** โ check gateway logs for `[rd-channel]`
lines. `pairing failed` usually means the code expired (10 min TTL);
generate a new one.
- **Paired before, offline now** โ the token persists in the state file;
a stale `pairingCode` in config is ignored and harmless. Check network
reachability to `api.riverdesk.ai:443`.
- **Reset pairing** โ delete the state file
(`~/.riverdesk/plugin-keypair.json.rd-state.json`), set a fresh
`pairingCode`, restart the gateway.
## License
MIT ยฉ RiverDesk
channels
Comments
Sign in to leave a comment