showcase/shell-docs/src/content/reference/channels/sdk/direct-adapters.mdx
@copilotkit/channels supports two provider-connection models:
| Model | Channel declaration | Provider connection | Available providers |
|---|---|---|---|
| Managed Intelligence | createChannel({ name, provider, agent }) | CopilotKit Intelligence stores provider credentials and owns ingress and egress | Slack and Microsoft Teams |
| Direct adapter | createChannel({ name, adapters, agent }) | Your Channels process stores provider credentials and owns the provider socket or webhook | Slack, Microsoft Teams, Discord, Telegram, and WhatsApp |
Managed Intelligence support for Discord and WhatsApp is coming soon. Their
direct adapters already ship in @copilotkit/[email protected].
Install the umbrella package and its tested runtime version:
npm install --save-exact @copilotkit/[email protected] @copilotkit/[email protected]
The package and all provider subpaths are ESM-only public exports. Use
import; CommonJS require() is not supported.
Import adapters from the package's provider subpaths:
import { createChannel } from "@copilotkit/channels";
import { slack } from "@copilotkit/channels/slack";
import { makeAgent } from "./agent.js";
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Missing required environment variable: ${name}`);
return value;
}
export const channel = createChannel({
name: "support-direct",
adapters: [
slack({
botToken: required("SLACK_BOT_TOKEN"),
appToken: required("SLACK_APP_TOKEN"),
}),
],
agent: makeAgent,
});
channel.onMessage(async ({ thread }) => {
await thread.runAgent();
});
Pass this Channel to new CopilotRuntime({ channels: [channel], ... }) and
start it through the runtime's Channels control, just as in the managed
quickstarts. For direct adapters, provider is ignored. Do not combine the
managed Intelligence adapter with direct adapters on the same Channel.
One direct Channel may contain multiple direct adapters. Its name must still
be present and unique among the Channels declared on that CopilotRuntime.
import {
slack,
SlackAdapter,
type SlackAdapterOptions,
} from "@copilotkit/channels/slack";
SlackAdapterOptions requires botToken and appToken. Socket Mode is on by
default. HTTP mode requires socketMode: false and a signingSecret.
The Slack entry point also exports its listener, renderers, codec, streaming
helpers, conversation store, built-in context and tools, file helpers, and
SLACK_LIMITS. Lower-level render and codec entry points are available from
@copilotkit/channels/slack/render and
@copilotkit/channels/slack/codec.
import {
teams,
TeamsAdapter,
type TeamsAdapterOptions,
} from "@copilotkit/channels/teams";
TeamsAdapterOptions accepts clientId, clientSecret, tenantId, and
port. clientId and clientSecret are required for real Teams;
tenantId may be omitted for a multi-tenant deployment. These values fall
back to the lowercase clientId, clientSecret, and tenantId environment
variables. All three may be omitted only for anonymous local development with
the Microsoft 365 Agents Playground. The adapter serves
POST /api/messages on port 3978 by default.
The Teams entry point also exports its server, Adaptive Card renderer,
conversation store, message stream, interaction helpers, file helpers, and
TEAMS_LIMITS. Renderer exports are also available from
@copilotkit/channels/teams/render.
import {
discord,
DiscordAdapter,
type DiscordAdapterOptions,
} from "@copilotkit/channels/discord";
DiscordAdapterOptions requires botToken and appId; set guildId to
register slash commands immediately in one development guild. The entry point
also exports its listener, renderer, command registration, conversation store,
streaming helpers, built-in context and tools, file helpers, and
DISCORD_LIMITS.
Enable the privileged Message Content Intent and Server Members Intent
for the bot in the Discord Developer Portal. The adapter requests
MessageContent and GuildMembers on every connection.
import {
telegram,
TelegramAdapter,
type TelegramAdapterOptions,
} from "@copilotkit/channels/telegram";
TelegramAdapterOptions requires a bot token. Ingress defaults to
long-polling. Set mode: "webhook" and provide webhook configuration for a
public webhook deployment. The entry point also exports its listener,
renderer, conversation store, streaming helper, built-in context and tools,
file helpers, and TELEGRAM_LIMITS.
import {
whatsapp,
WhatsAppAdapter,
type WhatsAppAdapterOptions,
} from "@copilotkit/channels/whatsapp";
WhatsAppAdapterOptions requires accessToken, phoneNumberId, appSecret,
and verifyToken. The webhook server uses port 3000 and path /webhook by
default. The entry point also exports its client, renderer, conversation and
history stores, built-in context and tools, file helpers, and WA_LIMITS.
Direct and managed adapters do not have identical capabilities. For example,
the direct Slack adapter supports modals, reactions, incremental streaming, and
ephemeral messages. Managed Slack accepts the streaming API but buffers the
stream and posts it once instead of updating incrementally; it does not support
the other three capabilities. Check
the direct adapter instance's read-only capabilities property when you own
the adapter. Capability-result Thread methods can also return { ok: false };
handle that result instead of assuming a provider name guarantees one
behavior.
The Slack and Teams guides in the provider picker document the production-ready managed path. Use this page when your deployment intentionally owns provider credentials, sockets, webhooks, and provider-specific operations.