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".
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
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".
version
1.0.1
author
Jeremy Longshore <jeremy@intentsolutions.io>
license
Apache-2.0
compatibility
Requires Claude Code >= v2.1.80 with a claude.ai login (Channels research preview rejects API-key-only auth), Bun >= 1.0 (Node.js fallback supported), and a Slack workspace where you can create apps. Doctor mode additionally shells out to curl and jq.
tags
["slack","mcp","install","doctor","lifecycle"]
user-invocable
true
argument-hint
[install | doctor | verify | repair | manifest | reset | tour | uninstall]
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.ai login (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.
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.ai login (NOT API-key-only): Channels is Research Preview and rejects pure API-key auth. If ANTHROPIC_API_KEY is set but no claude.ai session exists, instruct claude 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 manifest first 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.
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
/slack-channel:access policy allowlist, then add <user-id> 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:
The checks also need $SLACK_BOT_TOKEN and $SLACK_APP_TOKEN 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 mode 0700.
.env exists, is mode 0600, owned by current user.
.env contains both tokens with valid prefixes (xoxb- and xapp-).
Bot token is live: curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" https://slack.com/api/auth.test | jq -e '.ok == true'. Reports the bot_id and team if live; "invalid_auth" / "token_revoked" / "account_inactive" if not.
App token has connections:write: curl -s -X POST -H "Authorization: Bearer $SLACK_APP_TOKEN" https://slack.com/api/apps.connections.open | jq -e '.ok == true and (.url | startswith("wss://"))'. Expects ok: true and a wss:// URL. Failure modes: "not_authed" (token missing), "missing_scope" (token lacks connections:write), "token_revoked" (regenerate).
access.json exists, is mode 0600, parses as valid JSON: [ -f ~/.claude/channels/slack/access.json ] && jq empty ~/.claude/channels/slack/access.json.
allowFrom is 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.log exists, run bun server.ts --verify-audit-log ~/.claude/channels/slack/audit.log. Report hash-chain status.
Claude Code version ≥ v2.1.80 and claude.ai login present: claude --version and claude auth status.
Bot is in channel(s) configured in access.json.channels: for each opted-in channel, curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" "https://slack.com/api/conversations.members?channel=$CHANNEL_ID" | jq -e --arg bot "$BOT_USER_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 @<bot> hello 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:
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.json to access.json.reset.<timestamp> (don't delete — keep one rollback)
Move sessions/ to sessions.reset.<timestamp>/ (archive, never rm -rf — keep one rollback path per the skill's safety invariants)
Write a fresh empty access.json with mode 0600
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:
Print instructions for revoking the Slack app
Proceed? [y/N]"
On confirm:
Move the entire state dir to ~/.claude/channels/slack.uninstalled.<timestamp>
(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.<timestamp>; .env and audit.log untouched
tour
Conversation only — no filesystem changes
uninstall
State dir archived to slack.uninstalled.<timestamp> + 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 (invalid_auth, token_revoked, 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 — repair archives it as
access.json.broken.<timestamp> 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).
/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