Tlon Integration with OpenClaw: Setup and Capabilities
Learn how to connect OpenClaw to Urbit's Tlon messenger for DMs and group chats, including setup, bundled plugin details, and supported features like mentions and image uploads.
Read this when
- Working on Tlon/Urbit channel features
Tlon is a decentralized messaging application built on Urbit. Through OpenClaw, you can link to your Urbit ship and handle direct messages along with group chat messages. By default, replying in groups requires an @ mention, with authorization rules and an owner-approval process layered on top.
Status: bundled plugin. Supported features include DMs, group mentions, threads, rich text, image upload/download, and an owner approval system. Reactions and polls are not supported.
Bundled plugin
Current OpenClaw releases include Tlon as a bundled plugin; packaged builds don't require a separate installation.
For older builds or custom installs that omit it, install via npm:
openclaw plugins install @openclaw/tlon
Track the current release tag by using the bare package name. For reproducible installs, pin a version (@openclaw/tlon@x.y.z).
From a local checkout:
openclaw plugins install ./path/to/local/tlon-plugin
Details: Plugins
Setup
openclaw channels add --channel tlon --ship ~sampel-palnet --url https://your-ship-host --code lidlut-tabwed-pillex-ridrup
Alternatively, edit the config directly:
{
channels: {
tlon: {
enabled: true,
ship: "~sampel-palnet",
url: "https://your-ship-host",
code: "lidlut-tabwed-pillex-ridrup",
ownerShip: "~your-main-ship", // recommended: your ship, always authorized
},
},
}
After editing config directly, restart the gateway. Then DM the bot or @ mention it in a group channel.
Inbound durability
Before agent dispatch, OpenClaw persists accepted Tlon DM and group-chat events. Pending or retryable turns survive a Gateway restart, and work stays serialized per group channel or direct peer. Stable Urbit message IDs also prevent a redelivered event from processing while its queue record or retained completion record remains.
Across the queue-to-agent boundary, delivery is at least once: a crash during handoff can replay a turn. Consequently, agent actions with external side effects should remain idempotent where feasible.
Private/LAN ships
By default, OpenClaw blocks private/internal hostnames and IP ranges for SSRF protection. If your ship operates on a private network (localhost, LAN IP, internal hostname), opt in explicitly:
{
channels: {
tlon: {
url: "http://localhost:8080",
network: {
dangerouslyAllowPrivateNetwork: true,
},
},
},
}
Applies to targets like http://localhost:8080, http://192.168.x.x:8080, and http://my-ship.local:8080. Only enable this for a ship URL you trust; it disables SSRF protection for that account's HTTP requests.
Note
channels.tlon.allowPrivateNetwork(flat key) is retired.openclaw doctor --fixmoves it tochannels.tlon.network.dangerouslyAllowPrivateNetworkautomatically.
Group channels
Pin channels manually, or enable auto-discovery:
{
channels: {
tlon: {
groupChannels: ["chat/~host-ship/general", "chat/~host-ship/support"],
autoDiscoverChannels: true,
},
},
}
When unset in config, autoDiscoverChannels defaults to false; the setup wizard defaults the prompt to yes and writes true explicitly. With it on, OpenClaw scries joined groups on startup, watches new channels as group invites are accepted, and rechecks every 2 minutes.
Access control
DM allowlist (empty = no DMs allowed unless the sender is ownerShip):
{
channels: {
tlon: {
dmAllowlist: ["~zod", "~nec"],
},
},
}
Per channel, group authorization defaults to restricted. Set defaultAuthorizedShips for a baseline, and override per channel nest:
{
channels: {
tlon: {
defaultAuthorizedShips: ["~zod"],
authorization: {
channelRules: {
"chat/~host-ship/general": {
mode: "restricted",
allowedShips: ["~zod", "~nec"],
},
"chat/~host-ship/announcements": {
mode: "open",
},
},
},
},
},
}
Once the bot has replied inside a thread, it continues responding to later messages in that thread without needing another mention.
Set channels.tlon.implicitMentions.threadParticipation: false to require a new explicit mention for those follow-ups. Account overrides use channels.tlon.accounts.<id>.implicitMentions. Tlon does not currently produce replyToBot or quotedBot facts, so those flags have no effect here.
Owner and approval system
{
channels: {
tlon: {
ownerShip: "~your-main-ship",
},
},
}
The owner ship is authorized everywhere: DM invites are always auto-accepted, group invites are always auto-accepted, and channel messages always pass authorization. The owner does not need to be in dmAllowlist, defaultAuthorizedShips, or groupInviteAllowlist.
When ownerShip is set, unauthorized requests aren't simply dropped; they queue a pending approval and DM the owner:
- DM requests from ships not on
dmAllowlist - Mentions in channels where the sender fails authorization
- Group invites from ships not on
groupInviteAllowlist(when auto-accept is off, or on but the inviter is not allowlisted)
The owner replies in DM to act on a request:
| Owner reply | Effect |
|---|---|
approve / deny / block | Acts on the most recent pending approval |
approve <id> / deny <id> | Acts on a specific approval by id |
block | Also blocks the ship natively so it cannot reconnect |
unblock ~ship | Reverses a native block |
blocked | Lists currently blocked ships |
pending | Lists pending approval requests |
Without ownerShip configured, unauthorized DMs and channel mentions are just dropped and logged; there is no approval prompt.
Auto-accept settings
Auto-accept DM invites from ships already on dmAllowlist (the owner is always auto-accepted regardless of this flag):
{
channels: {
tlon: {
autoAcceptDmInvites: true,
},
},
}
Auto-accept group invites from an allowlist (fails closed: with autoAcceptGroupInvites: true and an empty groupInviteAllowlist, no non-owner invite is accepted):
{
channels: {
tlon: {
autoAcceptGroupInvites: true,
groupInviteAllowlist: ["~zod"],
},
},
}
Hot-reload via Urbit settings store
Most of the settings listed above (dmAllowlist, groupInviteAllowlist, groupChannels,
defaultAuthorizedShips, autoDiscoverChannels, autoAcceptDmInvites,
autoAcceptGroupInvites, ownerShip, showModelSignature) get copied into the ship's
%settings agent (desk moltbot, bucket tlon) during the initial run, and from that point on they are read directly from there. As a result, any adjustments made through a Landscape client or via the bundled skill's settings commands take effect without needing to restart the gateway. channelRules and pending approvals are likewise stored there in JSON format. For values that are never written to the settings store, the file configuration continues to act as the authoritative source.
Delivery targets (CLI/cron)
Pair this with openclaw message send or cron-based delivery:
- DM:
~sampel-palnetordm/~sampel-palnet - Group:
chat/~host-ship/channelorgroup:~host-ship/channel
Bundled skill
Included in the plugin is @tloncorp/tlon-skill, a command-line tool for direct Urbit operations, which becomes accessible as soon as the plugin is installed:
- Activity: mentions, replies, unreads
- Channels: list, create, rename
- Contacts: list/get/update profiles
- Groups: create, join, invite/request flows, roles
- Hooks: manage channel hooks
- Messages: history, search
- DMs: send, react, accept/decline
- Posts: react, delete
- Notebook: post to diary channels
- Settings: hot-reload plugin config via the settings store above
Capabilities
channels.tlon.mediaMaxMb sets the MiB limit for each inbound image download and outbound image load. Named accounts can override this with accounts.<id>.mediaMaxMb; otherwise, the channel root is consulted, followed by agents.defaults.mediaMaxMb. The pre-existing 6 MiB ceiling still governs image downloads and uploads. When a cap is configured, a failed size check or download causes the send to fail rather than embedding an unchecked URL. If an upload fails after a bounded download succeeds, the original URL can still be used. In the absence of a configured cap, the existing link fallback stays available even when the image cannot be fetched within that ceiling.
| Feature | Status |
|---|---|
| Direct messages | Supported |
| Groups/channels | Supported (mention-gated by default) |
| Threads | Supported (keeps replying once it has joined) |
| Rich text | Markdown converted to Tlon's native format |
| Images | Downloaded inbound, uploaded outbound |
| Reactions | Only via the bundled skill |
| Polls | Not supported |
| Native commands | Owner-only by default |
Troubleshooting
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
Typical issues:
- DMs ignored: the sender is not in
dmAllowlistand noownerShiphas been set up for the approval flow. - Group messages ignored: the channel has not been discovered or pinned, or the sender fails authorization and there is no
ownerShipto queue an approval. - Connection errors: verify the ship URL is reachable; for local ships, set
network.dangerouslyAllowPrivateNetwork. - Auth errors: login codes rotate, so copy the current code from your ship.
Configuration reference
Complete configuration: Configuration
| Key | Meaning |
|---|---|
channels.tlon.enabled | Turns channel startup on or off. |
channels.tlon.ship | The Urbit ship name used by the bot (for instance, ~sampel-palnet). |
channels.tlon.url | Ship URL, such as https://sampel-palnet.tlon.network. |
channels.tlon.code | Login code for the ship. |
channels.tlon.network.dangerouslyAllowPrivateNetwork | Permits ship URLs on localhost/LAN (SSRF opt-in). |
channels.tlon.ownerShip | Owner ship: always trusted, gets approval requests. |
channels.tlon.dmAllowlist | Ships that can DM (empty means only the owner). |
channels.tlon.autoAcceptDmInvites | Automatically accepts DMs coming from ships listed in dmAllowlist. |
channels.tlon.autoAcceptGroupInvites | Automatically accepts group invites originating from groupInviteAllowlist. |
channels.tlon.groupInviteAllowlist | Ships whose group invites get auto-accepted. |
channels.tlon.autoDiscoverChannels | Automatically discovers channels in joined groups (default: false). |
channels.tlon.implicitMentions.threadParticipation | Lets follow-ups in participated threads bypass mention gating. |
channels.tlon.groupChannels | Channel nests pinned manually. |
channels.tlon.defaultAuthorizedShips | Ships authorized across all channels (applied when no rule matches). |
channels.tlon.authorization.channelRules | Per-channel-nest auth mode plus allowlist. |
channels.tlon.showModelSignature | Adds _[Generated by <model>]_ to the end of replies. |
channels.tlon.responsePrefix | Automatic reply prefix: literal text, "auto", or a template like "[{model}]"; account settings take priority, and "" turns it off. |
channels.tlon.accounts.<id> | Extra named accounts for multi-ship configurations. |
Notes
- A reply in a group requires an @ mention (e.g.
~your-bot-ship) unless the bot has already joined that thread. - Replies to threads stay in-thread; the bot also receives the last 10 messages of thread context prepended for the agent.
- Rich text (bold, italic, code, headers, lists) gets converted into Tlon's native format.
- An inbound message asking for a channel summary (like "summarize this channel") triggers a built-in history summarization instead of the standard reply flow.
Related
- Channels Overview, all supported channels
- Pairing, DM authentication and pairing flow
- Groups, group chat behavior and mention gating
- Channel Routing, session routing for messages
- Security, access model and hardening