Agent-readable docs
Channels SDK Documentation
Technical documentation for @copilotkit/channels — the SDK that connects any AG-UI-compatible agent to Slack, Microsoft Teams, Discord, Telegram, and WhatsApp with native interactive UI. For developers building, wiring, and operating a long-running Channels listener.
Pages
- OverviewWhat the Channels SDK exposes: the five-piece mental model (Channel, Thread, Tools, UI, Context), the you-run vs Intelligence-manages boundary, runtime assumptions (Node.js 22+, long-running process, no serverless), and the shortest path to a first online Channel.
- InstallationInstall @copilotkit/channels with @copilotkit/runtime as a version-locked pair, enforce ESM with npm pkg set type=module, pin @ag-ui/client via overrides to avoid the duplicate-AbstractAgent compile failure, and configure tsconfig with jsxImportSource for the Channels JSX runtime.
- QuickstartBuild the first managed Channel: create the Channel in CopilotKit Intelligence, write the createChannel + CopilotRuntime + createCopilotNodeListener listener, set the four environment variables, start with node --env-file, and verify status().overall === "online" before trusting the deploy.
- Set up with a coding agentThe agent-driven setup path: npx copilotkit@latest channels setup, the hosted channels-guide.md workflow, installing setup-slack-channel via the CLI instead of vendoring it, and how this repository's canonical .agents/skills layout and .claude symlink keep the build-channels-agent skill authoritative.
- Architecture and the runtime boundaryHow a turn flows: platform event → Intelligence ingress → your Channels process → agent over AG-UI → native UI back into the conversation. What you host (agent, tools, listener, state) versus what Intelligence manages (platform credentials, ingress, delivery, reconnects), and why a Channel needs a persistent gateway connection.
- Channel lifecycle and statusThe runtime owns the lifecycle — there is no channel.start(). Listener creation starts the Channel; channels.ready() settles activation but also resolves on setup_required; the six SDK status values (connecting, online, setup_required, reconnecting, error, stopped) versus the Intelligence dashboard states; teardown ordering for SIGINT/SIGTERM.
- Managed Channels vs direct adaptersThe managed default (no adapter, Channel Code from Intelligence, no platform tokens in your process) versus the direct-adapter path (adapters: [slack({ botToken, appToken })], Socket Mode, defaultSlackTools/defaultSlackContext). When each applies, and why switching to a direct adapter to escape setup_required is a known failure mode.
- Handle mentions, messages, and subscriptionsWire the ten channel handlers — onMention, onMessage, onThreadStarted, onWelcome, onCommand, onInteraction, onInterrupt, onReaction, onModalSubmit, onModalClose — reply on mention with thread.runAgent(), forward contentParts explicitly, and use subscribe()/isSubscribed() to answer every message in an invited conversation.
- Add toolsDefine typed agent tools with defineChannelTool and any Standard Schema validator (Zod, Valibot, ArkType): the ChannelToolContext shape ({ thread, message?, user, actor, signal?, platform }), return-value rules (raw data back to the agent, error text on failure), and registration via createChannel({ tools }) or channel.tool().
- Render interactive UIPost one JSX tree that lowers to Block Kit, Adaptive Cards, or Discord components: thread.post/update/delete, inline onClick/onSelect handlers with content-stable IDs, graceful degradation on surfaces that skip unsupported nodes, and agent-rendered components via defineChannelComponent (0.7+).
- Human-in-the-loop approvalsGate agent actions on humans: thread.awaitChoice<T> to block a tool handler on a typed button choice, onInterrupt + thread.resume for agent-originated pauses (LangGraph-style interrupts), and making approval buttons survive restarts with a durable StateStore adapter plus registered components.
- Slash commands and modalsHandle commands with channel.onCommand — arguments arrive as raw text (options is populated only on structured surfaces like Discord) — hand them to the agent explicitly, and open modals with ctx.openModal calling Modal({...}) as a function (not <Modal> JSX), routing submissions by callbackId to onModalSubmit/onModalClose.
- Author a platform adapterImplement the PlatformAdapter contract for a new surface: ingress via start(sink), egress rendering of ChannelNode[] with a total renderer that skips unsupported nodes, createRunRenderer for live agent streaming, decodeInteraction with content-stable ID recovery, and the declared capabilities object.
- createChannel referenceEvery createChannel option with constraints: required identifyUser ("platform" or a callback), Channel Code naming rules for name, the agent factory contract and per-turn cloning, adapters, tools, context, components, commands, store (adapter, state schema, actionRetentionMs, concurrency), showToolStatus, replyContinuation, and sanitizeAgentEvents.
- Thread API referenceThe per-conversation thread handle: post, update, delete, stream, postFile, postEphemeral, runAgent (prompt, context, tools, transcript, memory grants), resume, awaitChoice, subscribe/unsubscribe/isSubscribed, getMessages, setTitle, setSuggestedPrompts, react, state/setState, and lookupUser — including which methods are capability-gated and degrade instead of throwing.
- UI components referenceThe full channels-ui JSX vocabulary with props and degradation rules: layout components (Message, Header, Section, Markdown, Fields, Field, Context, Divider, Image, Table, Chart), interactive components (Actions, Button, Select, Input), modal components (Modal, TextInput, ModalSelect, RadioButtons), and handler context shapes.
- Configuration referenceEnvironment variables and project configuration: INTELLIGENCE_API_KEY, CHANNEL_CODE, PORT, the paired INTELLIGENCE_API_URL / INTELLIGENCE_GATEWAY_WS_URL overrides (bare base URLs, never derived from each other), AGENT_URL for remote AG-UI agents, plus the required tsconfig (jsxImportSource, module settings) and package.json shape (type: module, overrides pin).
- Minimal Channel exampleThe smallest complete listener, file by file: lib/channel.ts (createChannel plus onMention/onMessage with the subscribe pattern), lib/runtime.ts (CopilotRuntime with an explicit CopilotKitIntelligence connection), lib/env.ts (fail-fast env loading), and server.ts (ready() gate, HTTP server, SIGINT teardown) — with the 🪁 no-model-call verification trick.
- OpenTag reference applicationThe flagship Channels app vendored as a pinned git submodule: what it demonstrates (Python LangGraph agent over AG-UI, Slack and Teams surfaces, file-aware prompts, approval-gated Linear/Notion writes), how to fetch it with git submodule update --init, its prerequisites, and the deliberate one-line workflow for bumping the pin.
- TroubleshootingDocumented failure modes with fixes: the duplicate @ag-ui/client "_debug private property" compile error, TS1309 from missing type: module, TS2345 ModalView narrowing, JSX compiled against React, setup_required and Waiting for runtime states, ready() resolving on a degraded Channel, Unknown option '--skill' from a stale CLI, and the invented Bot-prefixed APIs that never existed.
Complete Markdown
The complete agent-readable Markdown files are published separately from this HTML page.