# SlackProvider `SlackProvider` is the managed path for connecting agents to Slack. Register it on `Mastra.channels` and it provisions Slack apps via the Manifest API, runs the OAuth install flow, rotates configuration tokens, and routes Slack events to your agents. Use it when you want Mastra to own app creation and installation. For the lower-level path where you create the Slack app and configure scopes and webhooks yourself, use [`createSlackAdapter`](https://mastra.ai/docs/agents/channels) on the agent's `channels.adapters` instead. ## Usage example Register the provider on the `Mastra` constructor. The refresh token is single-use and rotates on startup; the resulting access tokens are persisted to `Mastra.storage`. ```typescript import { Mastra } from '@mastra/core/mastra' import { SlackProvider } from '@mastra/slack' export const mastra = new Mastra({ storage, channels: { slack: new SlackProvider({ refreshToken: process.env.SLACK_APP_CONFIG_REFRESH_TOKEN, baseUrl: process.env.MASTRA_BASE_URL, }), }, }) ``` When credentials aren't available at construction time (for example, entered through the Editor UI or loaded from a vault), construct the provider without them and call [`configure()`](#configurecredentials) later: ```typescript const slack = new SlackProvider() await slack.configure({ refreshToken: process.env.SLACK_APP_CONFIG_REFRESH_TOKEN, }) ``` ## Constructor parameters `SlackProviderConfig` combines Slack-specific fields, Slack-adapter overrides (`toolDisplay`, `streaming`, `typingStatus`), and a curated subset of [`ChannelConfig`](https://mastra.ai/reference/agents/channels) options (such as `handlers`, `inlineMedia`, and `state`) forwarded to every connected agent. All fields are optional. **refreshToken** (`string`): Slack App Configuration refresh token, used for automatic token rotation. Single-use; each rotation returns a new pair. Can also be provided later via \`configure()\`. If omitted, the provider starts unconfigured and cannot create apps until \`configure()\` is called or tokens are loaded from storage. Generate it under "Your App Configuration Tokens" at api.slack.com/apps. **token** (`string`): Slack App Configuration access token for programmatic app creation. Optional, because the provider rotates to a fresh token on startup using \`refreshToken\`. **baseUrl** (`string`): Public base URL for webhook and OAuth callbacks. Required when calling \`connect()\` to create apps. Can also be set via \`setBaseUrl()\` or auto-detected from the Mastra server config. For local development, use a tunnel such as \`cloudflared\`. **encryptionKey** (`string`): Encryption key for sensitive stored data (client secret, signing secret, bot token). Use a 32+ character random string. Can be set via the \`MASTRA\_ENCRYPTION\_KEY\` env var. If omitted, secrets are stored in plaintext (not recommended for production). **storage** (`ChannelsStorage`): Custom storage for installations. Defaults to Mastra's \`ChannelsStorage\` from the global storage. Throws if no persistent storage is available. **redirectPath** (`string`): Path to redirect to after OAuth completion. (Default: `"/"`) **onInstall** (`(installation: SlackInstallation) => Promise`): Called when a workspace successfully installs the app. **streaming** (`StreamingConfig | false`): Stream agent text deltas to Slack as they're generated. Pass \`{ updateIntervalMs }\` to customize the post-and-edit interval, or \`false\` to buffer text until step-finish. Disabling streaming restricts \`toolDisplay\` to static modes. (Default: `true`) **toolDisplay** (`ToolDisplay`): How tool calls are rendered in Slack: \`'cards'\`, \`'text'\`, \`'timeline'\`, \`'grouped'\`, \`'hidden'\`, or a function. \`'hidden'\` suppresses tool call/result rendering entirely. \`'timeline'\` and \`'grouped'\` require streaming. With \`streaming: false\`, only static modes are available and the default is \`'cards'\`. (Default: `'grouped'`) **typingStatus** (`boolean | TypingStatusFn`): Show a typing indicator while the agent works. Set \`false\` to disable, or pass a function to return custom status text per stream chunk (return \`undefined\` to fall back to the default for that chunk). (Default: `true`) **waitUntil** (`WaitUntilFn`): Returns a \`waitUntil\` for the current Slack webhook request. Required on serverless runtimes where Hono can't bridge the platform's \`ExecutionContext\` (Vercel, AWS Lambda). Without it, the invocation freezes after the 200 ack and kills the run mid-flight. Pass the bare \`waitUntil(promise)\` from your platform SDK (for example, \`@vercel/functions\`). Cloudflare Workers and Netlify users typically don't need this. **resolveWaitUntil** (`WaitUntilResolver`): Resolve \`waitUntil\` from the request's Hono \`Context\` when the runtime exposes it through the request and core's default doesn't cover it. Resolution order: \`waitUntil\` → \`resolveWaitUntil\` → core default. **handlers** (`ChannelHandlers`): Override built-in event handlers (\`onDirectMessage\`, \`onMention\`). Forwarded to \`AgentChannels\` for every agent connected via this provider. **inlineMedia** (`ChannelConfig['inlineMedia']`): Which media types to send inline to the model. **inlineLinks** (`ChannelConfig['inlineLinks']`): Promote URLs in message text to file parts. **threadContext** (`ChannelConfig['threadContext']`): Fetch recent thread messages from Slack when the agent joins mid-conversation. **tools** (`ChannelConfig['tools']`): Whether to include channel tools (\`add\_reaction\`, \`remove\_reaction\`). **state** (`ChannelConfig['state']`): State adapter for message deduplication, locking, and subscriptions. Defaults to the \`MastraStateAdapter\` backed by the Mastra instance's configured storage, so subscriptions persist across restarts. **chatOptions** (`ChannelConfig['chatOptions']`): Additional options passed directly to the Chat SDK. **logger** (`SlackAdapterConfig['logger']`): Logger forwarded to the underlying \`SlackAdapter\`. Defaults to the adapter's \`ConsoleLogger\`. ## Methods ### Agent connections #### `connect(agentId, options?)` Creates a new Slack app for the agent via the Manifest API and returns an OAuth result with the authorization URL to redirect the user to. Requires `baseUrl` to be set. If a pending installation already exists for the agent, returns its existing authorization URL instead of creating a duplicate app. ```typescript const result = await slack.connect('support-agent', { name: 'Support Bot', }) // Redirect the user to result.authorizationUrl to install the app ``` Returns: `Promise` ```typescript interface ChannelConnectResult { type: 'oauth' installationId: string authorizationUrl: string } ``` `SlackConnectOptions` is serializable and can be stored for stored agents: **name** (`string`): Display name for the Slack bot. Defaults to the agent name, then the agent ID. **description** (`string`): Bot description shown in Slack. Defaults to "{name} - Powered by Mastra". **iconUrl** (`string`): URL to a square image (min 512x512) for the app icon. Downloaded and uploaded to Slack automatically. **manifest** (`(defaults: SlackAppManifest) => SlackAppManifest`): Customize the Slack app manifest before it is sent to the Manifest API. Receives the default manifest and returns the final one. Use it for custom scopes, additional events, or interactivity settings. **redirectUrl** (`string`): URL to redirect to after successful OAuth completion. Defaults to the provider's \`redirectPath\` or \`/\`. #### `disconnect(agentId)` Disconnects an agent from Slack by deleting its app and removing the installation from storage. ```typescript await slack.disconnect('support-agent') ``` Returns: `Promise` #### `getInstallation(agentId)` Returns the Slack installation for an agent, or `null` if none exists. ```typescript const installation = await slack.getInstallation('support-agent') ``` Returns: `Promise` #### `listInstallations()` Lists all Slack installations (public info only), including active and pending. ```typescript const installations = await slack.listInstallations() ``` Returns: `Promise` ### Configuration #### `configure(credentials)` Provides or clears Slack App Configuration credentials at runtime. Use this when credentials aren't available at construction time. Pass `null` to clear credentials and delete stored tokens. ```typescript // Provide credentials (persists to storage immediately) await slack.configure({ refreshToken: 'xoxe-1-...' }) // Clear credentials and stored tokens await slack.configure(null) ``` Returns: `Promise` #### `setBaseUrl(baseUrl)` Sets the public base URL used for webhook and OAuth callbacks. Use this when the URL isn't known at construction time and can't be auto-detected from the server config. ```typescript slack.setBaseUrl('https://abc123.trycloudflare.com') ``` #### `initialize()` Recreates a `SlackAdapter` for each active installation in storage and injects `AgentChannels` into the corresponding agent so it receives Slack events on startup. Does not auto-provision new apps; use `connect()` to create one. Mastra calls this automatically, so you rarely call it directly. ```typescript await slack.initialize() ``` Returns: `Promise` ## Default manifest When `connect()` builds a Slack app, the generated manifest requests a default set of bot scopes and event subscriptions. Override them with the `manifest` option on `connect()`. | Default bot scopes | Default bot events | | ------------------- | ------------------ | | `chat:write` | `app_mention` | | `chat:write.public` | `message.channels` | | `im:write` | `message.groups` | | `channels:history` | `message.im` | | `channels:read` | `message.mpim` | | `groups:history` | | | `groups:read` | | | `im:history` | | | `im:read` | | | `mpim:history` | | | `mpim:read` | | | `app_mentions:read` | | | `users:read` | | | `reactions:write` | | | `files:read` | | | `assistant:write` | | ## Accessing the provider Access the registered provider through the typed `channels` getter, keyed by the id you registered it under: ```typescript const result = await mastra.channels.slack.connect('support-agent') ``` When the key is only known at runtime, look it up by string id and pass the concrete type: ```typescript const slack = mastra.getChannelProvider('slack') const result = await slack.connect('support-agent') ``` ## Storage requirement `SlackProvider` requires persistent storage on `Mastra` to encrypt and persist installations and rotating configuration tokens. The constructor throws if no persistent storage is available and no custom `storage` is passed. ## Related - [ChannelProvider](https://mastra.ai/reference/channels/channel-provider): the interface `SlackProvider` implements - [Channels](https://mastra.ai/docs/agents/channels): concepts, platform setup, and the `createSlackAdapter` path - [Channels reference](https://mastra.ai/reference/agents/channels): the `channels` config on the `Agent` constructor