Nakama

Discord

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, create an application, then configure it on two separate pages:

ValuePortal locationFor Nakama?
Bot tokenBotYes — paste in Integrations → Discord
Message Content IntentBot → Privileged Gateway IntentsYes — turn the toggle on
OAuth2 permissionsOAuth2 → URL GeneratorYes — invite the bot to your server
Application ID, Public KeyGeneral InformationNo

1a. Bot tab — token and intent

  1. Open Bot (not General Information) → Add Bot if needed → Reset TokenCopy
  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.

CommandTypeWhat it does
/startSlashWelcome and pairing help
/helpSlashShow command help
/stopSlashStop the current in-progress reply
/clearSlashClear chat history
/compactSlashCompact conversation history
/newSlashStart a new conversation (same Discord thread)
/closeSlashClose (archive) this bot conversation thread
/statusSlashShow server and model status
/orgTextChoose or switch organization
/profileTextChoose 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.

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:

DISCORD_BOT_TOKEN

Nakama also supports:

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 → 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.

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

On this page