A Slack app powered by Claude Code SDK. Responds in DMs, channels, and @-mentions with streaming responses, thread context, file uploads, and extensible MCP tool integrations.
src/slack-handler.ts- Message routing and event handlingsrc/claude-handler.ts- Session management and Claude Code SDK integrationsrc/mcp-manager.ts- MCP server configuration and tool managementsrc/message-processor.ts- Stream processing and response formattingsrc/tracking.ts- Analytics tracking for message processing and feedbacksrc/channel-config.ts- Channel-specific context and configuration managementsrc/user-utils.ts- User information and role-based access control
git clone https://github.com/duolingo/slack-ai-agent.git
npm install- Go to api.slack.com/apps → "Create New App" → "From an app manifest"
- Paste the contents of
slack-app-manifest.yaml - Install the app to your workspace
- Copy the Bot User OAuth Token (
xoxb-...) from "OAuth & Permissions" - Generate an App-Level Token with
connections:writescope (xapp-...) from "Basic Information" - Copy the Signing Secret from "Basic Information"
cp .env.example .envFill in your tokens. See .env.example for all available variables.
Copy the example configs and customize for your workspace:
| Example file | Copy to | Purpose |
|---|---|---|
config/example-reactions.yaml |
config/reactions.yaml |
Emoji reactions for thinking, completion, errors |
config/example-tool-allowlist.yaml |
config/tool-allowlist.yaml |
Role-based tool access control (key order = role hierarchy) |
config/example-tool-denylist.yaml |
config/tool-denylist.yaml |
Tools the bot must never use |
config/instructions/example-general-context.txt |
config/instructions/general-context.txt |
Base system prompt injected into every response |
| Example file | Copy to | Purpose |
|---|---|---|
config/example-channels.yaml |
config/channels.yaml |
Channel auto-reply routing, keyword triggers, ephemeral summaries |
config/instructions/example-channel.txt |
config/instructions/<name>.txt |
Channel-specific system prompt context (referenced by channels.yaml) |
config/subagents/example-subagents.yaml |
config/subagents/<name>.yaml |
Sub-agents for validation or post-processing |
config/approvable-actions/example-approvable-action.ts |
config/approvable-actions/<name>.ts |
Human-in-the-loop actions (auto-discovered) |
data/example-employees.yaml |
data/employees.yaml |
Employee directory for role assignment and people lookups |
mcp-servers.example.json |
mcp-servers.json |
MCP server connections (GitHub, Slack, Jenkins, etc.) |
Quick start:
cp .env.example .env
cp config/example-reactions.yaml config/reactions.yaml
cp config/example-tool-allowlist.yaml config/tool-allowlist.yaml
cp config/example-tool-denylist.yaml config/tool-denylist.yaml
cp config/instructions/example-general-context.txt config/instructions/general-context.txtnpm run dev # development (auto-reload)
npm run build && npm run prod # production- DMs: responds to all messages
- Configured channels: auto-replies based on
channels.yamlrules - All other channels: responds only when @-mentioned
- File uploads: supports images, code files, PDFs, and documents
npm test # run all tests
npx jest --watch # re-run on file changes
npx jest src/logger # run tests matching a patternTests use Jest with ts-jest. Test files live next to their source files as *.test.ts.
Apache 2.0 — see LICENSE.
Duolingo is hiring! Apply at https://www.duolingo.com/careers