Slack Integration
Set up Slack to create tasks and communicate with agents
Enable Slack for task creation, agent communication, and interactive workflows via direct messages and the Slack Assistant sidebar.
Setup
- Create a Slack App
- Enable Socket Mode (for real-time events without public webhooks)
- Enable Interactivity (for action buttons and modals)
- Enable Assistant View (for sidebar conversations)
- Add required bot token scopes:
app_mentions:readassistant:writechannels:history,channels:readchat:write,chat:write.customize,chat:write.publiccommandsfiles:read,files:writegroups:history,groups:readim:history,im:read,im:writempim:history,mpim:read,mpim:writereactions:writeusers:read
- Subscribe to bot events:
app_mention,assistant_thread_started,assistant_thread_context_changed,message.channels,message.groups,message.im,message.mpim - Install to your workspace and copy tokens
A ready-to-use slack-manifest.json is included in the repository root — import it directly in the Slack App configuration page to set up all scopes, events, and features automatically.
Configuration
# Required for Slack
SLACK_BOT_TOKEN=xoxb-... # Bot User OAuth Token
SLACK_APP_TOKEN=xapp-... # App-Level Token (Socket Mode)
SLACK_SIGNING_SECRET=... # Signing Secret (optional for Socket Mode)
# Disable Slack (if not using)
SLACK_DISABLE=trueHow It Works
Creating Tasks
@mention the bot in Slack to create tasks. All Slack messages are routed directly as tasks — there is no separate inbox system.
Routing priority:
swarm#<uuid>— explicit agent targeting (always wins)swarm#all— broadcast to all workers- Thread follow-up — if in a thread where a worker is already active, routes directly to that worker
- Lead fallback — if the bot was @mentioned and no other match, routes to the lead agent
If no agents are online, the message is queued as an unassigned task in the pool. The bot confirms that your request has been queued and will be processed when agents come back up.
Thread Follow-up Routing
When you @mention the bot in a thread where a worker is already handling a task, the message routes directly to that worker — no lead delegation needed. This keeps conversations flowing naturally.
If the assigned worker is offline or unavailable, the follow-up routes to the lead agent instead of dropping the message. The lead picks up the thread context and continues the conversation, preserving parentTaskId continuity for chained tasks.
By default, thread follow-ups route automatically without requiring an @mention. Set SLACK_THREAD_FOLLOWUP_REQUIRE_MENTION=true to require an explicit @mention for thread follow-up routing — non-mention thread messages will be silently dropped instead of auto-routing.
Follow-up re-delegation guard: When the lead receives a task.worker.completed or task.worker.failed follow-up, it is explicitly instructed (via prompt template) not to re-delegate the same work back to a worker. A second guard in send-task blocks any re-delegation on a Slack thread that already has a completed task within the last 48 hours, preventing the duplicate-response cycle where repeated re-delegations caused the bot to answer the same thread multiple times.
Slack Context Propagation
Slack metadata (slackChannelId, slackThreadTs, slackUserId) is auto-inherited from the creator's current task. When a lead delegates work from a Slack-originated task, workers automatically receive the Slack context and post progress updates to the originating thread — no manual metadata passing needed.
The auto-inheritance works via the X-Source-Task-Id header, which links the new task back to the creator's active task to look up Slack metadata.
For cases where auto-inheritance isn't available (e.g., programmatic task creation without an active parent task), you can pass Slack metadata explicitly on send-task:
slackChannelId— Channel ID for progress updatesslackThreadTs— Thread timestamp for thread-level updatesslackUserId— Original requester's Slack user ID
Explicit params override auto-inherited values when both are present.
Additive Slack Buffer
When enabled via ADDITIVE_SLACK=true, thread replies that do NOT @mention the bot are captured, buffered, and batched into a single follow-up task. This allows multi-message feedback without requiring an @mention each time.
- Messages are buffered for a configurable debounce window (
ADDITIVE_SLACK_BUFFER_MS, default 10s) - Buffered messages are flushed into a single task with dependency chaining to the active task
- Use the
!nowcommand to flush the buffer immediately — skips dependency chaining so the task starts right away - Reactions provide visual feedback: :eyes: for first captured message, :heavy_plus_sign: for subsequent appended messages, :zap: for
!now - When
SLACK_THREAD_FOLLOWUP_REQUIRE_MENTION=true, the additive buffer is disabled for non-mention messages
Tree-Based Status Messages
Tasks that spawn subtasks are rendered as a visual tree in a single evolving Slack message. The tree shows each subtask's status with icons, indentation, and truncated output:
✅ Research phase (3m)
├─ ✅ Analyze codebase — Found 12 relevant files
├─ ✅ Review dependencies — All up to date
└─ 🔄 Write reportStatus icons: ⏳ pending, 🔄 in progress, ✅ completed, ❌ failed, 🚫 cancelled. Trees show up to 8 children per node with an overflow indicator for larger task graphs.
Message Deduplication
When an agent posts its results directly to a Slack thread via the slack-reply tool, the task's completion message automatically switches to a minimal one-liner instead of repeating the full output. This prevents duplicate content in threads — the agent's detailed reply appears once, and the status message simply confirms completion.
Single Evolving Message
Each task gets a single Slack message that evolves through its lifecycle — from assignment to progress to completion. Instead of posting multiple messages, the bot uses chat.update to update one message in place:
- Assignment — When a task is created from Slack, the bot posts a structured Block Kit message with the task link, assigned agent, and status
- Progress — As the agent works, progress updates replace the message content (keeping the same message)
- Completion — The final message shows the task output, status, and action buttons
This keeps threads clean and avoids message spam during long-running tasks.
Rich Block Kit Messages
All Slack responses use structured Block Kit layouts instead of plain text:
- Headers with task status indicators
- Context blocks showing agent name, task ID, and timestamps
- Section blocks for progress and output text
- Action buttons for follow-up and viewing task logs
- Markdown is automatically converted to Slack's
mrkdwnformat
Interactive Actions
Task completion messages include interactive buttons:
- Follow-up — Opens a modal to send a follow-up message to the same agent, creating a new task with dependency on the completed one
- View Full Logs — Links to the task detail page in the dashboard
- Cancel — Shows a confirmation dialog before cancelling an in-progress task
Assistant Sidebar
The bot supports Slack's Assistant sidebar for direct conversations:
- Open the sidebar in any channel or DM to start a conversation
- Suggested prompts help you get started ("Check agent status", "Assign a task", "List recent tasks")
- Follow-up messages in assistant threads route to the same agent that handled the original task
- File uploads (
file_sharemessages) in assistant threads are automatically detected and routed to the lead agent - The assistant sets a typing status while the agent is working (gracefully handles permission errors in non-assistant threads)
Progress Updates
Workers reply in Slack threads with progress updates using the slack-reply MCP tool. This keeps the conversation context in one place.
Reading Messages
Agents can read Slack threads using slack-read:
- By task ID (reads the thread associated with a task)
- By channel ID (leads only, for channel history)
Posting Messages
The lead agent can post new messages to channels using slack-post.
User Filtering
By default, all Slack users can interact with the bot. To restrict access:
# Only users with matching email domains
SLACK_ALLOWED_EMAIL_DOMAINS=company.com,partner.com
# Specific user IDs always allowed (useful for admins)
SLACK_ALLOWED_USER_IDS=U12345678,U87654321If both are set, a user must match either an allowed domain or be in the user ID whitelist.
Attachment Handling
Slack messages with file attachments (voice memos, images, documents) are automatically recognized and processed. When a user sends a file — even without any text — the bot detects it and includes attachment metadata (filename, MIME type, size, Slack file ID) in the task description.
This means agents can:
- Receive voice messages or image uploads as tasks
- Access file metadata to decide whether to download and process attachments
- Use
slack-download-fileto retrieve the actual file content
File Handling
Agents can upload and download files via Slack:
slack-upload-file— Upload a file to a Slack channel or threadslack-download-file— Download a file from Slack by file ID or URL
Files are saved to /workspace/shared/downloads/{agentId}/slack/ by default (each agent writes to its own subdirectory).
Related
- Environment Variables — Slack configuration variables (
SLACK_BOT_TOKEN, etc.) - Task Lifecycle — How Slack messages become tasks
- GitHub App Integration — Another external task source
- Linear Integration — Bidirectional ticket tracking with Linear
- Sentry Integration — Automated error triage from Sentry
- x402 Payments — Enable agents to make crypto micropayments