Knowledge & tools

Slack tool

The Slack tool gives an agent the Slack Web API behind a single action it picks per call — 28 actions for messaging, reactions, reading and managing channels, DMs, users/profiles, files, and workspace info. One credential: a Bot User OAuth token.

It's a tool, not a chat channel. The agent posts and reads on demand — it's the team's robot worker in Slack (post an update, read a channel, look someone up), not a bot you hold a live back-and-forth with. (Two-way "talk to the bot in Slack" would be a separate channel build.)

Connect Slack

  1. Go to api.slack.com/appsCreate New App → From scratch; name it and pick the workspace.
  2. Open OAuth & Permissions → Bot Token Scopes and add the scopes for what you want the bot to do (see checklist below).
  3. Install to Workspace → Allow.
  4. Copy the Bot User OAuth Token (starts with xoxb-) and paste it into the tool's Bot User OAuth Token field.
Use the Bot token (xoxb-), not a user (xoxp-) or app-level (xapp-) token. Adding a scope later requires reinstalling the app.

Scope checklist

Add only what you need; each action the token's scopes don't cover returns a clean missing_scope error naming the scope.

  • Post + reactchat:write, chat:write.public, reactions:write, reactions:read
  • Read channelschannels:read, channels:history, groups:read, groups:history; self-join: channels:join
  • Manage channelschannels:manage, channels:write.topic, channels:write.invites
  • DMsim:write, im:history
  • Usersusers:read, users:read.email, users.profile:read
  • Filesfiles:write, files:read
  • Workspaceteam:read, emoji:read

Capabilities

The agent picks one action per call (28 total), grouped by area:

  • Messagingsend_message (channel + text/blocks, optional thread reply), update_message (channel, ts), delete_message (channel, ts).
  • Reactionsadd_reaction / remove_reaction (channel, timestamp, name), get_reactions (channel, timestamp).
  • Channels (read)list_channels, get_channel, read_history, read_thread (channel, ts), join_channel.
  • Channels (manage)create_channel (name), archive_channel, rename_channel (channel, name), set_channel_topic, set_channel_purpose, invite_to_channel (channel, users).
  • DMsopen_dm (users) → returns a DM channel id to send_message to.
  • Userslist_users, get_user, get_user_profile, lookup_user_by_email (email).
  • Filesupload_file (filename + content|file_url), list_files, get_file_info, delete_file.
  • Workspaceget_team_info, list_emoji.

Field reference

  • channel — a channel ID like C0123ABCD, or a DM channel ID D0123… (from list_channels / open_dm). To message a person, use their user ID or open a DM first.
  • user / users — a user ID like U0123ABCD (from list_users); users is comma-separated (invite / DM).
  • ts — a message's timestamp ID (e.g. 1700000000.123456) — the message to edit/delete, or a thread parent. Returned as ts when you post.
  • name — for reactions, the emoji name without colons (e.g. white_check_mark); for create/rename, the channel name (lowercase, hyphens, no spaces).
  • text / blocks / thread_ts — message text (Slack mrkdwn: *bold*, <url|label>, <@U123>); optional Block Kit layout; reply in a thread by passing the parent's timestamp.
  • Channel managementtopic / purpose (≤250 chars), is_private (create a private channel).
  • Uploadfilename, content (inline text) or file_url (public https to fetch), title, initial_comment.
  • Paginglimit / cursor (next-page cursor from response_metadata.next_cursor), and oldest / latest / inclusive for history windows.

Common recipes

  • Post an alertsend_message to #channel (the bot can post to any public channel without joining).
  • Escalate in a threadsend_message with thread_ts set to the parent message.
  • DM a useropen_dmsend_message to the returned DM channel id.
  • Share a file/reportupload_file with content or file_url and an initial_comment.
  • Read recent messages for contextread_history (the bot must be in the channel).
  • Spin up a project channelcreate_channelinvite_to_channel with the team's user ids.

Permissions & troubleshooting

Post anywhere, read where invited: chat:write.public lets the bot post to any public channel without joining, but reading history and reacting require the bot to be in the channel — it can join_channel first (if channels:join is granted) or be invited with /invite @YourBot. Private channels always need an explicit invite. Channels can be archived, not deleted (Slack has no delete-channel API).

Slack returns HTTP 200 even on failure; the tool detects {"ok":false} and surfaces the Slack error code (in trace/debug panels):

  • not_in_channel → the bot isn't a member; join or invite it.
  • missing_scope (needs scope: …) → add the scope in OAuth & Permissions, then reinstall.
  • channel_not_found / users_not_found / message_not_found → wrong ID; fetch it from list_channels / list_users first.
  • cant_update_message / cant_delete_message → the bot didn't author that message.
  • rate_limited → Slack throttling; retry later.

Classification & lifecycle

This is a read and write tool, and it can delete messages/files and archive channels. If you run it on an autonomous bot, set its safety classification to match. It's post-call-hook eligible (runs outside the LLM turn) — e.g. post a recap or escalate to a channel after a call.