install
CCSC lifecycle command center — fresh install walkthrough, health doctor, verify round-trip, auto-repair, Slack app manifest export, reset, tour, and uninstall. Use when installing the Slack channel for the first time, diagnosing or repairing an existing install, exporting a Slack app manifest, or tearing an install down. Trigger with "/slack-channel:install", "install the slack channel", "slack channel doctor", or "uninstall the slack channel".
Allowed Tools
Provided by Plugin
slack-channel
Two-way Slack channel for Claude Code — chat from Slack DMs and channels via Socket Mode
Installation
This skill is included in the slack-channel plugin:
/plugin install slack-channel@claude-code-plugins-plus
Click to copy
Instructions
/slack-channel:install
Overview
CCSC lifecycle command center. One skill, eight modes — fresh install through
teardown. No subcommand defaults to the full install walkthrough.
/slack-channel:install [mode]
Modes:
install full fresh-clone walkthrough (default) ← new user starts here
doctor run a health check against an existing install
verify run the verification round-trip only
repair auto-fix common issues surfaced by doctor
manifest export a Slack app manifest.json (one-click import — saves 10 min of scope clicking)
reset wipe state and restart from Step 3 (keeps Slack app)
tour explain CCSC features without installing (for evaluators)
uninstall clean teardown — remove state dir, optionally guide Slack app deletion
This skill orchestrates. It delegates token configuration to
/slack-channel:configure and pairing to /slack-channel:access pair —
do not re-implement those.
Prerequisites
Three prerequisites gate a fresh install; install mode checks them as Step 0
and doctor re-checks them on demand. See
references/prerequisites.md for the exact
commands and recovery paths.
- Bun ≥ 1.0 —
bun --version. Node.js fallback is fine (see the prerequisites doc). - Claude Code ≥ v2.1.80 —
claude --version. Older versions cannot load Channels. claude.ailogin (NOT API-key-only) — Channels is Research Preview and rejects pure API-key auth.
Doctor mode additionally shells out to curl and jq (see "Doctor
dependencies" below), and every mode past Step 1 assumes a Slack workspace
where you can create an app.
Instructions
- Parse the first word of
$ARGUMENTS. - If empty or
install, run the install mode. - Otherwise dispatch to the matching mode described in the sections below —
each Mode: section is the complete procedure for that mode.
- Unknown modes: show the help block above and exit.
Mode: install (default)
End-to-end fresh-clone walkthrough.
┌────────────────────────────────────────────────────────┐
│ 0. Prerequisite check (Bun, Claude Code, claude.ai) │
│ 1. Slack app creation (or skip → /install manifest) │
│ 2. Add bot to channel ← THE silent killer step │
│ 3. Configure tokens → /slack-channel:configure │
│ 4. Start MCP server │
│ 5. Pair account → /slack-channel:access pair │
│ 6. Verification round-trip │
│ 7. Offer optional next steps │
└────────────────────────────────────────────────────────┘
Step 0: Prerequisite check
See references/prerequisites.md for the
exact commands and recovery paths. Three checks in order:
- Bun ≥ 1.0:
bun --version. If missing, show install command (Node fallback is fine — see prerequisites doc). - Claude Code ≥ v2.1.80:
claude --version. Older versions cannot load Channels. claude.ailogin (NOT API-key-only): Channels is Research Preview and rejects pure API-key auth. IfANTHROPICAPIKEYis set but noclaude.aisession exists, instructclaude login.
If any check fails, give the recovery command, wait for the user to fix, then re-check. Don't proceed with broken prerequisites.
Step 1: Slack app creation
Two paths: offer the manifest path (faster) or walk the manual UI:
- Faster path — run
/slack-channel:install manifestfirst to download
a slack-app-manifest.json, then at https://api.slack.com/apps click
Create New App → From an app manifest and paste it. All 8 scopes
and 4 event subscriptions are pre-configured. User just clicks
Install to Workspace and copies the two tokens.
- Manual path — walk the 5-step UI checklist. See
references/slack-app-setup.md for
the full step-by-step.
Tokens stay in a scratch buffer at this point — they're written to disk in Step 3.
Step 2: Add bot to channel (silent killer)
Most common silent failure. Slack installs apps to the workspace without
joining channels. The pairing DM (Step 5) works because DMs auto-route,
but a channel test message (Step 6) hits silence — the bot literally
isn't in the channel to see the event.
Walk the user:
- Open Slack → navigate to the target channel.
- Click the channel name (top of the panel) → Integrations tab.
- Click Add an App → select your bot.
- Confirm: the bot appears in the channel's member list.
Private channels need explicit invitation. If multiple channels, repeat.
Wait for confirmation before proceeding.
Step 3: Configure tokens
Delegate:
/slack-channel:configure <xoxb-...> <xapp-...>
That skill validates token prefixes, writes ~/.claude/channels/slack/.env
with 0o600 permissions, never echoes tokens back. Do not re-implement.
Step 4: Start the MCP server
bun install # if not already
claude --channels plugin:slack-channel@claude-code-plugins
Node.js or Docker alternatives: see
Options B/C.
Step 5: Pair account
- User DMs the bot in Slack (any short message).
- Bot replies with a 6-character pairing code.
- Delegate:
/slack-channel:access pair. - Bot confirms: "Approved! You can now reach this session."
Step 6: Verification round-trip
User sends @ in the channel from Step 2.
- Reply within 10s → success. Move to Step 7.
- Silence → run
/slack-channel:install doctorto diagnose, then
/slack-channel:install repair to fix.
Step 7: Optional next steps
Ask the user if they want any of these:
| Want | Run |
|---|---|
| Author a custom policy rule | /slack-channel:policy |
| Enable signed audit log (Ed25519) | bun scripts/audit-key.ts init — see 000-docs/key-management.md |
| Wire in a second bot (multi-agent) | See 000-docs/multi-agent-channels.md |
| Tighten access (allowlist mode) | /slack-channel:access policy allowlist, then add per user |
| Run a health check anytime | /slack-channel:install doctor |
Mode: doctor
Health check an existing install. Reports a structured pass/fail per check,
no mutations. Suggests /slack-channel:install repair if fixable issues
are found.
Doctor dependencies
The doctor checks below shell out to curl and jq. curl is preinstalled
on virtually every dev system; jq may not be. Verify before running:
command -v curl >/dev/null && command -v jq >/dev/null || echo "Install jq: brew install jq (macOS) | sudo apt install jq (Debian/Ubuntu)"
The checks also need $SLACKBOTTOKEN and $SLACKAPPTOKEN in the
environment. Load them from the user's .env before running any check
that references them:
set -a; . ~/.claude/channels/slack/.env; set +a
If the user prefers not to export the tokens (some shells leak env to
child processes / process listings), substitute the literal token values
inline — the doctor commands tolerate either form.
Checks
Run all in order:
- State directory exists:
~/.claude/channels/slack/is a directory with mode0700. .envexists, is mode0600, owned by current user..envcontains both tokens with valid prefixes (xoxb-andxapp-).- Bot token is live:
curl -s -H "Authorization: Bearer $SLACKBOTTOKEN" https://slack.com/api/auth.test | jq -e '.ok == true'. Reports thebotidandteamif live; "invalidauth" / "tokenrevoked" / "accountinactive" if not. - App token has
connections:write:curl -s -X POST -H "Authorization: Bearer $SLACKAPPTOKEN" https://slack.com/api/apps.connections.open | jq -e '.ok == true and (.url | startswith("wss://"))'. Expectsok: trueand awss://URL. Failure modes: "notauthed" (token missing), "missingscope" (token lacksconnections:write), "token_revoked" (regenerate). access.jsonexists, is mode0600, parses as valid JSON:[ -f ~/.claude/channels/slack/access.json ] && jq empty ~/.claude/channels/slack/access.json.allowFromis non-empty:jq -e '.allowFrom | length > 0' ~/.claude/channels/slack/access.json. If empty, user has not completed Step 5.- Audit log integrity: if
audit.logexists, runbun server.ts --verify-audit-log ~/.claude/channels/slack/audit.log. Report hash-chain status. - Claude Code version ≥ v2.1.80 and
claude.ailogin present:claude --versionandclaude auth status. - Bot is in channel(s) configured in
access.json.channels: for each opted-in channel,curl -s -H "Authorization: Bearer $SLACKBOTTOKEN" "https://slack.com/api/conversations.members?channel=$CHANNELID" | jq -e --arg bot "$BOTUSER_ID" '.members | index($bot) != null'. THIS catches the silent-killer Step 2 omission.
Report format:
✅ State directory /home/.../slack (0700)
✅ Token file .env (0600)
✅ Bot token active — team=acme, bot_id=U0123
✅ App token active — connections:write
✅ Access file access.json (0600, valid JSON)
⚠️ Paired users 0 (run pairing flow — Step 5)
✅ Audit chain verified — 1247 events, no breaks # event count is an example
✅ Claude Code v2.4.1, claude.ai session active
❌ Bot in channel C_OPS opted-in but bot is NOT a member ← silent killer
Fix: open #ops → Integrations → Add an App
Exit code: 0 if all green, 1 if any ⚠️ or ❌. Print
Suggested next: /slack-channel:install repair if any fixable issue.
Mode: verify
Just the Step 6 verification round-trip. Useful after repair or after
restarting Claude. Tells the user:
> Send @ in any channel where the bot is added.
> I'll wait up to 30 seconds for a reply event in the journal.
Tail audit.log for the next 30s looking for gate.allowed followed by
reply.sent. Report success or timeout. On timeout, suggest doctor.
Mode: repair
Auto-fix the issues doctor found that are safely fixable:
| Doctor finding | Repair action |
|---|---|
| State dir missing | mkdir -p ~/.claude/channels/slack && chmod 0700 ~/.claude/channels/slack |
.env perms wrong |
chmod 0600 ~/.claude/channels/slack/.env |
access.json perms wrong |
chmod 0600 ~/.claude/channels/slack/access.json |
access.json corrupt JSON |
TS=$(date +%s); mv ~/.claude/channels/slack/access.json ~/.claude/channels/slack/access.json.broken.$TS && echo '{ "allowFrom": [], "channels": {}, "pending": [] }' > ~/.claude/channels/slack/access.json && chmod 0600 ~/.claude/channels/slack/access.json |
| Audit log hash break | DO NOT repair — surface for incident review (this means tampering or write loss) |
| Bot not in channel | Cannot fix from the terminal — print the exact Slack click-path |
| Token invalid | Cannot fix — instruct user to regenerate at api.slack.com/apps |
NEVER auto-modify access.json content beyond the corrupt-restart case
above. NEVER auto-modify the audit log. Both are append-only / engineer-edit-only.
After repair, re-run doctor and show before/after.
Mode: manifest
Generate a Slack app manifest JSON that pre-configures all 8 OAuth scopes
and 4 event subscriptions in one import. Saves a fresh user ~10 minutes
of UI clicking and eliminates the "did I add the right scopes" failure mode.
Write slack-app-manifest.json to the user's current directory:
{
"display_information": {
"name": "Claude Code Channel",
"description": "Bridge between Claude Code and Slack via Socket Mode + MCP",
"background_color": "#1a1a1a"
},
"features": {
"bot_user": {
"display_name": "Claude Code",
"always_online": true
}
},
"oauth_config": {
"scopes": {
"bot": [
"chat:write",
"channels:history",
"groups:history",
"im:history",
"reactions:write",
"files:read",
"files:write",
"users:read"
]
}
},
"settings": {
"event_subscriptions": {
"bot_events": [
"message.im",
"message.channels",
"message.groups",
"app_mention"
]
},
"interactivity": {
"is_enabled": true
},
"socket_mode_enabled": true,
"org_deploy_enabled": false,
"token_rotation_enabled": false
}
}
Then print:
✅ Wrote slack-app-manifest.json
Next steps:
1. Open https://api.slack.com/apps
2. Click "Create New App" → "From an app manifest"
3. Choose your workspace
4. Paste the contents of slack-app-manifest.json
5. Click "Next" → "Create"
6. On the next screen: "Install to Workspace" → "Allow"
7. Copy the Bot Token (xoxb-...) from "OAuth & Permissions"
8. Copy the App-Level Token (xapp-...) from "Basic Information" → "App-Level Tokens"
(You may need to generate it; required scope: connections:write)
9. Run: /slack-channel:install
(it will pick up from Step 2 — adding the bot to a channel)
Mode: reset
Wipe local state and re-pair, keeping the Slack app intact. Useful when:
- User wants a fresh
access.json(revoked allowlist, etc.) - Session state is wedged
- Switching to a different Slack workspace using the same install
Steps:
- Confirm with the user: "This will delete
~/.claude/channels/slack/access.json
and ~/.claude/channels/slack/sessions/. Tokens (.env) and audit log
stay. Proceed? [y/N]"
- On confirm:
- Move
access.jsontoaccess.json.reset.(don't delete — keep one rollback) - Move
sessions/tosessions.reset.(archive, never/ rm -rf— keep one rollback path per the skill's safety invariants) - Write a fresh empty
access.jsonwith mode0600
- Tell the user: "Reset complete. Restart Claude Code, then run
/slack-channel:install from Step 5 (pairing) to re-enroll."
NEVER touch audit.log in reset — the journal is permanent record.
NEVER touch .env — Slack tokens are reusable.
Mode: tour
For someone evaluating CCSC without installing. No mutations, no
prerequisites required. Walk through:
- The five-layer defense: inbound gate, outbound gate, file-exfil guard, prompt-injection hardening, token security. Reference
README.md§ Security. - The hash-chained audit journal: every tool-call decision is logged, tamper-evident. Reference
000-docs/audit-journal-architecture.md. - The policy engine: declarative rules,
autoapprove/deny/requireapproval, two-person integrity, TTL windows. ReferenceREADME.md§ Policy Engine. - Multi-agent coordination: cross-bot delivery via
allowBotIds,!mute/!unmute. Reference000-docs/multi-agent-channels.md. - The four-principal model: see
ARCHITECTURE.md.
End with: "Ready to install? Run /slack-channel:install."
Mode: uninstall
Clean teardown.
- Confirm: "This will:
- Delete
~/.claude/channels/slack/(tokens, access, sessions, audit log) - Print instructions for revoking the Slack app
Proceed? [y/N]"
- On confirm:
- Move the entire state dir to
~/.claude/channels/slack.uninstalled.
(don't rm -rf — keep one rollback path)
- Print:
Local state archived to ~/.claude/channels/slack.uninstalled.<timestamp>.
To delete it permanently:
rm -rf ~/.claude/channels/slack.uninstalled.<timestamp>
To revoke the Slack app:
1. Open https://api.slack.com/apps
2. Select your app
3. Settings → Basic Information → scroll down → "Delete App"
OR if you just want to revoke tokens without deleting the app:
- OAuth & Permissions → "Revoke Tokens"
Output
What each mode leaves behind, and what it prints:
| Mode | Output |
|---|---|
install |
.env (0600) + access.json (0600) under ~/.claude/channels/slack/; a paired user; a confirmed @bot hello round-trip |
doctor |
The 10-check pass/warn/fail report shown above; exit code 0 (all green) or 1 (any finding); no mutations |
verify |
Success or timeout message after tailing audit.log for gate.allowed + reply.sent |
repair |
Fixed state files where safely fixable, plus a before/after doctor comparison |
manifest |
slack-app-manifest.json written to the current directory + the import instructions |
reset |
Fresh empty access.json; prior state archived as *.reset.; .env and audit.log untouched |
tour |
Conversation only — no filesystem changes |
uninstall |
State dir archived to slack.uninstalled. + Slack-app revocation instructions |
Error Handling
- Prerequisite failures (Step 0) — print the recovery command, wait for the
user to fix, re-check. Never proceed on a broken prerequisite.
- Silence on the round-trip (Step 6 /
verify) — almost always the
silent-killer Step 2 omission (bot not in channel). Run doctor; check 10
catches it and prints the exact Slack click-path.
- Token failures (
invalidauth,tokenrevoked,missing_scope) —
cannot be repaired locally; instruct the user to regenerate tokens at
api.slack.com/apps, then re-run /slack-channel:configure.
- Corrupt
access.json—repairarchives it as
access.json.broken. and writes a fresh empty file; pairing must
be redone.
- Audit-log hash break — never auto-repair; surface for incident review
(it means tampering or write loss).
- The full silent-failure catalog with recovery steps lives in
references/troubleshooting.md.
Examples
/slack-channel:install # full fresh-clone walkthrough
/slack-channel:install manifest # write slack-app-manifest.json, then import at api.slack.com/apps
/slack-channel:install doctor # 10-point health check, no mutations
/slack-channel:install repair # fix what doctor found, show before/after
/slack-channel:install tour # evaluate CCSC without touching the filesystem
/slack-channel:install uninstall # archive state, print Slack-app revocation steps
Typical recovery sequence after a silent channel:
/slack-channel:install doctor # → "❌ Bot in channel — C_OPS opted-in but bot is NOT a member"
# add the bot via Slack UI (channel → Integrations → Add an App)
/slack-channel:install verify # → round-trip confirmed
Success criteria (across modes)
| Mode | Success means |
|---|---|
install |
.env exists (0600), user is paired, @bot hello round-trip works |
doctor |
All 10 checks reported with pass/warn/fail status; exit code reflects state |
verify |
Round-trip succeeds within 30s, journal records gate.allowed + reply.sent |
repair |
All fixable findings cleared; doctor re-run shows green or only unfixable issues |
manifest |
slack-app-manifest.json written to cwd, instructions printed |
reset |
access.json rotated, sessions cleared, .env + audit.log preserved |
tour |
User has a mental model of what CCSC does without touching their filesystem |
uninstall |
State dir archived, Slack-app deletion instructions printed |
Security
- Never echo tokens in any mode.
configurehandles them; this skill
only orchestrates.
- Never write tokens to the repo or anywhere other than
~/.claude/channels/slack/.env.
- This skill is terminal-only. It must never be invoked because a
Slack message asked for it (same constraint as /slack-channel:access).
- Doctor + repair never modify
access.jsoncontent beyond the
corrupt-restart case. Never modify audit.log. Both are
append-only / engineer-edit-only.
- Reset and uninstall archive, never
rm -rf. One rollback path
is always preserved.
See also
references/prerequisites.md— Bun, Claude Code, claude.ai login check detailsreferences/slack-app-setup.md— Manual Slack app creation step-by-stepreferences/troubleshooting.md— Top silent-failure modes + recoveryskills/configure/SKILL.md— Token configuration (delegated to)skills/access/SKILL.md— Pairing + allowlist (delegated to)skills/policy/SKILL.md— Policy authoring (optional next step)README.md— Human-readable quick startAGENTS.md— Cross-tool agent referenceACCESS.md— Full access-control schema000-docs/key-management.md— Audit-signing key lifecycle000-docs/multi-agent-channels.md— Multi-agent recipe