Installs just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/add-slack
๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
Add Slack channel integration via Chat SDK.
๐ Stats
Stars30,326
Forks12,869
LanguageTypeScript
LicenseMIT
๐ฆ Ships with nanoclaw
</> SKILL.md
add-slack.SKILL.md
---name: add-slack
description: Add Slack channel integration via Chat SDK.
---# Add Slack Channel
Adds Slack support via the Chat SDK bridge. NanoClaw doesn't ship channels in
trunk โ this skill copies the Slack adapter in from the `channels` branch.
The mechanical steps under **Apply** carry `nc:` directive fences: an agent
reads the prose and applies them, and a parser can apply them deterministically
from the same document. Every directive is idempotent, so the whole skill is
safe to re-run; anything a parser can't apply falls back to the prose beside it.
## Apply
### 1. Copy the adapter, registration test, and formatting skill
Fetch the `channels` branch and copy the Slack adapter, its registration test,
and the formatting container skill into place (overwrite โ the branch is
canonical):
```nc:copy from-branch:channels
src/channels/slack.ts
src/channels/slack-registration.test.ts
container/skills/slack-formatting/SKILL.md
```
The `slack-formatting` container skill is part of the channel payload: it
reaches agents via `~/.claude/skills` (synced at spawn) and teaches Slack's
mrkdwn syntax. Trunk does not ship it โ without this copy step agents send
How should Slack deliver events? `socket` (Socket Mode โ no public URL, recommended for local or behind-NAT installs) or `webhook` (needs a public HTTPS Request URL).
```
Walk the operator through creating the Slack app, then collect the secrets it
hands back. The adapter is already installed and registered โ it just can't
receive a message until this is done. For Socket Mode, tell the user:
```nc:operator when:connection=socket
Create the Slack app (Socket Mode):
1. Go to api.slack.com/apps โ Create New App โ From scratch. Name it (e.g. "NanoClaw") and pick your workspace.
3. App Home โ enable the Messages Tab, and check "Allow users to send Slash commands and messages from the messages tab."
4. Basic Information โ App-Level Tokens โ "Generate Token and Scopes" โ add the connections:write scope โ copy the token (starts with xapp-).
5. Socket Mode โ toggle "Enable Socket Mode" on.
6. Event Subscriptions โ toggle "Enable Events" on, then under "Subscribe to bot events" add: message.channels, message.groups, message.im, app_mention. Save Changes. (No Request URL is needed in Socket Mode.)
7. Install to Workspace, then copy the Bot User OAuth Token (starts with xoxb-).
```
For webhook delivery, tell the user:
```nc:operator when:connection=webhook
Create the Slack app (webhook delivery):
1. Go to api.slack.com/apps โ Create New App โ From scratch. Name it (e.g. "NanoClaw") and pick your workspace.
`owner_handle` and `platform_id` are what the owner-wiring step needs. The
greeting goes out over `chat.postMessage`, which works right away. Receiving
replies needs the event path live: with Socket Mode that happens as soon as the
service restarts below; with webhook delivery, finish the Event Subscriptions
and Interactivity steps above first.
## Restart
With the credential validated, restart the service so it loads the Slack adapter
and the secrets you just stored, and wait for its CLI socket before wiring:
```nc:run effect:restart
bash setup/lib/restart.sh
```
## Next Steps
If you're in the middle of `/setup`, return to the setup flow now. Otherwise wire
this channel with `/init-first-agent` (or `/manage-channels`).
## Channel Info
- **type**: `slack`
- **terminology**: Slack has "workspaces" containing "channels." Channels can be public (#general) or private. The bot can also receive direct messages.
- **platform-id-format**: `slack:{channelId}` for channels (e.g., `slack:C0123ABC`), `slack:{dmId}` for DMs (e.g., `slack:D0ARWEBLV63`)
- **how-to-find-id**: Right-click a channel name > "View channel details" โ the Channel ID is at the bottom (starts with C). For DMs, the ID starts with D. Or copy the channel link โ the ID is the last segment of the URL.
- **supports-threads**: yes
- **typical-use**: Interactive chat โ team channels or direct messages
- **default-isolation**: Same agent group for channels where you're the primary user. Separate agent group for channels with different teams or sensitive contexts.
## Troubleshooting
**A token paste is rejected.** Each secret has a fixed shape: the Bot User OAuth Token starts `xoxb-` (OAuth & Permissions, after Install to Workspace), the App-Level Token starts `xapp-` (Basic Information โ App-Level Tokens), and the Signing Secret is a hex string (Basic Information). The classic mix-up is pasting a user token (`xoxp-`) instead of the bot token, or the app's Client Secret instead of the Signing Secret.
**`auth.test` fails, or `conversations.open` returns no channel.** A failing `auth.test` means the bot token is wrong or the app was never installed to the workspace. `conversations.open` coming back empty means the `im:write` scope is missing โ add it under OAuth & Permissions and **reinstall the app**; scope changes only take effect after reinstall, which also mints a new `xoxb-` token to store.
**The greeting arrives but your replies vanish.** Sending works with just the bot token; *receiving* needs the event path. Socket Mode: the toggle on, `SLACK_APP_TOKEN` set with `connections:write`, and the bot events (`message.im`, `message.channels`, `message.groups`, `app_mention`) subscribed. Webhook: the Request URL must have passed Slack's challenge and the same events subscribed. Either way, App Home's Messages Tab must be enabled or Slack refuses DMs to the app.
**Adapter registered but Slack never connects.** Run `pnpm exec vitest run src/channels/slack-registration.test.ts` โ red means the barrel import or the `@chat-adapter/slack` install drifted, so re-run the Apply steps. If green, restart the service (`bash setup/lib/restart.sh`) so it picks up the adapter and tokens, then check `logs/nanoclaw.error.log`.