install
CCSC lifecycle command center — fresh install walkthrough, health doctor, verify round-trip, auto-repair, Slack app manifest export, reset, tour, and uninstall. One skill for the full install lifecycle.
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
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.
Mode dispatch
Parse the first word of $ARGUMENTS. If empty or install, run install.
Otherwise dispatch to the matching 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 README.md § Quick Start 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
✅ 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"
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 + recovery../configure/SKILL.md— Token configuration (delegated to)../access/SKILL.md— Pairing + allowlist (delegated to)../policy/SKILL.md— Policy authoring (optional next step)../../README.md— Human-readable quick start../../AGENTS.md— Cross-tool agent reference../../ACCESS.md— Full access-control schema../../000-docs/key-management.md— Audit-signing key lifecycle../../000-docs/multi-agent-channels.md— Multi-agent recipe