/add-discord
Add Discord bot channel integration via Chat SDK.
Claude Code
$ npx -y skills add nanocoai/nanoclaw --skill add-discord --agent claude-code
Codex
$ npx skills add nanocoai/nanoclaw --skill add-discord -a codex -y
Cursor
$ npx skills add nanocoai/nanoclaw --skill add-discord -a cursor -y
Gemini CLI
$ npx skills add nanocoai/nanoclaw --skill add-discord -a gemini-cli -y
GitHub Copilot
$ npx skills add nanocoai/nanoclaw --skill add-discord -a github-copilot -y
OpenCode
$ npx skills add nanocoai/nanoclaw --skill add-discord -a opencode -y
Windsurf
$ npx skills add nanocoai/nanoclaw --skill add-discord -a windsurf -y
SKILL.md
add-discord.SKILL.mdname: add-discord
description: Add Discord bot channel integration via Chat SDK.
Add Discord Channel
Adds Discord bot support via the Chat SDK bridge. NanoClaw doesn't ship channels in trunk — this skill copies the Discord adapter in from the `channels` branch.
The mechanical steps under **Apply** carry `nc:` directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it.
Apply
1. Copy the adapter and its tests
Fetch the `channels` branch and copy the Discord adapter, its registration test and its gateway test into `src/channels/` (overwrite — the branch is canonical):
src/channels/discord.ts
src/channels/discord-registration.test.ts
src/channels/discord-gateway.test.ts
2. Register the adapter
Append the self-registration import to the channel barrel (skipped if the line is already present). This one line is the skill's only reach-in into core:
import './discord.js';
3. Configure the adapter patch
Adapter 4.41.1 drops every server message that @mentions anyone. It serializes the Discord gateway packet after discord.js has patched it in place into a circular object, so the forward throws and the message never arrives. The committed pnpm patch backports the fix from adapter 4.42.0. Register it before installing the package. pnpm reapplies it after every install and fails if the pinned package drifts away from the patch:
patches/@chat-adapter__discord@4.41.1.patch
The reinstall applies the patch to an install that already has the adapter, since the step below skips a package that is already present. It runs only then: pnpm refuses a patch for a package that isn't installed, so a fresh install gets the patch from the step below instead:
pnpm pkg set 'pnpm.patchedDependencies[@chat-adapter/discord@4.41.1]=patches/@chat-adapter__discord@4.41.1.patch'
if node -e 'process.exit(require("./package.json").dependencies?.["@chat-adapter/discord"] ? 0 : 1)'; then pnpm install --no-frozen-lockfile; fiAdapter 4.42.0 and later carry the fix. Installs keep this registration, so the bump past 4.41.1 must replace this step with an `effect:refresh` step that removes it before the install (see `ERR_PNPM_UNUSED_PATCH` under Troubleshooting).
4. Install the adapter package
Pinned to an exact version — the supply-chain policy rejects ranges and `latest`:
@chat-adapter/discord@4.41.1
5. Build and validate
Build first: it guards the typed `createChatSdkBridge(...)` core call and proves the dependency is installed. Then run the two tests.
pnpm run build
pnpm exec vitest run src/channels/discord-registration.test.ts src/channels/discord-gateway.test.ts
`discord-registration.test.ts` imports the real channel barrel and asserts the registry contains `discord`. It goes red if the import line is deleted or drifts, if the barrel fails to evaluate, or if `@chat-adapter/discord` isn't installed (the import throws) — so it also covers the dependency from step 4. End-to-end delivery against a real server is verified manually once the service runs.
`discord-gateway.test.ts` feeds the installed adapter a server message that @mentions the bot, with the in-place change discord.js makes to it, and asserts the message reaches the webhook as sent. It goes red when the adapter lacks the step 3 patch.
Credentials
Discord app setup is human and interactive — no parser can click through the Discord Developer Portal. The adapter is installed and registered, but it can't receive a message until the bot exists, has Message Content Intent, and shares a server with you. Tell the user:
Create the Discord bot:
1. Go to https://discord.com/developers/applications → New Application. Name it (e.g. "NanoClaw Assistant").
2. Bot tab → Add Bot if needed → Reset Token, then copy the Bot Token (it's shown only once).
3. Bot tab → Privileged Gateway Intents → enable Message Content Intent.
4. OAuth2 → URL Generator → Scopes: bot; Bot Permissions: Send Messages, Read Message History, Add Reactions, Attach Files, Use Slash Commands.
5. Open the generated URL and invite the bot to a server you're also in (a personal server is fine) — the bot can only DM you once you share a server.
Paste the Bot Token (it's shown only once). You don't paste the Application ID or the Public Key by hand — the bot's own application record carries both, so a single call derives them from the token:
Paste the Bot Token — Bot tab. Click `Reset Token` if you need a new one.
Read the application's own record. `GET /oauth2/applications/@me` returns the Application ID (`id`), the Public Key (`verify_key`), and your own account as the app's owner (`owner.id`) — so the App ID, the Public Key, and your Discord user ID all come from this one call instead of being copied by hand. A bad token fails here, before the restart, rather than silently later:
curl -sf https://discord.com/api/v10/oauth2/applications/@me -H "Authorization: Bot {{bot_token}}"Store the token and the two derived credentials — the adapter reads them from `.env` and fails to start without `DISCORD_PUBLIC_KEY` and `DISCORD_APPLICATION_ID` (set-if-absent, so a value you've already filled in is never overwritten):
DISCORD_BOT_TOKEN={{bot_token}}
DISCORD_APPLICATION_ID={{application_id}}
DISCORD_PUBLIC_KEY={{public_key}}Restart
Restart the service so it loads the Discord adapter and the credentials you just stored, and wait for its CLI socket before resolving:
Read more
name: add-discord description: Add Discord bot channel integration via Chat SDK.
Add Discord Channel
Adds Discord bot support via the Chat SDK bridge. NanoClaw doesn't ship channels in trunk — this skill copies the Discord adapter in from the `channels` branch.
The mechanical steps under **Apply** carry `nc:` directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it.
Apply
1. Copy the adapter and its tests
Fetch the `channels` branch and copy the Discord adapter, its registration test and its gateway test into `src/channels/` (overwrite — the branch is canonical):
src/channels/discord.ts src/channels/discord-registration.test.ts src/channels/discord-gateway.test.ts
2. Register the adapter
Append the self-registration import to the channel barrel (skipped if the line is already present). This one line is the skill's only reach-in into core:
import './discord.js';
3. Configure the adapter patch
Adapter 4.41.1 drops every server message that @mentions anyone. It serializes the Discord gateway packet after discord.js has patched it in place into a circular object, so the forward throws and the message never arrives. The committed pnpm patch backports the fix from adapter 4.42.0. Register it before installing the package. pnpm reapplies it after every install and fails if the pinned package drifts away from the patch:
patches/@chat-adapter__discord@4.41.1.patch
The reinstall applies the patch to an install that already has the adapter, since the step below skips a package that is already present. It runs only then: pnpm refuses a patch for a package that isn't installed, so a fresh install gets the patch from the step below instead:
pnpm pkg set 'pnpm.patchedDependencies[@chat-adapter/discord@4.41.1]=patches/@chat-adapter__discord@4.41.1.patch'
if node -e 'process.exit(require("./package.json").dependencies?.["@chat-adapter/discord"] ? 0 : 1)'; then pnpm install --no-frozen-lockfile; fiAdapter 4.42.0 and later carry the fix. Installs keep this registration, so the bump past 4.41.1 must replace this step with an `effect:refresh` step that removes it before the install (see `ERR_PNPM_UNUSED_PATCH` under Troubleshooting).
4. Install the adapter package
Pinned to an exact version — the supply-chain policy rejects ranges and `latest`:
@chat-adapter/discord@4.41.1
5. Build and validate
Build first: it guards the typed `createChatSdkBridge(...)` core call and proves the dependency is installed. Then run the two tests.
pnpm run build
pnpm exec vitest run src/channels/discord-registration.test.ts src/channels/discord-gateway.test.ts
`discord-registration.test.ts` imports the real channel barrel and asserts the registry contains `discord`. It goes red if the import line is deleted or drifts, if the barrel fails to evaluate, or if `@chat-adapter/discord` isn't installed (the import throws) — so it also covers the dependency from step 4. End-to-end delivery against a real server is verified manually once the service runs.
`discord-gateway.test.ts` feeds the installed adapter a server message that @mentions the bot, with the in-place change discord.js makes to it, and asserts the message reaches the webhook as sent. It goes red when the adapter lacks the step 3 patch.
Credentials
Discord app setup is human and interactive — no parser can click through the Discord Developer Portal. The adapter is installed and registered, but it can't receive a message until the bot exists, has Message Content Intent, and shares a server with you. Tell the user:
Create the Discord bot: 1. Go to https://discord.com/developers/applications → New Application. Name it (e.g. "NanoClaw Assistant"). 2. Bot tab → Add Bot if needed → Reset Token, then copy the Bot Token (it's shown only once). 3. Bot tab → Privileged Gateway Intents → enable Message Content Intent. 4. OAuth2 → URL Generator → Scopes: bot; Bot Permissions: Send Messages, Read Message History, Add Reactions, Attach Files, Use Slash Commands. 5. Open the generated URL and invite the bot to a server you're also in (a personal server is fine) — the bot can only DM you once you share a server.
Paste the Bot Token (it's shown only once). You don't paste the Application ID or the Public Key by hand — the bot's own application record carries both, so a single call derives them from the token:
Paste the Bot Token — Bot tab. Click `Reset Token` if you need a new one.
Read the application's own record. `GET /oauth2/applications/@me` returns the Application ID (`id`), the Public Key (`verify_key`), and your own account as the app's owner (`owner.id`) — so the App ID, the Public Key, and your Discord user ID all come from this one call instead of being copied by hand. A bad token fails here, before the restart, rather than silently later:
curl -sf https://discord.com/api/v10/oauth2/applications/@me -H "Authorization: Bot {{bot_token}}"Store the token and the two derived credentials — the adapter reads them from `.env` and fails to start without `DISCORD_PUBLIC_KEY` and `DISCORD_APPLICATION_ID` (set-if-absent, so a value you've already filled in is never overwritten):
DISCORD_BOT_TOKEN={{bot_token}}
DISCORD_APPLICATION_ID={{application_id}}
DISCORD_PUBLIC_KEY={{public_key}}Restart
Restart the service so it loads the Discord adapter and the credentials you just stored, and wait for its CLI socket before resolving:
A lightweight alternative to OpenClaw that runs in containers for security. Connects to WhatsApp, Telegram, Slack, Discord, Gmail and other messaging apps,, has memory, scheduled jobs, and runs directly on Anthropic's Agents SDK
Other skills on nanoclaw.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
opencli-adapter-author
Build or improve an OpenCLI JS adapter using observed site behavior, existing adapters and browser API evidence. For ad-hoc…
Questions about add-discord.
- Which coding agents can use add-discord?
- add-discord installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

