Channels Overview
Run your CopilotKit agent as a bot inside Slack, Teams, WhatsApp, Telegram, and Discord.
Channels let you take a CopilotKit agent and run it as a bot inside a chat app. The user talks to your agent in Slack, Teams, WhatsApp, Telegram, or Discord, and your agent answers right there in the thread.
You write the bot once. The same agent, tools, commands, and interactive cards run on every platform you attach.
A channel, end to end#
Three pieces: a TanStack AI agent, JSX turned on, and a channel that plugs the agent into a platform and replies with clickable UI.
npm install @copilotkit/channels @copilotkit/runtime @tanstack/ai @tanstack/ai-openaiThe agent#
A Built-in Agent in TanStack factory mode. You own the model call with TanStack AI; the agent turns its stream into the events the channel renders.
import { BuiltInAgent, convertInputToTanStackAI } from "@copilotkit/runtime/v2";
import { chat } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
export const agent = new BuiltInAgent({
type: "tanstack",
factory: (ctx) => {
const { messages, systemPrompts, tools } = convertInputToTanStackAI(ctx.input);
return chat({
adapter: openaiText("gpt-5.5"),
messages,
systemPrompts: ["You are a helpful support assistant.", ...systemPrompts],
tools,
abortController: ctx.abortController,
});
},
});Turn on JSX#
Replies render as native UI. Point the JSX runtime at the channels package.
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@copilotkit/channels"
}
}The channel#
Declare a channel, then answer messages. A reply can be the agent's own words, or a card whose button you handle right where you wrote it.
import { createChannel } from "@copilotkit/channels";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
import { Message, Section, Actions, Button } from "@copilotkit/channels/ui";
import { agent } from "./agent";
// A managed channel: Intelligence hosts the transport, so no adapter.
const channel = createChannel({
name: "support-bot",
agent,
});
channel.onMessage(async ({ thread, message }) => {
// let the agent answer
await thread.runAgent({ prompt: message.text });
// then post a card, and handle the click right here
await thread.post(
<Message>
<Section>{"Did that answer your question?"}</Section>
<Actions>
<Button
onClick={async ({ thread }) => {
await thread.post("Glad I could help!");
}}
>
Yes, thanks
</Button>
</Actions>
</Message>,
);
});
// The runtime owns the channel's lifecycle. A CopilotKit Intelligence key runs
// any channel (free tier available); `ready()` activates it.
const apiUrl = process.env.COPILOTKIT_INTELLIGENCE_URL!;
const runtime = new CopilotRuntime({
agents: {},
intelligence: new CopilotKitIntelligence({
apiUrl,
wsUrl: apiUrl.replace(/^http/, "ws"),
apiKey: process.env.COPILOTKIT_API_KEY!,
}),
identifyUser: () => ({ id: "demo-user", name: "Demo User" }),
channels: [channel],
});
const listener = createCopilotNodeListener({ runtime });
await listener.channels?.ready();
// Mount the listener on an HTTP server to keep the process running (see the Quickstart).That is a working bot: a TanStack AI agent, answering across platforms, replying with clickable UI. The Quickstart adds the dashboard setup and environment, and the UI library shows how to register that card so its button still works after a restart.
Two ways to connect a platform#
Every channel runs through the Intelligence runtime, so both paths need a CopilotKit Intelligence key (free tier available). The difference is who holds the platform bot credentials — either way, the runtime drives the channel.
| Managed | Direct (platform adapter) | |
|---|---|---|
| Who holds the platform tokens | CopilotKit Intelligence | You supply them to the adapter |
| Add a platform | Attach it in the Intelligence dashboard | Add another adapter in code |
| Best for | Shipping fast, many platforms, no platform secrets in your app | Owning one platform's connection end to end |
With the managed path your process holds no Slack or Teams tokens: Intelligence receives the platform event, delivers the turn to your bot, runs the same handlers, and does the credentialed send back. With a direct adapter you supply the platform credentials, but the runtime still owns the channel's lifecycle. Start with managed. See Platforms for what Intelligence handles for you and the per-platform setup.
What you can build#
Quickstart
A working bot that answers messages, end to end.
UI library
Reply with cards, buttons, and inputs using JSX.
Interactive flows
Approval gates and reaction handlers built on components.
Commands and reactions
Slash commands and react-to-any-message handlers.
Files and multimodality
Let users drop in images and files for the agent to read.
MCP servers
Give the bot external tools through MCP.
Platforms
Teams, WhatsApp, Slack, Telegram, and Discord, and what Intelligence handles for you.
API reference
Every method on the channel, the thread, and JSX callbacks.