Slack
Nakama can run as a Slack app so your team can talk to the same agent from a DM or from any channel the app is in.
The mental model is simple:
- Slack is a channel for Nakama, like Telegram or Discord
- A Slack connection belongs to one profile: each profile connects its own Slack app, and that app always answers as that profile
- The bridge talks to the same Nakama server as the web app
- Pairing links a real Slack member to your Nakama access
Why Slack
- Works on a local or private server. The bridge uses Slack Socket Mode: Nakama opens the connection to Slack, so you do not need a public URL, a webhook, or a tunnel.
- No app review. An app you install in your own workspace is ready to use right away. Slack only reviews apps listed in the Slack Marketplace.
- Stays out of the way in channels. The app only answers when someone mentions it, and then keeps the conversation in a thread.
What Slack supports
With Slack enabled, linked members can:
- chat with a Nakama profile in a DM with the app
@mentionthe app in a channel, which opens a thread the app keeps following- keep every conversation attached to the connection's profile
- stop, clear, or restart conversations
While the agent is working, Nakama adds an 👀 reaction to your message and removes it when the reply is posted.
Slack replies are text only for now. Images, files, and saved artifacts are not sent to or from Slack yet.
Step 1: Create the Slack app
Nakama gives you an app manifest so you do not have to set scopes and events by hand.
- Open Agent → your agent → Channels → Slack for the agent that should answer in Slack (you need to be an org admin)
- Click Copy manifest
- Open Slack apps, choose From a manifest, pick your workspace, and paste the manifest
- Review the summary and click Create
The channel settings route is /profiles/:profileId/channels/slack.
The manifest turns on Socket Mode, the app's Messages tab, and these bot scopes:
| Scope | Why Nakama needs it |
|---|---|
chat:write | Post replies |
im:history | Read DMs sent to the app |
channels:history | Read public channel messages that mention the app, and its threads |
groups:history | The same for private channels the app is invited to |
reactions:write | Show the 👀 working reaction |
users:read | Tell full members apart from guests for Everyone in the workspace |
Step 2: Copy the two tokens
Slack Socket Mode needs two different tokens:
| Token | Where in the Slack app settings | Starts with |
|---|---|---|
| Bot token | Install App → Install to Workspace, then copy Bot User OAuth Token | xoxb- |
| App token | Basic Information → App-Level Tokens → Generate Token and Scopes, add the connections:write scope | xapp- |
If your workspace requires admin approval for new apps, the install step sends a request to a workspace admin first.
Step 3: Save in Nakama
On Agent → your agent → Channels → Slack:
- Paste the bot token and the app token
- Click Save
Nakama validates the bot token with Slack's auth.test API and validates the app token by opening a Socket Mode connection. The app-token check verifies the xapp- token type and connections:write access. Nakama also compares the app ID in the app token with the bot's app when Slack can answer bots.info; that same-app check is skipped when the bot lacks the users:read scope. The save error identifies an invalid token, missing Socket Mode scope, or a mismatched app when Slack provides enough information to detect it.
After the first save, Nakama generates a pairing code on the same page.
These settings belong to this profile. Another profile sees Slack as not connected until it connects a Slack app of its own. One Slack app cannot serve two connections, because Slack would split its messages between them, so Nakama refuses to save an app another profile already uses.
Step 4: Start the Slack bridge
Use the worker controls on Agent → your agent → Channels → Slack to start the worker. The agent's Channels list shows Slack as Connected once the bridge is running and at least one member can chat.
For local development only, you can instead run bun run dev:slack from the repo root. A direct run must include the organization and profile scope so it reads the correct profile-scoped config:
NAKAMA_CHANNEL_ORG_ID="org_your_org" \
NAKAMA_CHANNEL_PROFILE_ID="your-profile" \
bun run dev:slackSave the Slack connection in the same Nakama config directory first. Set NAKAMA_SERVER_URL and NAKAMA_CONFIG_DIR as needed for a separate server or non-default config root.
If you change a token later, restart the profile's Slack bridge worker so it picks up the new one.
Step 5: Pair your Slack account
Pairing links your Slack member to Nakama so people who are not linked cannot use the app.
- Open Nakama in Slack. In the Slack sidebar, open Nakama under Apps. If it is not listed, search for Nakama at the top of Slack and open the app.
- Send the code in the DM. Go to its Messages tab and send the pairing code from the profile's Slack settings as a normal message. Only this DM works: a code posted in a channel, or sent with an
@mention, is not accepted. - Wait for the reply. Nakama answers "Linked successfully" and the member shows up under Allowed users.
A code works once. Click New code for the next person; the card updates by itself when someone links.
Optional: Let everyone in the workspace chat
Pairing members one by one does not scale to a whole team. Turn on Everyone in the workspace on Agent → your agent → Channels → Slack and click Save: every full member of your Slack workspace can then use the app with no pairing.
What members do: nothing to set up. They open Nakama under Apps and send a message, or @mention Nakama in a channel the app was added to.
These people are still left out and need pairing or Allowed users:
- guests (single-channel and multi-channel)
- people from other organizations in shared (Slack Connect) channels
- other bots and deactivated accounts
If Slack cannot confirm who someone is, Nakama treats them as not allowed.
This option needs the users:read scope. The manifest from Nakama includes it. If your app was created before, add users:read under OAuth & Permissions → Bot Token Scopes and reinstall the app first; Nakama refuses to save the toggle until the scope is there.
Everyone who can chat reaches this profile and its tools like a paired member does, so check what the profile can do before opening it to the whole workspace.
Optional: Allow members directly
Instead of pairing, you can allow Slack members up front:
- In Slack, open the member's profile, click ⋯, and choose Copy member ID
- On Agent → your agent → Channels → Slack, paste the ID into Allowed users and press Enter. It turns into a badge; paste several IDs at once and each becomes its own badge. Click × on a badge to remove it.
- Click Save
Member IDs start with U or W, for example U01ABCDEF. Display names do not work here.
Allowed users is the full access list, including members who paired. To revoke someone, remove their ID and click Save.
DM behavior
Once a member is paired or allowed:
- every message in the DM goes to the Nakama profile
- the DM keeps its own Nakama conversation until you send
!new
If a member who is not linked messages the app, Nakama asks for the pairing code instead of passing the message to the profile.
Channel behavior
Invite the app to a channel first (for example, type /invite @Nakama in that channel). Then:
@mentionthe app to start a conversation. Nakama replies in a thread under your message.- Keep chatting in that thread without mentioning the app again. Each thread is its own conversation.
- Messages in the channel that do not mention the app are ignored.
- Only linked members can start or continue a conversation. Messages from other members are ignored.
Replies in channels are visible to everyone in the channel, and Nakama tells the profile so.
Commands
Slack treats any message that starts with / as a Slack command, so Nakama commands start with !. They work in DMs and in threads.
| Command | What it does |
|---|---|
!help | Show command help |
!new | Start a new conversation |
!clear | Clear this conversation's history |
!stop | Stop the reply that is in progress |
!status | Show server, profile, and model status |
The connection always answers as its profile, in that profile's organization. To reach another profile from Slack, that profile connects its own Slack app.
Reply formatting
Profiles write normal Markdown. Nakama sends it as a Slack Markdown block, so bold, italics, links, lists, and code blocks show up as intended. Long replies are split into several messages.
Configuration notes
Nakama stores each profile's Slack settings under its local config directory (default ~/.nakama/orgs/<org-id>/channels/<profile-id>/slack/):
- bot token and app token
- pairing code
- paired and allowed member IDs, and the Everyone in the workspace switch
Override the config root with NAKAMA_CONFIG_DIR when needed.
Disconnect and token rotation
Stop keeps the Slack configuration. Disconnect removes the credentials, pairings, and channel directory's session/thread data. Each profile uses its own Slack app and connection; one app cannot be shared by two profiles.
Long-lived Slack workers keep the tokens they loaded at startup. After rotating either the bot token or app token, save the new values and restart the profile's Slack worker.
Troubleshooting
Save says the channel account is already in use by another profile
Each profile needs its own Slack app. Create a new app from the manifest for this profile and save its tokens here.
Save says the tokens come from different Slack apps
The bot token and the app token were copied from two different apps. Copy both from the same app's settings page. Nakama detects this through the app ID when Slack's bots.info check is available; a missing users:read scope can prevent that comparison.
Save fails with invalid_auth
The token was copied wrong or has been revoked. Copy it again from the Slack app settings (Step 2). The bot token must start with xoxb- and the app token with xapp-.
Save fails with not_allowed_token_type on the app token
The app token is missing the connections:write scope, or Socket Mode is off. Generate a new app-level token with that scope and check Socket Mode in the app settings.
The app does not answer at all
Check these first:
- The worker is running on Agent → your agent → Channels → Slack
- The Nakama server is running
- The Slack member is paired or listed under Allowed users
- Only one Slack bridge worker runs for this app
Saving Everyone in the workspace asks for users:read
The Slack app does not have the users:read scope yet. Open the app settings, add it under OAuth & Permissions → Bot Token Scopes, click Reinstall to Workspace, then save again in Nakama.
I sent the pairing code in a channel and nothing linked
Pairing codes only work in a DM with the app, so a code posted in a channel is never used up by someone else. Open the Nakama app under Apps in the Slack sidebar, go to its Messages tab, and send the code there.
I cannot message the app in Slack
The app's Messages tab is turned off. In the Slack app settings, open App Home and turn on Messages Tab and Allow users to send Slash commands and messages from the messages tab. The manifest from Nakama sets both.
DMs work but channels do not
- The app is not in the channel yet. Invite it with
/invite @Nakama. - The message did not
@mentionthe app, and it was not in a thread the app already answered. - The member has not paired or been allowed yet.