{"id":49492667,"url":"https://github.com/sohei-t/slack-bridge-for-claude-code","last_synced_at":"2026-05-01T07:06:11.704Z","repository":{"id":340503723,"uuid":"1166306378","full_name":"sohei-t/slack-bridge-for-claude-code","owner":"sohei-t","description":"Bidirectional Slack integration for Claude Code - control AI coding sessions from your phone via Slack Bot DM with real-time notifications","archived":false,"fork":false,"pushed_at":"2026-03-12T07:39:13.000Z","size":65,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-12T14:27:39.079Z","etag":null,"topics":["ai-tools","automation","claude-code","developer-tools","python","slack-api","slack-bot","tmux"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sohei-t.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-25T04:48:42.000Z","updated_at":"2026-03-12T07:39:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sohei-t/slack-bridge-for-claude-code","commit_stats":null,"previous_names":["sohei-t/slack-bridge-for-claude-code"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sohei-t/slack-bridge-for-claude-code","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sohei-t%2Fslack-bridge-for-claude-code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sohei-t%2Fslack-bridge-for-claude-code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sohei-t%2Fslack-bridge-for-claude-code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sohei-t%2Fslack-bridge-for-claude-code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sohei-t","download_url":"https://codeload.github.com/sohei-t/slack-bridge-for-claude-code/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sohei-t%2Fslack-bridge-for-claude-code/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32487751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","automation","claude-code","developer-tools","python","slack-api","slack-bot","tmux"],"created_at":"2026-05-01T07:06:10.171Z","updated_at":"2026-05-01T07:06:11.694Z","avatar_url":"https://github.com/sohei-t.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![CI](https://github.com/sohei-t/slack-bridge-for-claude-code/actions/workflows/ci.yml/badge.svg)\n![Python 3.10+](https://img.shields.io/badge/Python-3.10+-3776AB?logo=python\u0026logoColor=white)\n![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)\n![Slack](https://img.shields.io/badge/Slack-Socket_Mode-4A154B?logo=slack\u0026logoColor=white)\n![tmux](https://img.shields.io/badge/tmux-terminal_multiplexer-1BB91F)\n\n# Slack Bridge for Claude Code\n\nA bidirectional integration tool that bridges [Slack](https://slack.com) and [Claude Code](https://docs.anthropic.com/en/docs/claude-code), letting you control Claude Code from your phone via Slack Bot DM. Receive real-time notifications when tasks complete or when Claude needs permission, and send instructions back -- all without touching your Mac.\n\n---\n\n## The Problem\n\nWhen Claude Code runs long tasks on your Mac, you have no way to know when it finishes unless you are sitting at your desk. If Claude needs permission to execute a command, it blocks until you physically walk over and type `y`. This tool eliminates that friction entirely.\n\n## The Solution\n\nSlack Bridge creates a two-way communication channel between your phone and Claude Code:\n\n- **Mac to Phone**: Automatic notifications for task completion and permission prompts\n- **Phone to Mac**: Send instructions, approve/deny permissions, and check status -- all from Slack DM\n\n---\n\n## Architecture\n\n```\n+--------------------------------------------------------------+\n|  Your Mac (always-on)                                        |\n|                                                              |\n|  +-----------------+       +---------------------------+     |\n|  | bot.py          |       | tmux sessions             |     |\n|  | (Socket Mode)   |------\u003e|  +---------------------+  |     |\n|  |                 |       |  | Claude Code (main)  |  |     |\n|  | Receives Slack  |       |  +---------------------+  |     |\n|  | messages and    |       |  | Claude Code (worker)|  |     |\n|  | button actions  |       |  +---------------------+  |     |\n|  +-----------------+       +-------------+-------------+     |\n|                                          |                   |\n|  +-----------------+                     |                   |\n|  | Hook Scripts    |\u003c--------------------+                   |\n|  |                 |  Claude Code events:                    |\n|  | slack-notify.sh |  - Stop (task complete)                 |\n|  | slack-notify-   |  - Notification (permission prompt)     |\n|  |   waiting.sh    |                                         |\n|  +-----------------+                                         |\n|          |                                                   |\n+----------|---------------------------------------------------+\n           | Slack API (HTTPS)\n           v\n+--------------------------------------------------------------+\n|  Slack API (api.slack.com)                                   |\n|  - Socket Mode WebSocket (bot.py \u003c-\u003e Slack)                  |\n|  - REST API (hook scripts -\u003e Slack)                          |\n+--------------------------------------------------------------+\n           ^\n           |\n+--------------------+\n|  Phone (Slack App) |\n|  - Notifications   |\n|  - Approve / Deny  |\n|  - Send commands   |\n+--------------------+\n```\n\n**Data flow summary:**\n\n| Path | Mechanism | Purpose |\n|------|-----------|---------|\n| Phone -\u003e Mac | Slack Socket Mode -\u003e `bot.py` -\u003e `tmux send-keys` | Send instructions to Claude Code |\n| Mac -\u003e Phone | Claude Code hook -\u003e `slack-notify.sh` -\u003e Slack REST API | Task completion notification |\n| Mac -\u003e Phone | Claude Code hook -\u003e `slack-notify-waiting.sh` -\u003e Slack REST API | Permission prompt with Approve/Deny buttons |\n| Phone -\u003e Mac | Slack Button Action -\u003e `bot.py` -\u003e `tmux send-keys` | One-tap approve (`y`) or deny (`n`) |\n\n---\n\n## Features\n\n### Bidirectional Communication\n\n| Direction | Feature | Details |\n|-----------|---------|---------|\n| Mac -\u003e Phone | Task completion notification | Claude's response summary + tmux screen capture |\n| Mac -\u003e Phone | Permission prompt notification | Prompt details + **Approve / Deny** buttons (Block Kit) |\n| Phone -\u003e Mac | Send instructions | Type in Slack DM, delivered to Claude Code via tmux |\n| Phone -\u003e Mac | Check status | `status` command shows current tmux screen content |\n| Phone -\u003e Mac | Multi-session support | `@session_name` mention or interactive session picker |\n\n### Notifications\n\n- **Task completion**: When Claude finishes a task, you receive a notification containing Claude's response summary and a tmux screen capture. No action buttons -- purely informational.\n- **Permission prompt**: When Claude needs approval (e.g., to run a shell command), you receive the prompt details with **Approve** and **Deny** buttons for one-tap response via Slack's Block Kit interactive components.\n\n### Multi-Session Support\n\nRun multiple Claude Code instances in separate tmux sessions and control them all from a single Slack DM:\n\n- **Auto-detection**: If only one tmux session exists, messages route automatically\n- **Session picker**: If multiple sessions exist, Block Kit buttons let you choose the target\n- **Direct mention**: `@worker1 run tests` sends directly to the `worker1` session\n- **Status overview**: `status` shows all sessions with their last output line\n\n### Security\n\n- **Allowed user filtering**: Only the configured Slack user ID can interact with the bot\n- **Unauthorized requests are silently ignored**: No information leakage to other users\n- **PID-based process management**: Prevents duplicate bot instances\n\n### Hook-Based Integration\n\nThe bridge uses Claude Code's native hook system -- no polling, no custom Claude Code modifications:\n\n- **Stop hook** (`slack-notify.sh`): Fires when Claude finishes a task\n- **Notification hook** (`slack-notify-waiting.sh`): Fires on permission prompts (matched by `permission_prompt`)\n\nBoth hooks run as background processes to avoid blocking Claude Code.\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- macOS (or Linux with tmux)\n- Python 3.10+\n- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed\n- A Slack workspace where you can create apps\n\n### Step 1: Install Dependencies\n\n```bash\npip3 install slack_bolt slack_sdk\nbrew install tmux  # if not already installed\n```\n\n### Step 2: Create a Slack App\n\n1. Go to [https://api.slack.com/apps](https://api.slack.com/apps) -\u003e **Create New App** -\u003e **From scratch**\n2. Name it (e.g., `Claude Code Bridge`) and select your workspace\n3. Enable **Socket Mode**:\n   - Navigate to **Basic Information** -\u003e **App-Level Tokens** -\u003e **Generate Token**\n   - Scope: `connections:write`\n   - Save the `xapp-...` token\n4. Add **Bot Token Scopes** under **OAuth \u0026 Permissions**:\n   - `chat:write` -- Send messages\n   - `im:history` -- Read DM history\n   - `im:write` -- Open DM channels\n   - `users:read` -- Read user info\n5. Enable **Event Subscriptions**:\n   - Subscribe to bot event: `message.im`\n6. **Install to Workspace**:\n   - Save the `xoxb-...` Bot User OAuth Token\n7. Find your **Slack User ID**:\n   - Click your profile in Slack -\u003e **...** -\u003e **Copy member ID**\n\n### Step 3: Configure Environment Variables\n\n```bash\ncp .env.example .env\n# Edit .env with your tokens and user ID\n```\n\nOr add to `~/.config/ai-agents/profiles/default.env`:\n\n```\nSLACK_NOTIFY_ENABLED=true\nSLACK_BOT_TOKEN=xoxb-your-bot-token\nSLACK_APP_TOKEN=xapp-your-app-token\nSLACK_ALLOWED_USER=U0000000000\nTMUX_SESSION_NAME=claude\n```\n\n### Step 4: Deploy Files\n\n```bash\n# Bot\nmkdir -p ~/.claude/slack-bot\ncp bot/bot.py ~/.claude/slack-bot/\n\n# Hook scripts\nmkdir -p ~/.claude/hooks\ncp hooks/slack-notify.sh ~/.claude/hooks/\ncp hooks/slack-notify-waiting.sh ~/.claude/hooks/\nchmod +x ~/.claude/hooks/slack-notify*.sh\n```\n\n### Step 5: Configure Claude Code Hooks\n\nAdd to `~/.claude/settings.json`:\n\n```json\n{\n  \"hooks\": {\n    \"Stop\": [\n      {\n        \"matcher\": \"\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"bash ~/.claude/hooks/slack-notify.sh\"\n          }\n        ]\n      }\n    ],\n    \"Notification\": [\n      {\n        \"matcher\": \"permission_prompt\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"bash ~/.claude/hooks/slack-notify-waiting.sh\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n\u003e **Note**: If you already have hooks configured, merge these entries into the existing arrays rather than overwriting.\n\n### Step 6: Start\n\n```bash\n# Start a tmux session with Claude Code\ntmux new -s claude\n# Inside tmux, run: claude\n\n# In a separate terminal, start the bot\ncd ~/.claude/slack-bot \u0026\u0026 nohup python3 bot.py \u003e\u003e bot.log 2\u003e\u00261 \u0026\n```\n\n### Step 7: Verify\n\nSend a message to your bot's DM in Slack:\n\n- `status` -- See tmux screen content\n- `sessions` -- List all active tmux sessions\n- `hello` -- Sends \"hello\" to Claude Code\n\n---\n\n## Commands Reference\n\n| Command | Description | Example |\n|---------|-------------|---------|\n| `\u003cany text\u003e` | Send instruction to Claude Code (auto-routed) | `run the tests` |\n| `@session \u003ctext\u003e` | Send to a specific tmux session | `@worker1 deploy to staging` |\n| `status` | Show all sessions with last output line | `status` |\n| `status \u003csession\u003e` | Show full screen capture of a session | `status worker1` |\n| `sessions` | List all active tmux sessions | `sessions` |\n| `ls` | Alias for `sessions` | `ls` |\n| `y` / `n` | Approve or deny (auto-routed) | `y` |\n| `cc: \u003ctext\u003e` | Same as `\u003ctext\u003e` (`cc:` prefix is optional) | `cc: fix the bug` |\n\n### Interactive Elements\n\n| Element | When It Appears | Action |\n|---------|-----------------|--------|\n| **Approve** button | Permission prompt notification | Sends `y` to the correct tmux session |\n| **Deny** button | Permission prompt notification | Sends `n` to the correct tmux session |\n| **Session picker** buttons | Multiple tmux sessions active | Routes your message to the selected session |\n\n---\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Required | Description | Example |\n|----------|----------|-------------|---------|\n| `SLACK_NOTIFY_ENABLED` | Yes | Enable/disable notifications | `true` |\n| `SLACK_BOT_TOKEN` | Yes | Bot User OAuth Token from Slack | `xoxb-...` |\n| `SLACK_APP_TOKEN` | Yes | App-Level Token for Socket Mode | `xapp-...` |\n| `SLACK_ALLOWED_USER` | Yes | Your Slack User ID (security filter) | `U0123456789` |\n| `TMUX_SESSION_NAME` | No | Default tmux session name | `claude` (default) |\n\n### Configuration File Location\n\nThe bot reads environment variables from `~/.config/ai-agents/profiles/default.env`. Alternatively, you can use a `.env` file in the project directory.\n\n---\n\n## Auto-Start with `tcc`\n\nAdd the following to your `~/.zshrc` to automatically start the Slack bot and Claude Code together:\n\n```bash\n# Slack Bot auto-start (kill existing -\u003e restart)\n_start_slack_bot() {\n  pkill -f \"slack-bot/bot.py\" 2\u003e/dev/null\n  sleep 1\n  cd ~/.claude/slack-bot \u0026\u0026 nohup python3 bot.py \u003e\u003e bot.log 2\u003e\u00261 \u0026\n  cd - \u003e /dev/null\n}\n\n# tmux + Claude Code + Slack Bot\ntcc() {\n  _start_slack_bot\n  local name=\"${1:-$(basename \"$PWD\")}\"\n  name=$(echo \"$name\" | tr -c 'a-zA-Z0-9_-' '-' | sed 's/^-\\+//;s/-\\+$//;s/-\\{2,\\}/-/g')\n  if [ -z \"$name\" ] || [ \"${#name}\" -le 1 ]; then\n    echo \"Could not derive session name from: $(basename \"$PWD\")\"\n    printf \"Enter session name: \"\n    read name\n    [ -z \"$name\" ] \u0026\u0026 echo \"Cancelled\" \u0026\u0026 return 1\n    name=$(echo \"$name\" | tr -c 'a-zA-Z0-9_-' '-' | sed 's/^-\\+//;s/-\\+$//;s/-\\{2,\\}/-/g')\n  fi\n  if tmux has-session -t \"$name\" 2\u003e/dev/null; then\n    tmux attach -t \"$name\"\n  else\n    tmux new-session -d -s \"$name\" -c \"$PWD\"\n    tmux send-keys -t \"$name\" \"claude\" Enter\n    tmux attach -t \"$name\"\n  fi\n}\n\n# Reattach to existing session (does NOT restart bot)\natcc() {\n  local name=\"${1:-claude}\"\n  tmux attach -t \"$name\" 2\u003e/dev/null || echo \"Session '$name' not found. Start with tcc.\"\n}\n```\n\nThe bot process is fully independent from tmux sessions. Restarting it has zero impact on running Claude Code instances.\n\n---\n\n## Multi-Session Usage\n\n```bash\n# Terminal 1: main session\ntcc main-project\n\n# Terminal 2: worker session\ntcc worker1\n\n# From Slack:\n# \"run tests\"             -\u003e session picker buttons appear\n# \"@worker1 run tests\"    -\u003e sends directly to worker1\n# \"status\"                -\u003e shows both sessions with last output\n```\n\n---\n\n## Deployment Modes\n\n### Direct Deployment (Recommended)\n\nCopy files manually as described in the [Quick Start](#quick-start) section. This gives you full control over file placement and configuration.\n\n```\n~/.claude/\n  slack-bot/\n    bot.py              # Slack bot (Socket Mode)\n  hooks/\n    slack-notify.sh     # Task completion hook\n    slack-notify-waiting.sh  # Permission prompt hook\n```\n\n### Skill Deployment (Optional)\n\nIf you use Claude Code's Agent Skills feature, deploy as a skill for management via slash commands:\n\n```bash\nmkdir -p ~/.claude/skills/slack-bridge/hooks\ncp skill/SKILL.md ~/.claude/skills/slack-bridge/\ncp skill/bot.py ~/.claude/skills/slack-bridge/\ncp skill/hooks/slack-notify.sh ~/.claude/skills/slack-bridge/hooks/\ncp skill/hooks/slack-notify-waiting.sh ~/.claude/skills/slack-bridge/hooks/\n```\n\nSkill commands:\n\n| Command | Description |\n|---------|-------------|\n| `/slack-bridge setup` | Guided first-time setup |\n| `/slack-bridge start` | Start the bot |\n| `/slack-bridge stop` | Stop the bot |\n| `/slack-bridge status` | Check all components |\n\n---\n\n## How It Works\n\n### Bot (`bot.py`)\n\nThe bot bridges two interfaces:\n\n- **Slack API** via Socket Mode -- receives messages and button actions from your phone in real time\n- **tmux CLI** via `send-keys` / `capture-pane` -- injects text into Claude Code and reads screen output\n\ntmux provides the critical capability that regular terminals lack: **external I/O access**. `send-keys` injects input as if typed on the keyboard, while `capture-pane` reads the current screen contents.\n\n### Hook Scripts\n\nHook scripts are triggered automatically by Claude Code's event system:\n\n1. **Stop event** (`slack-notify.sh`):\n   - Reads the hook payload from stdin (JSON with `cwd`, `last_assistant_message`)\n   - Auto-detects the current tmux session name\n   - Captures the tmux pane content (last 20 lines)\n   - Sends a Block Kit notification to your Slack DM with Claude's response summary and screen capture\n\n2. **Notification event** (`slack-notify-waiting.sh`):\n   - Reads the hook payload from stdin (JSON with `cwd`, `message`)\n   - Captures the tmux pane to show the actual permission prompt\n   - Sends a Block Kit notification with **Approve** and **Deny** buttons\n   - Button values include the tmux session name, ensuring actions route to the correct session\n\n### Button Actions\n\nWhen you tap **Approve** or **Deny** in Slack, the bot receives the action via Socket Mode and sends `y` or `n` to the correct tmux session. The session name is embedded in the button value, making multi-session approval reliable.\n\n### PID-Based Process Management\n\nThe bot writes its PID to `~/.claude/slack-bot/bot.pid` on startup. If a previous instance is running, it is terminated before the new instance starts. This prevents duplicate bot processes.\n\n---\n\n## Project Structure\n\n```\nslack-bridge-for-claude-code/\n  bot/\n    bot.py                  # Main bot (Socket Mode + tmux integration)\n    requirements.txt        # Python dependencies\n  hooks/\n    slack-notify.sh         # Stop hook (task completion notification)\n    slack-notify-waiting.sh # Notification hook (permission prompt)\n  skill/\n    SKILL.md                # Claude Code Agent Skill definition\n    bot.py                  # Bot copy for skill deployment\n    hooks/\n      slack-notify.sh\n      slack-notify-waiting.sh\n  tests/\n    conftest.py             # Shared pytest fixtures\n    test_bot.py             # Comprehensive test suite\n  .github/\n    workflows/\n      ci.yml                # GitHub Actions CI (flake8, mypy, pytest)\n  .env.example              # Environment variable template\n  pyproject.toml            # Project metadata and tool configuration\n  LICENSE                   # MIT License\n```\n\n---\n\n## Testing\n\nThe project includes a comprehensive test suite covering tmux helpers, message parsing, authorization, and Slack event handler behavior.\n\n```bash\n# Install dev dependencies\npip install pytest flake8 mypy slack-bolt slack-sdk\n\n# Run tests\npytest tests/ -v\n\n# Run linting\nflake8 bot/ --max-line-length=120\n\n# Run type checking\nmypy bot/ --ignore-missing-imports\n```\n\n### CI/CD\n\nGitHub Actions runs on every push and pull request to `main`:\n\n- **flake8** -- Code style and linting\n- **mypy** -- Static type checking\n- **pytest** -- Unit tests\n\n---\n\n## Requirements\n\n- macOS or Linux with tmux\n- Python 3.10+\n- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (MAX subscription recommended)\n- A Slack workspace where you can create apps\n\n---\n\n## Contributing\n\nContributions are welcome. To get started:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/my-feature`)\n3. Make your changes and ensure all tests pass (`pytest tests/ -v`)\n4. Run linting and type checks (`flake8 bot/` and `mypy bot/`)\n5. Commit your changes and open a pull request\n\nPlease follow the existing code style and include tests for new functionality.\n\n---\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\nCopyright (c) 2025 sohei-t\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsohei-t%2Fslack-bridge-for-claude-code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsohei-t%2Fslack-bridge-for-claude-code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsohei-t%2Fslack-bridge-for-claude-code/lists"}