Nakama

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
  • @mention the 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.

  1. Open Agent → your agent → Channels → Slack for the agent that should answer in Slack (you need to be an org admin)
  2. Click Copy manifest
  3. Open Slack apps, choose From a manifest, pick your workspace, and paste the manifest
  4. 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:

ScopeWhy Nakama needs it
chat:writePost replies
im:historyRead DMs sent to the app
channels:historyRead public channel messages that mention the app, and its threads
groups:historyThe same for private channels the app is invited to
reactions:writeShow the 👀 working reaction
users:readTell full members apart from guests for Everyone in the workspace

Step 2: Copy the two tokens

Slack Socket Mode needs two different tokens:

TokenWhere in the Slack app settingsStarts with
Bot tokenInstall App → Install to Workspace, then copy Bot User OAuth Tokenxoxb-
App tokenBasic Information → App-Level Tokens → Generate Token and Scopes, add the connections:write scopexapp-

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:

  1. Paste the bot token and the app token
  2. 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:slack

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

  1. 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.
  2. 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.
  3. 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:

  1. In Slack, open the member's profile, click ⋯, and choose Copy member ID
  2. 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.
  3. 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:

  • @mention the 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.

CommandWhat it does
!helpShow command help
!newStart a new conversation
!clearClear this conversation's history
!stopStop the reply that is in progress
!statusShow 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:

  1. The worker is running on Agent → your agent → Channels → Slack
  2. The Nakama server is running
  3. The Slack member is paired or listed under Allowed users
  4. 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 @mention the app, and it was not in a thread the app already answered.
  • The member has not paired or been allowed yet.

Next steps

On this page