Pairing
Pairing — Slack DMs default to pairing mode.
Status: production-ready for DMs + channels via Slack app integrations. Default mode is Socket Mode; HTTP Events API mode is also supported.
Pairing
Pairing — Slack DMs default to pairing mode.
Slash commands
Slash commands — Native command behavior and command catalog.
Channel troubleshooting
Channel troubleshooting — Cross-channel diagnostics and repair playbooks.
Create Slack app and tokens
In Slack app settings:
xapp-...) with connections:writexoxb-...)Configure RemoteClaw
{ channels: { slack: { enabled: true, mode: "socket", appToken: "xapp-...", botToken: "xoxb-...", }, },}Env fallback (default account only):
SLACK_APP_TOKEN=xapp-...SLACK_BOT_TOKEN=xoxb-...Subscribe app events
Subscribe bot events for:
app_mentionmessage.channels, message.groups, message.im, message.mpimreaction_added, reaction_removedmember_joined_channel, member_left_channelchannel_renamepin_added, pin_removedAlso enable App Home Messages Tab for DMs.
Start gateway
remoteclaw gatewayConfigure Slack app for HTTP
channels.slack.mode="http")/slack/events)Configure RemoteClaw HTTP mode
{ channels: { slack: { enabled: true, mode: "http", botToken: "xoxb-...", signingSecret: "your-signing-secret", webhookPath: "/slack/events", }, },}Use unique webhook paths for multi-account HTTP
Per-account HTTP mode is supported.
Give each account a distinct webhookPath so registrations do not collide.
botToken + appToken are required for Socket Mode.botToken + signingSecret.SLACK_BOT_TOKEN / SLACK_APP_TOKEN env fallback applies only to the default account.userToken (xoxp-...) is config-only (no env fallback) and defaults to read-only behavior (userTokenReadOnly: true).chat:write.customize if you want outgoing messages to use the active agent identity (custom username and icon). icon_emoji uses :emoji_name: syntax.For actions/directory reads, user token can be preferred when configured. For writes, bot token remains preferred; user-token writes are only allowed when userTokenReadOnly: false and bot token is unavailable.
channels.slack.dmPolicy controls DM access (legacy: channels.slack.dm.policy):
pairing (default)allowlistopen (requires channels.slack.allowFrom to include "*"; legacy: channels.slack.dm.allowFrom)disabledDM flags:
dm.enabled (default true)channels.slack.allowFrom (preferred)dm.allowFrom (legacy)dm.groupEnabled (group DMs default false)dm.groupChannels (optional MPIM allowlist)Pairing in DMs uses remoteclaw pairing approve slack <code>.
channels.slack.groupPolicy controls channel handling:
openallowlistdisabledChannel allowlist lives under channels.slack.channels.
Runtime note: if channels.slack is completely missing (env-only setup), runtime falls back to groupPolicy="allowlist" and logs a warning (even if channels.defaults.groupPolicy is set).
Name/ID resolution:
channels.slack.dangerouslyAllowNameMatching: trueChannel messages are mention-gated by default.
Mention sources:
<@botId>)agents.list[].groupChat.mentionPatterns, fallback messages.groupChat.mentionPatterns)Per-channel controls (channels.slack.channels.<id|name>):
requireMentionusers (allowlist)allowBotsskillssystemPrompttools, toolsBySendertoolsBySender key format: id:, e164:, username:, name:, or "*" wildcard
(legacy unprefixed keys still map to id: only)commands.native: "auto" does not enable Slack native commands).channels.slack.commands.native: true (or global commands.native: true)./<command> names).channels.slack.slashCommand.Default slash command settings:
enabled: falsename: "remoteclaw"sessionPrefix: "slack:slash"ephemeral: trueSlash sessions use isolated keys:
agent:<agentId>:slack:slash:<userId>and still route command execution against the target conversation session (CommandTargetSessionKey).
direct; channels as channel; MPIMs as group.session.dmScope=main, Slack DMs collapse to agent main session.agent:<agentId>:slack:channel:<channelId>.:thread:<threadTs>) when applicable.channels.slack.thread.historyScope default is thread; thread.inheritParent default is false.channels.slack.thread.initialHistoryLimit controls how many existing thread messages are fetched when a new thread session starts (default 20; set 0 to disable).Reply threading controls:
channels.slack.replyToMode: off|first|all (default off)channels.slack.replyToModeByChatType: per direct|group|channelchannels.slack.dm.replyToModeManual reply tags are supported:
[[reply_to_current]][[reply_to:<id>]]Note: replyToMode="off" disables all reply threading in Slack, including explicit [[reply_to_*]] tags. This differs from Telegram, where explicit tags are still honored in "off" mode. The difference reflects the platform threading models: Slack threads hide messages from the channel, while Telegram replies remain visible in the main chat flow.
Slack file attachments are downloaded from Slack-hosted private URLs (token-authenticated request flow) and written to the media store when fetch succeeds and size limits permit.
Runtime inbound size cap defaults to 20MB unless overridden by channels.slack.mediaMaxMb.
channels.slack.textChunkLimit (default 4000)channels.slack.chunkMode="newline" enables paragraph-first splittingthread_ts)channels.slack.mediaMaxMb when configured; otherwise channel sends use MIME-kind defaults from media pipelinePreferred explicit targets:
user:<id> for DMschannel:<id> for channelsSlack DMs are opened via Slack conversation APIs when sending to user targets.
Slack actions are controlled by channels.slack.actions.*.
Available action groups in current Slack tooling:
| Group | Default |
|---|---|
| messages | enabled |
| reactions | enabled |
| pins | enabled |
| memberInfo | enabled |
| emojiList | enabled |
assistant.threads.setStatus and require bot scope assistant:write.channel_id_changed can migrate channel config keys when configWrites is enabled.Slack interaction: ... system events with rich payload fields:
workflow_* metadataview_submission and view_closed events with routed channel metadata and form inputsackReaction sends an acknowledgement emoji while RemoteClaw is processing an inbound message.
Resolution order:
channels.slack.accounts.<accountId>.ackReactionchannels.slack.ackReactionmessages.ackReactionagents.list[].identity.emoji, else ”👀”)Notes:
"eyes")."" to disable the reaction for a channel or account.{ "display_information": { "name": "RemoteClaw", "description": "Slack connector for RemoteClaw" }, "features": { "bot_user": { "display_name": "RemoteClaw", "always_online": false }, "app_home": { "messages_tab_enabled": true, "messages_tab_read_only_enabled": false }, "slash_commands": [ { "command": "/remoteclaw", "description": "Send a message to RemoteClaw", "should_escape": false } ] }, "oauth_config": { "scopes": { "bot": [ "chat:write", "channels:history", "channels:read", "groups:history", "im:history", "mpim:history", "users:read", "app_mentions:read", "assistant:write", "reactions:read", "reactions:write", "pins:read", "pins:write", "emoji:read", "commands", "files:read", "files:write" ] } }, "settings": { "socket_mode_enabled": true, "event_subscriptions": { "bot_events": [ "app_mention", "message.channels", "message.groups", "message.im", "message.mpim", "reaction_added", "reaction_removed", "member_joined_channel", "member_left_channel", "channel_rename", "pin_added", "pin_removed" ] } }}If you configure channels.slack.userToken, typical read scopes are:
channels:history, groups:history, im:history, mpim:historychannels:read, groups:read, im:read, mpim:readusers:readreactions:readpins:reademoji:readsearch:read (if you depend on Slack search reads)Check, in order:
groupPolicychannels.slack.channels)requireMentionusers allowlistUseful commands:
remoteclaw channels status --proberemoteclaw logs --followremoteclaw doctorCheck:
channels.slack.dm.enabledchannels.slack.dmPolicy (or legacy channels.slack.dm.policy)remoteclaw pairing list slackValidate bot + app tokens and Socket Mode enablement in Slack app settings.
Validate:
webhookPath per HTTP accountVerify whether you intended:
channels.slack.commands.native: true) with matching slash commands registered in Slackchannels.slack.slashCommand.enabled: true)Also check commands.useAccessGroups and channel/user allowlists.
RemoteClaw supports Slack native text streaming via the Agents and AI Apps API.
channels.slack.streaming controls live preview behavior:
off: disable live preview streaming.partial (default): replace preview text with the latest partial output.block: append chunked preview updates.progress: show progress status text while generating, then send final text.channels.slack.nativeStreaming controls Slack’s native streaming API (chat.startStream / chat.appendStream / chat.stopStream) when streaming is partial (default: true).
Disable native Slack streaming (keep draft preview behavior):
channels: slack: streaming: partial nativeStreaming: falseLegacy keys:
channels.slack.streamMode (replace | status_final | append) is auto-migrated to channels.slack.streaming.channels.slack.streaming is auto-migrated to channels.slack.nativeStreaming.assistant:write scope.replyToMode.chat.startStream).chat.appendStream).chat.stopStream).Primary reference:
Configuration reference - Slack
High-signal Slack fields:
mode, botToken, appToken, signingSecret, webhookPath, accounts.*dm.enabled, dmPolicy, allowFrom (legacy: dm.policy, dm.allowFrom), dm.groupEnabled, dm.groupChannelsdangerouslyAllowNameMatching (break-glass; keep off unless needed)groupPolicy, channels.*, channels.*.users, channels.*.requireMentionreplyToMode, replyToModeByChatType, thread.*, historyLimit, dmHistoryLimit, dms.*.historyLimittextChunkLimit, chunkMode, mediaMaxMb, streaming, nativeStreamingconfigWrites, commands.native, slashCommand.*, actions.*, userToken, userTokenReadOnly