docspluginstransportsslack

slack

A Slack app over Socket Mode — direct messages reach an agent through a bot you create at api.slack.com and connect to the server.

Getting the tokens

Cast connects as a Slack app via Socket Mode. You need two tokens, both minted at api.slack.com/apps: a workspace bot token (xoxb-…) and an app-level token (xapp-…). There are two ways to set the app up — paste a manifest in one shot, or click through each setting by hand. The manifest is faster when Slack offers it, but the modal that exposes it isn't always shown; if you only see "Create New App" with a name field, use the manual path.

At api.slack.com/apps?new_app=1, in the Create New App modal, choose From a manifest, select your workspace, and paste:

slack app manifest
display_information:
  name: Cast
  description: Personal AI assistant
features:
  bot_user:
    display_name: Cast
    always_online: true
  app_home:
    home_tab_enabled: false
    messages_tab_enabled: true
    messages_tab_read_only_enabled: false
oauth_config:
  scopes:
    bot:
      - chat:write
      - im:history
      - im:read
      - im:write
      - users:read
      - files:read
      - files:write
settings:
  event_subscriptions:
    bot_events:
      - message.im
  interactivity:
    is_enabled: true
  socket_mode_enabled: true
  token_rotation_enabled: false
⚠ HEADS UP
The messages_tab_read_only_enabled: false line is critical — without it the bot's DM input is disabled ("Sending messages to this app has been turned off").

After creating the app, install it to your workspace and copy the xoxb-… bot token from OAuth & Permissions, plus the xapp-… app-level token from Basic Information → App-Level Tokens.

Route configuration

Each entry binds one Slack app to one agent. To run multiple agents from one workspace, create one app per agent and add one entry each.

routes.json

json · slack slice
{
  "slack": [
    {
      "address": "assistant",
      "botToken": "xoxb-...",
      "appToken": "xapp-...",
      "allowedUserIds": ["U012ABCDEF"]
    }
  ]
}
FieldTypeDefaultEffect
botTokenstringrequiredBot User OAuth token, must start with xoxb-.
appTokenstringrequiredApp-level token with connections:write, must start with xapp-. Powers the Socket Mode connection.
addressstringrequiredCanonical agent address this app routes to.
channelstringChannel preset for conversations. Falls back to the agent's default.
allowedTeamIdsstring[]Workspace allowlist. Empty or omitted means no filter — the gateway ACL is the gate.
allowedUserIdsstring[]Per-user allowlist. Empty or omitted means no filter.
botUserIdstringOverride for the bot's own user ID (self-message filtering). Discovered via auth.test() at connect when omitted.
streamingbooleantrueLive edit-in-place streaming. Set false to deliver one sealed message per response.

What works in chat

  • Live streaming — the bot posts a message and edits it in place as the agent writes, then seals it when the turn finishes.
  • Approvals — sensitive actions appear as Block Kit buttons; approve or reject and the message updates with the decision.
  • Attachments — work in both directions. The files:read scope is required, or inbound images fail silently.
  • DM-only — Cast subscribes solely to message.im and ignores @mentions in channels and shared spaces.
  • No typing indicator — Slack DMs expose no typing API. Lifecycle notices (waking, working) still render as messages when you're recently active.

Notes & gotchas

⚠ HEADS UP
Keep token rotation off — Cast does not implement Slack's refresh-token dance. If you see a "Refresh Token" alongside the bot token, rotation is on; toggle it off (OAuth & Permissions → Token Rotation) and reinstall.

Why Socket Mode

Socket Mode lets the app receive events over an outbound WebSocket that Cast opens itself, so the server runs anywhere with internet access — a laptop, a box behind a firewall. The trade-off is the second (xapp-) token and the step ordering above. Credentials live in routes.json with no separate secrets file; see Transports for the shared config model.