If you already live in Discord and want an AI helper that sees the same channels you do, wiring OpenClaw into your server is the fastest path. This tutorial walks through everything I wish I'd known: creating the Discord application, locking down OAuth2 scopes, mapping channels, designing slash commands, and deciding whether to host the bot in a private guild or drop it into an existing one. I’ll finish with the self-cloning pattern—letting OpenClaw spin up fresh servers for new users.

Why run OpenClaw on Discord instead of yet another chat UI?

• You already have notifications on every device.
• Role-based permissions mean you can separate #ops from #random without extra code.
• Discord’s slash command UX is miles ahead of raw text prompts.
• WebSockets are free; you’re not paying per message like with SMS or WhatsApp.
• Most dev teams are on Discord anyway, so you get zero-friction onboarding.

OpenClaw 1.7.3 (current master as of June 2024) ships a first-party Discord connector living in packages/connector-discord. The code runs fine on Node 22.3 LTS—the same version the gateway expects. I strongly recommend sticking to that version until Discord finally fixes their ES module breakage in 23.x.

Prerequisites

  • Node ≥ 22.0.0 and npm ≥ 10 (or pnpm if you hate disk usage)
  • A Discord account with “Manage Server” rights on at least one guild
  • OpenClaw daemon running locally (npm i -g openclaw@latest) or a ClawCloud account
  • Postgres or SQLite for OpenClaw’s memory store (Out-of-the-box SQLite works fine for small teams)

Step 1 — Create a Discord application & bot user

1.1 Register the app

Head to discord.com/developers/applications → New Application. Name it something unambiguous like openclaw-assistant. Save.

1.2 Add a bot user

Navigate to Bot → “Add Bot”. Feel free to disable “Public Bot” if you don’t want randos inviting it. Note the following values:

  • BOT_TOKEN (hit “Reset Token” and copy)
  • Client ID
  • Public Key (needed for slash command verification)

We’ll drop these into environment variables in a minute.

1.3 Turn on privileged intents

Enable Message Content Intent, plus Server Members Intent if you plan to greet newcomers. Without message content, the bot sees only its own messages and gets useless fast.

Step 2 — Build the OAuth2 URL and invite your bot

2.1 Pick the right scopes

For most assistants you need only:

  • bot
  • applications.commands

The first lets the bot connect to the gateway; the second registers slash commands.

2.2 Choose granular permissions

Discord’s permission integer builder is awful. I use the REST endpoint instead:

curl -G https://discord.com/api/v10/oauth2/authorize \ --data-urlencode "client_id=123456789012345678" \ --data-urlencode "scope=bot%20applications.commands" \ --data-urlencode "permissions=274877990912" # Send Messages + Read History + Use Slash Commands

Permissions 274877990912 maps to:

  • View Channels
  • Send Messages
  • Embed Links & Attach Files
  • Add Reactions
  • Use Slash Commands

Stick to least privilege. You don’t need Administrator unless you plan to let OpenClaw kick your colleagues.

2.3 Invite

Open the generated URL in your browser, pick a server where you have “Manage Server”, and authorize. The bot should now appear offline in your member list—good sign.

Step 3 — Install and configure the OpenClaw Discord connector

3.1 Global install (local testing)

# node 22.x recommended npm i -g openclaw@1.7.3

3.2 Create a project directory

mkdir ~/openclaw-discord && cd $_ openclaw init # writes openclaw.config.json

3.3 OpenClaw config snippet

{ "connectors": { "discord": { "enabled": true, "token": "$DISCORD_BOT_TOKEN", "clientId": "$DISCORD_CLIENT_ID", "publicKey": "$DISCORD_PUBLIC_KEY", "prefix": "!", // legacy commands, optional "intents": [ "Guilds", "GuildMessages", "MessageContent" ] } }, "memory": { "driver": "sqlite", "filename": "./openclaw.db" } }

You can also export environment variables instead of hard-coding them. OpenClaw will read process.env.DISCORD_BOT_TOKEN et al. if the JSON value is missing.

3.4 Fire it up

openclaw daemon start

The daemon spawns the gateway plus a worker for tools. You should see:

[discord] Logged in as openclaw-assistant#0420

Switch to Discord—the bot is now online.

Step 4 — Channel routing and slash command design

4.1 Default behavior

Out of the box, OpenClaw replies in the same channel where it’s mentioned. If the message is a DM, that’s enough. In busy guilds this gets noisy fast, so let’s route.

4.2 Map channels to tools

Add a simple router inside src/routers/discord.js:

export default function route(message) { if (message.channel.name === 'status') { return 'system-status-flow'; } if (message.channel.name === 'db') { return 'sql-flow'; } return 'default'; }

Then reference it in openclaw.config.json:

"discord": { "router": "./src/routers/discord.js" }

4.3 Slash commands

Discord forces an interaction-based flow for slash commands. Register them at startup:

openclaw discord sync-commands ./commands

Example ./commands/ping.js:

export default { name: 'ping', description: 'Is OpenClaw awake?', execute: async (interaction, claw) => { const t0 = Date.now(); await interaction.deferReply(); const reply = await claw.run('ping-flow'); const latency = Date.now() - t0; await interaction.editReply(`${reply} (latency ${latency}ms)`); } };

Every time you change the command list you must re-sync or wait up to an hour for Discord propagation.

Dedicated private server vs dropping into an existing guild

5.1 Trade-offs

  • Existing guild — quickest test, no extra invites, but permission spaghetti grows over time.
  • Private guild — clean security boundary, easier to grant the bot Admin without wrecking production chat, but you lose organic conversations that teach the model.

On my team we keep a claw-lab server. The main company Discord stays bot-free except for a single #assistant channel bridged over Webhooks. Works fine, keeps the CEO from accidentally typing /rm -rf *.

5.2 Moving later

Discord does not support transferring slash commands across guilds. If you start in a private guild and later invite the bot elsewhere, you must run sync-commands again with --guild flag or use global commands (slower prop time).

The self-cloning pattern: let OpenClaw spawn new servers

One popular community request is the “clone yourself” ability: a user DMs the bot clone me, and the bot spins up a new private server where that user + the bot are members. Great for consultants spinning dedicated assistants per client.

6.1 Required scopes

Add guilds.join OAuth2 scope and give the bot Create Guild (permission 33554432). Note this only works for verified bots with fewer than 10 servers.

6.2 Minimal code

import { REST, Routes } from 'discord.js'; async function cloneGuild(user) { const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_BOT_TOKEN); const guild = await rest.post(Routes.guilds(), { body: { name: `openclaw-${user.username}` } }); // Wait for Discord to set up channels await new Promise(r => setTimeout(r, 5000)); // Invite user const channel = guild.channels.cache.find(c => c.type === 0); // first text channel const invite = await channel.createInvite({ maxAge: 86400, maxUses: 1 }); await user.send(`Here’s your private server: ${invite.url}`); }

Wire that into a flow entry point. Danger zone: you are now rate-limit fodder; Discord caps guild creation to 50/day.

Operational tips: logs, rate limits, secrets

  • Logs — Run the daemon with DEBUG=discord:* openclaw daemon start. Verbose but priceless during OAuth failures.
  • Rate limits — OpenClaw batches tool outputs, but Discord applies a hard 5 requests/second per route. Use setTimeout or a queue when posting long message chains.
  • Edit in place — Instead of spamming updates, use message.edit() so Discord counts it as one write.
  • Secrets — Do not bake BOT_TOKEN into docker-compose.yml. Use docker secret or ClawCloud’s encrypted env UI.
  • Backup memory — SQLite is fine until the file corrupts. Schedule a cron job: sqlite3 openclaw.db .dump | gzip > backup.sql.gz

Next steps

Your bot is now live, replying in Discord with full OpenClaw tooling—including browser control, shell access, and the Composio 800-tool surface. Play with it in a throwaway channel first; the !shell tool does exactly what it promises. From here, hook in GitHub webhooks for automatic PR triage or let the bot schedule meetings through Google Calendar. When you’re ready for production reliability, move the exact same config to ClawCloud: Settings → Import → Paste openclaw.config.json. The container starts in about 60 seconds and Discord will see no difference.

Keep it iterative: add one permission, one command, one tool at a time. Discord makes it too easy to expose everything. Resist. Your future self—and your audit log—will thank you.