
Nakama can run as a Discord bot so you can chat with the same agent from DMs, server channels, or threads.

The mental model is simple:

- Discord is a **channel** for Nakama
- The bridge talks to the same Nakama server as the web app
- Pairing links a real Discord user to your Nakama access

## What Discord supports

With Discord enabled, users can:

- chat with a Nakama profile in a private DM
- use the bot in server channels and threads after DM pairing
- switch org and profile with commands
- stop, clear, compact, or restart conversations
- receive streaming replies with typing indicators and live todo progress

Discord currently supports **text messages only**. Attachments and voice are not forwarded to the agent.

## Step 1: Create the bot in Discord

In the [Discord Developer Portal](https://discord.com/developers/applications), create an application, then configure it on two separate pages:

| Value | Portal location | For Nakama? |
| --- | --- | --- |
| **Bot token** | **Bot** | Yes — paste in **Integrations → Discord** |
| **Message Content Intent** | **Bot → Privileged Gateway Intents** | Yes — turn the toggle **on** |
| OAuth2 permissions | **OAuth2 → URL Generator** | Yes — invite the bot to your server |
| Application ID, Public Key | General Information | No |

### 1a. Bot tab — token and intent

1. Open **Bot** (not General Information) → **Add Bot** if needed → **Reset Token** → **Copy**
2. Scroll to **Privileged Gateway Intents** and turn **Message Content Intent** **on**

This toggle is required. Without it, the bridge worker logs `Used disallowed intents` and cannot connect. There is no API for this — you must flip the toggle in the Developer Portal.

### 1b. OAuth2 — invite the bot to a server

1. Open **OAuth2 → URL Generator**
2. Under **Scopes**, check `bot` and `applications.commands`
3. Under **Bot Permissions**, check:
   - **View Channels**
   - **Send Messages**
   - **Read Message History**
   - **Attach Files**
   - **Send Messages in Threads** (recommended if you use threads)
   - **Manage Threads** (recommended so `/close` can archive bot conversation threads)
4. Copy the generated URL, open it, pick a server, and approve

You can also use the **Invite bot to server** link on **Integrations → Discord** after saving your token — Nakama generates an invite with the right permissions.

Keep the token secret. If you enable Message Content Intent after the bot is already in a server, generate a fresh invite and add the bot again.

## Step 2: Save in Nakama

Open **Integrations → Discord**, then:

1. Paste the bot token
2. Choose the default Nakama profile for Discord replies
3. Save — Nakama generates a pairing code on the same page

## Step 3: Pair your Discord account

Pairing links your Discord user to Nakama so unlinked users cannot use the bot.

1. Copy the pairing code from **Integrations → Discord** (click **Regenerate** if needed)
2. Open a private DM with your bot and send the code as a plain text message

After a successful match, that user is linked and the code is cleared. Server channels require DM pairing first.

## Step 4: Start the Discord bridge

On **Integrations → Discord**, use the **Bridge worker** controls to start the worker.

The bridge connects to Discord and forwards messages to your Nakama server.

For local development only, you can instead run `bun run dev:discord` from the repo root.

## Optional: Direct allowlist instead of pairing

Nakama also supports allowlisting Discord user IDs directly.

This is useful when you want to pre-authorize specific users without the one-time pairing flow.

To add users from the dashboard:

1. Open **Integrations → Discord**
2. In **Allowed users**, click **Manage**
3. Paste a Discord user snowflake ID and click **Add**

Use the numeric Discord user ID (snowflake), not the `@username`.

You can also configure allowed users through `DISCORD_ALLOWED_USER_IDS` for environment-based deployments.

## Private chat behavior

Private chat is the simplest mode.

Once paired or allowlisted:

- normal messages go to the Nakama agent
- the bot keeps a Discord chat session
- slash commands work immediately

If an unlinked user opens the bot, Nakama asks for the pairing code instead of sending the message to the agent.

## Server and thread behavior

Nakama supports Discord servers, but it is intentionally conservative about when it replies.

In a server channel, the bot responds only when the message is:

- a slash command from Discord's command menu
- a reply to one of the bot's messages
- a direct `@mention` of the bot, or of a Discord role the bot holds

This keeps server channels usable without making the bot noisy.

### Threads and profiles

In Discord threads, each thread keeps its own Nakama session.

- In a parent server channel, every `@mention` or reply to the bot starts a **new** Discord thread (you do not need `/close` or `/new` first)
- Continue chatting inside a bot-started thread without mentioning the bot again
- The same user can have multiple open bot threads in one channel, and agent replies in different threads can run at the same time
- `/profile` inside a thread changes only that thread
- new threads inherit the channel-level profile set with `/profile` in the parent channel (or the default Discord profile if none is set)
- `/profile` in the main channel changes the channel-level profile used by new threads
- `/org` stays channel-level, so switch org first if a thread needs a profile from another org
- `/close` inside a bot-started thread archives that thread only; other open bot threads stay usable
- `/new` starts a fresh Nakama conversation in the current Discord thread (it does not open a new Discord thread)
- threads the bot did not start stay quiet until you `@mention` the bot (or reply to it); that claims the thread so follow-ups work without another mention

Replies in server channels are visible to everyone in that channel. Nakama prefixes those messages so the agent knows the reply is public.

## Discord commands

Session control uses Discord slash commands. Org and profile switching use text commands.

| Command | Type | What it does |
| --- | --- | --- |
| `/start` | Slash | Welcome and pairing help |
| `/help` | Slash | Show command help |
| `/stop` | Slash | Stop the current in-progress reply |
| `/clear` | Slash | Clear chat history |
| `/compact` | Slash | Compact conversation history |
| `/new` | Slash | Start a new conversation (same Discord thread) |
| `/close` | Slash | Close (archive) this bot conversation thread |
| `/status` | Slash | Show server and model status |
| `/org` | Text | Choose or switch organization |
| `/profile` | Text | Choose or switch profile |

In servers, `@mention` the bot (or a role it holds) or reply to it to chat — each mention in a parent channel opens a new thread. Complete DM pairing first.

## Reply formatting

Agents can write normal Markdown-style replies. Nakama sends them as plain Discord text and splits long replies into multiple messages when needed.

Discord has a 2000-character limit per message. Nakama automatically chunks longer replies.

## Saved artifacts and share links

When your agent saves a file for you with the `save-artifact` skill (content file plus `.nakama-meta.json` sidecar in the same turn), Nakama posts a **Publish-style share link** after the reply in Discord.

- The link uses the same unguessable `/s/{token}` URLs as dashboard Publish — no Nakama login required to open it.
- Anyone who can read the Discord message can open the link until the share is revoked from the web app.
- Set **Web Public URL** in Nakama settings (or `NAKAMA_WEB_PUBLIC_URL`) so channel footers include absolute links.

To receive the file itself in Discord, ask in plain language — for example, “send the file” or “attach the PDF”. The agent uses the Discord-only `send_discord_artifact` tool to upload a native attachment when the file is within Discord’s size limit. You can also type `/attach` as a shortcut for the most recent saved artifact. If the file is too large, use the share link instead.

Unpaired saves (content without a sidecar in the same turn) do not produce share links or attachments.

## Configuration notes

Nakama stores Discord bridge settings under its local config directory (default `~/.nakama/discord/`).

Important values include:

- bot token
- default Discord profile
- pairing code
- paired user IDs
- allowed user IDs from the dashboard allowlist

Environment-based setup is also supported. The main env var is:

```text
DISCORD_BOT_TOKEN
```

Nakama also supports:

```text
DISCORD_ALLOWED_USER_IDS
nakama_DISCORD_PROFILE_ID
```

Override the config root with `NAKAMA_CONFIG_DIR` when needed.

## Troubleshooting

### Bridge worker logs `Used disallowed intents`

The Discord bridge cannot start because **Message Content Intent** is off for this bot.

**Fix:**

1. [Discord Developer Portal](https://discord.com/developers/applications) → your app → **Bot**
2. Under **Privileged Gateway Intents**, turn **Message Content Intent** **on**
3. Save, then restart the Discord bridge worker in **Integrations → Discord**

If the bot was already in your server before you enabled the intent, generate a fresh invite (Step 1b) and add the bot again.

This is not something Nakama can enable for you — Discord only exposes this as a portal toggle, not an API setting.

### The bot does not answer at all

Check these first:

1. The bot token is saved correctly
2. The Discord bridge worker is running (start it from **Integrations → Discord**; use `bun run dev:discord` only in development)
3. The Nakama server is running
4. The Discord user is paired or allowlisted

### Private chat works but server channels do not

Usually one of these is true:

- **Message Content Intent** is off — turn the toggle on under **Bot → Privileged Gateway Intents** (see Step 1a)
- the bot was invited before Message Content Intent was enabled — re-invite with a fresh URL (Step 1b)
- the message was not a slash command, reply, bot `@mention`, or `@mention` of a role the bot holds
- the user has not completed DM pairing yet

### Mentions do not work in servers

1. Turn **Message Content Intent** on (Step 1a), then re-invite the bot (Step 1b)
2. Make sure only one Discord bridge worker is running
3. `@mention` the bot user (or a role assigned to the bot) or reply to one of its messages

If Discord autocomplete offers both a **role** and the **bot user** with similar names, either works when the bot holds that role. Mentioning an unrelated role does not trigger a reply.

### Discord says to link in a private DM

This usually means:

- the user never sent the pairing code
- the pairing code expired or was replaced
- the user tried to pair in a server channel instead of a DM

Generate a new pairing code from **Integrations → Discord** and send it to the bot in a private DM.

## Next steps

- [Quickstart](/quickstart)
- [Profiles](/profiles)
- [Telegram](/telegram)
- [WhatsApp](/whatsapp)
