From chat-sdk
Build multi-platform chat bots for Slack, Teams, Google Chat, Discord, GitHub, and Linear using Chat SDK npm package. Handles mentions, webhooks, messages, reactions, cards, modals, and AI streaming.
How this skill is triggered — by the user, by Claude, or both
Slash command
/chat-sdk:chat-sdkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, GitHub, and Linear. Write bot logic once, deploy everywhere.
Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, GitHub, and Linear. Write bot logic once, deploy everywhere.
The chat package ships with full documentation in node_modules/chat/docs/ and TypeScript source types. Always read these before writing code:
node_modules/chat/docs/ # Full documentation (MDX files)
node_modules/chat/dist/ # Built types (.d.ts files)
Key docs to read based on task:
docs/getting-started.mdx — setup guidesdocs/usage.mdx — event handlers, threads, messages, channelsdocs/streaming.mdx — AI streaming with AI SDKdocs/cards.mdx — JSX interactive cardsdocs/actions.mdx — button/dropdown handlersdocs/modals.mdx — form dialogs (Slack only)docs/adapters.mdx — platform-specific adapter setupdocs/state.mdx — state adapter config (Redis, ioredis, PostgreSQL, memory)Also read the TypeScript types from node_modules/chat/dist/ to understand the full API surface.
import { Chat } from "chat";
import { createSlackAdapter } from "@chat-adapter/slack";
import { createRedisState } from "@chat-adapter/state-redis";
const bot = new Chat({
userName: "mybot",
adapters: {
slack: createSlackAdapter({
botToken: process.env.SLACK_BOT_TOKEN!,
signingSecret: process.env.SLACK_SIGNING_SECRET!,
}),
},
state: createRedisState({ url: process.env.REDIS_URL! }),
});
bot.onNewMention(async (thread) => {
await thread.subscribe();
await thread.post("Hello! I'm listening to this thread.");
});
bot.onSubscribedMessage(async (thread, message) => {
await thread.post(`You said: ${message.text}`);
});
post(), schedule(), subscribe(), startTyping()text, formatted (mdast AST), raw| Handler | Trigger |
|---|---|
onNewMention | Bot @-mentioned in unsubscribed thread |
onSubscribedMessage | Any message in subscribed thread |
onNewMessage(regex) | Messages matching pattern in unsubscribed threads |
onSlashCommand("/cmd") | Slash command invocations |
onReaction(emojis) | Emoji reactions added/removed |
onAction(actionId) | Button clicks and dropdown selections |
onAssistantThreadStarted | Slack Assistants API thread opened |
onAppHomeOpened | Slack App Home tab opened |
Pass any AsyncIterable<string> to thread.post(). Works with AI SDK's textStream:
import { ToolLoopAgent } from "ai";
const agent = new ToolLoopAgent({ model: "anthropic/claude-4.5-sonnet" });
bot.onNewMention(async (thread, message) => {
const result = await agent.stream({ prompt: message.text });
await thread.post(result.textStream);
});
Set jsxImportSource: "chat" in tsconfig. Components: Card, CardText, Button, Actions, Fields, Field, Select, SelectOption, Image, Divider, LinkButton, Section, RadioSelect.
await thread.post(
<Card title="Order #1234">
<CardText>Your order has been received!</CardText>
<Actions>
<Button id="approve" style="primary">Approve</Button>
<Button id="reject" style="danger">Reject</Button>
</Actions>
</Card>
);
| Package | Purpose |
|---|---|
chat | Core SDK |
@chat-adapter/slack | Slack |
@chat-adapter/teams | Microsoft Teams |
@chat-adapter/gchat | Google Chat |
@chat-adapter/discord | Discord |
@chat-adapter/github | GitHub Issues |
@chat-adapter/linear | Linear Issues |
@chat-adapter/state-redis | Redis state (production) |
@chat-adapter/state-ioredis | ioredis state (alternative) |
@chat-adapter/state-pg | PostgreSQL state (production) |
@chat-adapter/state-memory | In-memory state (development) |
This monorepo uses Changesets for versioning and changelogs. Every PR that changes a package's behavior must include a changeset.
pnpm changeset
# → select affected package(s) (e.g. @chat-adapter/slack, chat)
# → choose bump type: patch (fixes), minor (features), major (breaking)
# → write a short summary for the CHANGELOG
This creates a file in .changeset/ — commit it with the PR. When merged to main, the Changesets GitHub Action opens a "Version Packages" PR to bump versions and update CHANGELOGs. Merging that PR publishes to npm.
To create a community or vendor adapter, implement the Adapter interface from chat and read:
docs/contributing/building.mdx — full step-by-step guide (uses a Matrix adapter as example)docs/contributing/testing.mdx — testing your adapterdocs/contributing/publishing.mdx — npm naming conventions and publishingThe adapter must implement handleWebhook, parseMessage, postMessage, editMessage, deleteMessage, thread ID encoding/decoding, and a FormatConverter (extend BaseFormatConverter from chat). Use @chat-adapter/shared for error classes and message utilities.
Each adapter exposes a webhook handler via bot.webhooks.{platform}. Wire these to your HTTP framework's routes (e.g. Next.js API routes, Hono, Express).
npx claudepluginhub pleaseai/claude-code-plugins --plugin chat-sdkProvides expert guidance on Vercel AI SDK's Chat SDK for building multi-platform chatbots—Slack, Telegram, Discord, Teams, Google Chat, GitHub, Linear—with one codebase. Covers Chat class, adapters, threads, messages, cards, modals, streaming, state, webhooks.
Builds Slack apps with the Bolt framework in Python, JavaScript, or Java. Covers Block Kit UIs, slash commands, event handling, OAuth, and Workflow Builder integration.