All work

Personal project · npm package2025

slack-claude-bridge

Self-hosted Slack ↔ Claude Code bridge: drive Claude on your laptop from Slack on your phone. Published as an npm package.

Node.jsTypeScriptSlack Socket ModeClaude Code CLInpm
slack-claude-bridge — bridge between Slack on a phone and Claude Code on a laptop. Mention the bot, get a screenshot back, resume sessions via claude -p --resume.

Context

A self-hosted bridge between Slack and Claude Code that runs on my machine and lets me drive a real Claude session from anywhere my phone is. Two modes: one-shot @mentions that fire the slack-respond skill and return a screenshot, and a Conductor session mirror that pipes every Claude turn from any enrolled workspace into a Slack thread — replies feed straight back into the same session via `claude -p --resume`.

Published to npm as `@imran-ansari/slack-claude-bridge`. I use it daily across multiple parallel Conductor worktrees.

What I built

  • Slack Socket Mode listener that routes mentions and thread replies to a local `claude -p` invocation with the correct cwd, session ID, and resume state.
  • Conductor session mirror via Stop hook: a turn ending in any opted-in workspace POSTs to a local notify endpoint, which lands the diff/screenshot in a dedicated Slack thread.
  • Resume protocol — thread replies attach to the same session ID and `claude -p --resume` re-enters with full context, so phone replies feel like the workstation never left.
  • Per-workspace enrollment via a `.slack-mirror` marker file, so noise from non-opted-in worktrees doesn't leak into Slack.
  • Packaged and published to npm under the `@imran-ansari/slack-claude-bridge` scope.

Deep dive

Why a Stop hook + thread mirror

Claude Code's hook system runs a shell command at end-of-turn. Pointing it at a local notify URL lets the bridge collect every turn passively across N parallel worktrees without polling, without modifying Claude itself, and without giving Slack any code-execution rights — Slack only ever sees the final output.