discord-app-setup
The discord-app-setup skill guides users through creating a Discord application and configuring a bot to connect to an assistant via the Discord Gateway. Use this skill when setting up a new Discord bot integration for the first time, as it walks through application creation, bot user configuration with required intents, and secure credential collection in the correct sequence without skipping steps.
git clone --depth 1 https://github.com/vellum-ai/vellum-assistant /tmp/discord-app-setup && cp -r /tmp/discord-app-setup/skills/discord-app-setup ~/.claude/skills/discord-app-setupSKILL.md
You are helping your user create a Discord application and connect a Discord bot to the assistant via the Discord Gateway. Walk through each step below.
**CRITICAL: Follow these steps strictly in order. Do NOT combine steps, skip ahead, or ask for the bot token before the bot user has been configured. The token is shown only once after reset — collect it the moment the user generates it, never before.**
## Value Classification
| Value | Type | Secret? |
| --------- | ---------- | ------- |
| Bot Token | Credential | **Yes** |
The **Bot Token** is the only value that needs to be persisted. Always collect it via the assistant's secure credential prompt — never accept it pasted in plaintext chat.
The Application ID and Public Key are derivable from the bot token at any time via Discord's API and do not need to be stored separately.
# Setup Steps
## Step 0: Check Existing Configuration
Before starting, run the check script:
```bash
bun skills/discord-app-setup/scripts/check-config.ts
```
The script outputs JSON: `{ "configured": boolean, "details": string, "error"?: string }`.
- If `error` is present, **stop**. The check could not run, so the credential state is unknown, and `configured: false` here does **not** mean "not set up". Do not start the setup walkthrough. It will not fix this, and re-running setup on an app that already has a token forces a needless token reset that breaks any other deployment using it.
- `cli_not_found` means the `assistant` command is missing from this environment's PATH. That is an installation problem. Report it as one, quote `details`, and stop.
- `cli_failed` or `unparseable_output` means the CLI ran but did not answer usefully. Report `details` verbatim and stop.
- If `configured` is `true` — Discord is already set up. Offer to verify the connection or reconfigure.
- If `configured` is `false` with no `error`, the check ran and found no token. Continue to Step 0.5.
## Step 0.5: Prefer the In-Product Wizard
If an interactive client is connected, call `ui_show` with `surface_type: "channel_setup"` and `data: { channel: "discord" }`. This opens the Discord setup wizard in the side panel: create the app, connect the token through a masked field, and add the bot to a server, all without the token entering chat. The wizard is non-blocking and auto-notifies you when it is closed.
⚠️ **Tool call first, announcement second, in the same turn.** Do not claim the wizard is open until the `ui_show` call has returned success. After success, tell the user:
> I've opened the Discord setup wizard in the side panel. It walks you through creating the app, connecting its bot token, and adding the bot to a server. It will notify me when you close it; ask me here if you hit a snag.
When the wizard-closed notification arrives, re-run the Step 0 check script to confirm a token was stored. A stored token completes Steps 1 through 4; the invite (Step 5) happens on the wizard's last step, and closing the panel does not prove it happened. Ask the user directly:
> Did you add the bot to a server on the wizard's last step? If not, I can give you the install link again.
If they did not, run the Step 5 invite script and have them complete it before continuing. Only then continue at Step 6 (identity verification). Do not mark setup complete while the bot is in no server.
If `ui_show` fails (no interactive client, or the surface is rejected), fall back to the chat-guided flow below: it collects the token through the secure credential prompt instead.
## Step 1: Create the Discord Application
Tell the user:
> Open **https://discord.com/developers/applications** and click **New Application** in the top-right. Give it a name (this is how the bot appears to users) and accept the Developer Terms of Service. After creation you'll land on the application's **General Information** page.
Wait for the user to confirm they've created the app before proceeding. Discord does not support manifest-based creation — the rest of the configuration happens step by step in the portal.
**Offer the assistant's avatar as the app icon.** General Information is where Discord takes one, so this is the moment to mention it; the wizard path in Step 0.5 shows the same thing on its own create step. The rendered PNG sits at `$VELLUM_WORKSPACE_DIR/data/avatar/avatar-image.png` and is 512x512 for a character avatar. Tell the user:
> While you're on **General Information**, you can set the bot's icon to your assistant's avatar. I can point you at the file if you'd like it.
Skip this if the assistant has no avatar set. It is cosmetic, so do not block setup on it.
## Step 2: Configure the Bot User
Discord automatically attaches a Bot user to every new application. This integration needs **no privileged intents**, so the only thing to do here is confirm all three are off.
Direct the user:
> In the left sidebar click **Bot**. Scroll to **Privileged Gateway Intents** and leave all three **OFF**:
>
> - ⬜ **Presence Intent**
> - ⬜ **Server Members Intent**
> - ⬜ **Message Content Intent**
>
> If any are already enabled, turn them off and click **Save Changes**.
Why none are needed: the assistant's Discord client identifies with the non-privileged `GUILDS`, `GUILD_MESSAGES`, and `DIRECT_MESSAGES` intents only. It acts on messages that mention the bot and on DMs sent to it, and Discord exempts four cases from the Message Content restriction: messages that mention your app, DMs with your app, your app's own messages, and the target of a message context-menu command. Every message the assistant reads falls inside that exemption and already arrives with full text. Server Members would deliver `GUILD_MEMBER_*` events that nothing here consumes.
Turning them on would grant access the software never reads, and would opt the app into Discord's privileged-intent review (with annual reapplication) once it is visible to more than 10,000 users.
> ℹ️ Two different Discord thresholds are easy to conf>
>
>
>
Check Vellum Assistant architecture and package boundaries. Use when editing imports, moving code, adding endpoints, touching assistant/gateway/client/skill boundaries, or reviewing architecture-sensitive changes.
Review Vellum Assistant code changes for correctness, repo-specific quality rules, security risks, and missing validation. Use when reviewing diffs, preparing a PR, finishing implementation work, or when the user asks for a code review, quality pass, or pre-merge check in this repository.
Guide Vellum Assistant feature flag changes and rollout hygiene. Use when adding, editing, reviewing, or documenting assistant feature flags, rollout-gated behavior, or platform flag follow-up work.
Validate Vellum Assistant database and workspace migrations. Use when adding, editing, reviewing, or testing migrations, release-note migrations, persisted schemas, workspace file formats, or data backfills.