Skip to main content

CopilotKit channels

The same Mastra agent that powers your in-app copilot can also run as a bot in messaging platforms. CopilotKit's Channels SDK connects your agent to Slack and other messaging platforms, with threads, tool calls, rich interactive messages, and human-in-the-loop approvals handled natively in the channel.

info

Full platform setup lives in the CopilotKit Channels documentation. This page shows how Channels fit together with a Mastra agent.

How it fits together
Direct link to How it fits together

Your Mastra agent stays where it's deployed, exposed over AG-UI through registerCopilotKit() (see CopilotKit overview). A channel is a separate long-running process built with @copilotkit/channels: you attach one or more platform adapters and point the channel at your agent. createChannel takes an array of adapters, so a single process can serve several platforms at once.

Install the SDK (batteries-included, every adapter):

npm install @copilotkit/channels
channel.ts
import { createChannel, Message, Section } from '@copilotkit/channels'
import { slack } from '@copilotkit/channels/slack'
import { mastraAgent } from './agent' // your AG-UI Mastra agent

const channel = createChannel({
// Point the channel at your Mastra agent (an AbstractAgent, or a per-thread factory).
agent: mastraAgent,
adapters: [
slack({
botToken: process.env.SLACK_BOT_TOKEN!,
appToken: process.env.SLACK_APP_TOKEN!,
}),
],
})

channel.onMention(async ({ thread }) => {
await thread.runAgent()
})

await channel.start()

The agent receives ordinary AG-UI input and emits ordinary AG-UI events; the platform mechanics stay behind the adapter, so the same Mastra agent runs unchanged across every channel. Rich messages are written as JSX and rendered to each platform's native format (Block Kit on Slack, for example), so an interactive card degrades gracefully where a platform has no equivalent.

Slack
Direct link to Slack

The Slack quickstart takes you from zero to a bot you can @-mention in a channel, then adds an interactive button card. Slack runs over Socket Mode, which opens an outbound WebSocket to Slack, so no public URL or tunnel is required during development.

Set the Slack credentials in your environment:

  • SLACK_BOT_TOKEN: Bot User OAuth token (xoxb-...)
  • SLACK_APP_TOKEN: App-level token with the connections:write scope (xapp-...)

Other platforms
Direct link to Other platforms

The Channels SDK isn't limited to Slack. Other platforms like Microsoft Teams run through the same @copilotkit/channels API: add the matching adapter to the adapters array and the rest of your agent code stays the same. See the CopilotKit Channels documentation for the current platform list and per-platform setup.

Message pipeline and architecture
Direct link to Message pipeline and architecture

Managed channels keep a deliberate credential split, which matters when your Mastra agent uses separate model keys and tools:

  • You keep the agent logic, model credentials, tools, and the channel process.
  • CopilotKit Intelligence holds the platform credentials, message delivery, registration, health, and reconnects.

A turn begins when a user messages the app. Intelligence receives the platform event, and the gateway delivers the turn to your running channel process. Your Mastra agent runs and renders a reply. Intelligence then returns the reply as native platform content. Platform credentials never enter the agent process, and enterprise Intelligence can be self-hosted for data residency.

note

By default, interactive actions live in memory and reset on restart. Back the channel with a durable action and state store (Redis or Postgres) so buttons and per-thread state survive restarts and span multiple instances.