Disclaw
Manage Discord workspace structure and OpenClaw routing as code. Use when creating/renaming/deleting Discord channels, categories, threads, or managing agent...
Description
name: disclaw description: "Manage Discord workspace structure and OpenClaw routing as code. Use when creating/renaming/deleting Discord channels, categories, threads, or managing agent-to-channel bindings. Triggers on: Discord channels, workspace structure, channel setup, routing, binding, disclaw." metadata: openclaw: requires: bins: [disclaw] config: [channels.discord.token]
Disclaw — Discord Structure as Code
Disclaw manages Discord workspace structure (categories, channels, threads) and OpenClaw agent-to-channel bindings as code via a YAML config file.
Disclaw vs Discord plugin: Disclaw manages structure (create/rename/delete channels, categories, threads; manage bindings and routing gates). The Discord plugin manages messaging (send/receive, reactions, pins, thread replies). They do not conflict.
Installation
npm install -g @ofan/disclaw
disclaw --version
Prerequisites
- Discord bot token must be in OpenClaw config at
channels.discord.token - Gateway API access — add to
openclaw.json:
This lets disclaw read/write config via the gateway API. Without it, disclaw falls back to CLI.{ gateway: { tools: { allow: ["gateway"] } } } - Config file — create
disclaw.yamlin the workspace (see format below)
Verify Setup
disclaw validate -c disclaw.yaml
disclaw diff -c disclaw.yaml
Config File Format
The config file (disclaw.yaml) declares the desired state of Discord workspace structure.
version: 1
managedBy: disclaw
guild: "YOUR_GUILD_ID"
channels:
# Standalone channel (no category)
- name: announcements
topic: "Important announcements"
# Category with channels
- category: Engineering
channels:
- name: general
threads: [Standup, Retro]
- name: alerts
topic: "Automated alerts only"
# Another category
- category: Support
channels:
- name: tickets
- name: escalations
# OpenClaw agent bindings (optional)
openclaw:
requireMention: false
agents:
main: general # single channel
siren: [general, alerts] # multiple channels
support: # with options
channel: tickets
requireMention: true
Key rules
guildis the Discord server ID (right-click server → Copy Server ID)- Channel names must be lowercase, no spaces (Discord enforces this)
- Thread names can have spaces and mixed case
- Agent bindings reference channel names from the
channelssection requireMentioncontrols whether the bot needs @mention to respond in that channel
Commands
disclaw diff — Show what would change
disclaw diff -c disclaw.yaml
disclaw diff -c disclaw.yaml --json # structured output
disclaw diff -c disclaw.yaml --channel alerts # filter by channel
Shows: managed resources (create/update/delete/noop), unmanaged resources, unbound agents, stale agents, routing health warnings, and pinned messages.
disclaw apply — Apply changes (dry-run by default)
disclaw apply -c disclaw.yaml # dry-run (shows what would change)
disclaw apply -c disclaw.yaml --yes # actually apply changes
disclaw apply -c disclaw.yaml --prune --yes # also delete unmanaged resources
Safety: Always takes a snapshot before mutating. Creates before deletes. Bindings and routing gates are updated atomically.
disclaw import — Import unmanaged Discord resources
disclaw import -c disclaw.yaml # dry-run (shows what would be imported)
disclaw import -c disclaw.yaml --yes # write to config file
Discovers Discord channels/categories/threads not in the config and adds them. Also finds unbound OpenClaw agents.
disclaw rollback — Restore from snapshot
disclaw rollback -c disclaw.yaml # dry-run
disclaw rollback -c disclaw.yaml --yes # actually rollback
Restores Discord state from the most recent pre-apply snapshot. Drift-aware (shows what changed since the snapshot).
disclaw validate — Validate config (no API calls)
disclaw validate -c disclaw.yaml
disclaw validate -c disclaw.yaml --json
Safe for CI. Checks: schema validity, empty names, duplicate channels/threads, binding refs pointing to non-existent channels.
Filter flags (diff, apply, import)
--category <names...> # filter by category name
--channel <names...> # filter by channel name
--thread <names...> # filter by thread name
--agent <names...> # filter by agent name
--json # structured JSON output
Gateway options (all commands except validate)
--gateway-url <url> # override gateway URL (default: http://127.0.0.1:18789)
--gateway-token <token> # override gateway auth token
Also via env vars: OPENCLAW_GATEWAY_URL, OPENCLAW_GATEWAY_TOKEN.
Common Workflows
Add a new channel
- Edit
disclaw.yaml— add channel under the appropriate category - Validate:
disclaw validate -c disclaw.yaml - Preview:
disclaw diff -c disclaw.yaml - Apply:
disclaw apply -c disclaw.yaml --yes
Bind an agent to a channel
- Edit
disclaw.yaml— add entry underopenclaw.agents - Preview:
disclaw diff -c disclaw.yaml - Apply:
disclaw apply -c disclaw.yaml --yes
This creates the binding AND allowlists the channel in routing gates automatically.
Import existing Discord channels
- Run:
disclaw import -c disclaw.yaml(dry-run to preview) - Review the output
- Run:
disclaw import -c disclaw.yaml --yes(writes to config) - Verify:
disclaw diff -c disclaw.yaml
Delete a channel
- Remove the channel from
disclaw.yaml - Preview:
disclaw apply -c disclaw.yaml --prune - Apply:
disclaw apply -c disclaw.yaml --prune --yes
Warning: --prune is required for deletions. Without it, removed channels are shown as "unmanaged" but not deleted.
Rename a channel
- Change the channel name in
disclaw.yaml - Preview:
disclaw diff -c disclaw.yaml(shows delete old + create new) - Apply:
disclaw apply -c disclaw.yaml --yes
Note: Discord doesn't support true renames via API — disclaw creates the new channel and (with --prune) deletes the old one.
Troubleshooting
"Discord bot token not found"
- Ensure
channels.discord.tokenis set inopenclaw.json - Or set
DISCORD_BOT_TOKENenv var
"Gateway tool not available"
- Add
gateway.tools.allow: ["gateway"]toopenclaw.json - Or disclaw will fall back to CLI automatically
"Gateway auth failed"
- Check
OPENCLAW_GATEWAY_TOKENenv var matchesgateway.auth.tokenin config - Or pass
--gateway-token <token>
"OpenClaw CLI timed out"
- Check if the gateway is running:
openclaw status - Check network:
curl http://127.0.0.1:18789/
"Discord connection timed out"
- Check internet connectivity
- Verify bot token is valid
- Try again (Discord API can be flaky)
"Permission denied" during apply
- Bot needs: Manage Channels, Manage Threads permissions
- Check bot role position in Discord server settings
Safety
- Dry-run by default — all mutating commands require
--yes - Snapshot before apply — automatic, saved to
.disclaw/snapshots/ - Rollback available —
disclaw rollback -c disclaw.yaml --yes - Managed-scope only — disclaw only touches resources in the config
- Creates before deletes — safer ordering during apply
- Validation — config is validated before any API calls
Reviews (0)
No reviews yet. Be the first to review!
Comments (0)
No comments yet. Be the first to share your thoughts!