Slack + Mastra
A pattern for connecting Slack bots to Mastra agents with streaming responses and conversation memory.
This example includes two demo agents (reverse, caps) — each gets its own Slack app and webhook route.
How It Works
Slack message → /slack/{app}/events → Mastra agent → streaming response back to Slack
- One Slack app per agent — each agent has its own bot token and signing secret
- Streaming updates — shows typing indicators while the agent thinks/uses tools
- Thread memory — conversations are scoped to Slack threads via Mastra memory
Setup
1. Install
1pnpm install2. Environment Variables
Create .env:
1OPENAI_API_KEY=sk-your-key
2
3## Each Slack app needs its own credentials
4SLACK_REVERSE_BOT_TOKEN=xoxb-...
5SLACK_REVERSE_SIGNING_SECRET=...
6
7SLACK_CAPS_BOT_TOKEN=xoxb-...
8SLACK_CAPS_SIGNING_SECRET=...3. Create Slack Apps
For each agent you want to expose:
- api.slack.com/apps → Create New App → From scratch
- OAuth & Permissions → Add Bot Token Scopes and Get Token:
app_mentions:read— receive @mentionschannels:history— read messages in public channelschat:write— send messagesim:history— read direct messages- Copy Bot User OAuth Token to .env
- Event Subscriptions → Enable and set Request URL:
https://your-server.com/slack/{agentName}/events
- Subscribe to bot events:
app_mention,message.im - Agents & AI Apps → Toggle on to enable agent features
- Basic Information → copy Signing Secret to .env
4. Run
1## Dev with ngrok for webhooks
2ngrok http 4111
3pnpm devAdding Your Own Agents
1. Create the Agent
1// src/mastra/agents/my-agent.ts
2import { Agent } from '@mastra/core/agent';
3import { Memory } from '@mastra/memory';
4
5export const myAgent = new Agent({
6 name: 'my-agent',
7 instructions: 'Your agent instructions...',
8 model: 'openai/gpt-4o-mini',
9 memory: new Memory({ options: { lastMessages: 20 } }),
10});2. Register with Mastra
1// src/mastra/index.ts
2import { myAgent } from './agents/my-agent';
3
4export const mastra = new Mastra({
5 agents: { myAgent },
6 // ...
7});3. Add Slack Route
1// src/mastra/slack/routes.ts
2const slackApps: SlackAppConfig[] = [
3 {
4 name: 'my-agent', // Route: /slack/my-agent/events
5 botToken: process.env.SLACK_MY_AGENT_BOT_TOKEN!,
6 signingSecret: process.env.SLACK_MY_AGENT_SIGNING_SECRET!,
7 agentName: 'myAgent', // Must match key in mastra.agents
8 },
9];4. Create Slack App & Add Env Vars
Follow the Slack app setup above, then add the credentials to .env.
Project Structure
src/mastra/
├── agents/
│ ├── caps-agent.ts # Simple text transformation agent
│ └── reverse-agent.ts # Agent with tool + workflow capabilities
├── slack/
│ ├── chunks.ts # Handle nested streaming chunk events
│ ├── constants.ts # Animation timing configuration
│ ├── routes.ts # Slack webhook handlers (creates one per app)
│ ├── status.ts # Format status text with spinners
│ ├── streaming.ts # Stream agent responses to Slack
│ ├── types.ts # TypeScript type definitions
│ ├── utils.ts # Helper functions
│ └── verify.ts # Slack request signature verification
├── workflows/
│ └── reverse-workflow.ts # Multi-step text transformation workflow
└── index.ts # Mastra instance with agents and routes
Key Files
routes.ts— Defines webhook endpoints and maps Slack apps to agentsstreaming.ts— Streams responses with animated spinners and tool/workflow indicatorsstatus.ts— Formats status messages (thinking, tool calls, workflow steps)verify.ts— Validates Slack request signatures for security