-
Notifications
You must be signed in to change notification settings - Fork 20
feat: add Claude Code Channels support for real-time Slack messaging #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
marciogranzotto
wants to merge
25
commits into
slackapi:main
Choose a base branch
from
marciogranzotto:feat/channels-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
38f0488
docs: add design spec for Claude Code Channels support
marciogranzotto a8a5bf5
docs: address spec review feedback for channels design
marciogranzotto 67e979d
docs: add implementation plan for Slack channels support
marciogranzotto 892e14d
chore: initialize project with bun, bolt, mcp sdk, and zod
marciogranzotto 5738952
feat: add settings module with read/write and schema validation
marciogranzotto b67af46
feat: add gating module with allowlist and pairing flow
marciogranzotto 4d58042
feat: add MCP server module with tool definitions and permission relay
marciogranzotto 0d4cf0c
feat: add bridge module with event transformation and tool handling
marciogranzotto 49f59ff
fix: rewrite bridge module to match spec — notification format, permi…
marciogranzotto 7c40b29
feat: add Slack module with Socket Mode and event handlers
marciogranzotto 0eeba18
feat: add entry point and register channel server in .mcp.json
marciogranzotto 2797fc4
docs: add channel setup instructions to README
marciogranzotto 6b8f779
test: add end-to-end integration tests for channel flows
marciogranzotto e0c1c05
fix: address all code review findings
marciogranzotto 7fe6ee1
fix: handle conversations.join gracefully and add channels:join scope
marciogranzotto df990ee
feat: add interactive Approve/Deny buttons for permission relay
marciogranzotto d8925f8
docs: update CLAUDE.md, plugin.json, and messaging skill for channels
marciogranzotto b762219
chore: add .env to gitignore
marciogranzotto 2229830
chore: add node_modules to gitignore
marciogranzotto 45cf8b9
chore: trigger CLA check after signing agreement
marciogranzotto 31758f9
fix: address PR review comments
marciogranzotto a3cf06f
chore: remove development artifacts from docs/
marciogranzotto bd6036b
chore: migrate from bun to npm/tsx/vitest
marciogranzotto 790e1b9
test: migrate test files from bun:test to vitest
marciogranzotto 8323955
docs: clarify Channels is Claude Code-specific, remove bun references
marciogranzotto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,11 @@ | ||
| { | ||
| "name": "slack", | ||
| "description": "Slack integration for searching messages, sending communications, managing canvases, and more", | ||
| "description": "Slack integration for searching messages, sending communications, managing canvases, and real-time bidirectional messaging via Channels", | ||
| "version": "1.0.0", | ||
| "author": { | ||
| "name": "Slack", | ||
| "url": "https://slack.com" | ||
| }, | ||
| "homepage": "https://github.com/slackapi/slack-mcp-cursor-plugin", | ||
| "homepage": "https://github.com/slackapi/slack-mcp-plugin", | ||
| "license": "MIT" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,4 @@ | ||
| .claude/ | ||
| .env | ||
| node_modules/ | ||
| bun.lock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| # Slack App Setup for Channels | ||
|
|
||
| Step-by-step guide to create and configure the Slack app needed for the channel server. | ||
|
|
||
| ## 1. Create the App | ||
|
|
||
| 1. Go to [api.slack.com/apps](https://api.slack.com/apps) | ||
| 2. Click **Create New App** | ||
| 3. Choose **From scratch** | ||
| 4. Name it something like `Claude Code Channel` (or whatever you prefer) | ||
| 5. Select your workspace | ||
| 6. Click **Create App** | ||
|
|
||
| ## 2. Enable Socket Mode | ||
|
|
||
| 1. In the left sidebar, click **Socket Mode** | ||
| 2. Toggle **Enable Socket Mode** to ON | ||
| 3. You'll be prompted to create an App-Level Token: | ||
| - Name it `socket-mode` (or anything descriptive) | ||
| - Add the scope `connections:write` | ||
| - Click **Generate** | ||
| 4. **Copy the token** — it starts with `xapp-`. This is your `SLACK_APP_TOKEN`. Save it somewhere safe; you won't see it again. | ||
|
|
||
| ## 3. Add Bot Token Scopes | ||
|
|
||
| 1. In the left sidebar, click **OAuth & Permissions** | ||
| 2. Scroll down to **Scopes** > **Bot Token Scopes** | ||
| 3. Click **Add an OAuth Scope** and add each of these: | ||
|
|
||
| | Scope | Purpose | | ||
| |---|---| | ||
| | `chat:write` | Send messages and replies | | ||
| | `reactions:write` | Add emoji reactions | | ||
| | `channels:join` | Join public channels when asked to watch them | | ||
| | `channels:read` | Read channel info (names, members) | | ||
| | `channels:history` | Read messages in public channels the bot is in | | ||
| | `groups:read` | Read private channel info | | ||
| | `im:read` | Read DM channel info | | ||
| | `im:history` | Read DM messages sent to the bot | | ||
| | `users:read` | Look up user names and profiles | | ||
| | `app_mentions:read` | Receive @mention events | | ||
|
|
||
| ## 4. Subscribe to Events | ||
|
|
||
| 1. In the left sidebar, click **Event Subscriptions** | ||
| 2. Toggle **Enable Events** to ON | ||
| 3. Expand **Subscribe to bot events** | ||
| 4. Click **Add Bot User Event** and add each of these: | ||
|
|
||
| | Event | Purpose | | ||
| |---|---| | ||
| | `message.im` | DMs to the bot | | ||
| | `message.channels` | Messages in public channels the bot is in | | ||
| | `app_mention` | @mentions of the bot in any channel | | ||
| | `reaction_added` | Emoji reactions on messages | | ||
|
|
||
| 5. Click **Save Changes** at the bottom | ||
|
|
||
| ## 5. Enable the Messages Tab | ||
|
|
||
| This allows users to DM the bot — required for pairing and direct interaction. | ||
|
|
||
| 1. In the left sidebar, click **App Home** | ||
| 2. Scroll down to **Show Tabs** | ||
| 3. Check **Messages Tab** | ||
| 4. Make sure **"Allow users to send Slash commands and messages from the messages tab"** is checked | ||
|
|
||
| ## 6. Enable Interactivity | ||
|
|
||
| Required for the permission relay buttons (Approve/Deny). | ||
|
|
||
| 1. In the left sidebar, click **Interactivity & Shortcuts** | ||
| 2. Toggle **Interactivity** to ON | ||
| 3. With Socket Mode enabled, no Request URL is needed — Bolt handles it automatically | ||
| 4. Click **Save Changes** | ||
|
|
||
| ## 7. Install the App to Your Workspace | ||
|
|
||
| 1. In the left sidebar, click **Install App** | ||
| 2. Click **Install to Workspace** | ||
| 3. Review the permissions and click **Allow** | ||
| 4. **Copy the Bot User OAuth Token** — it starts with `xoxb-`. This is your `SLACK_BOT_TOKEN`. | ||
|
|
||
| ## 8. Configure the Channel Server | ||
|
|
||
| Add your tokens to `.mcp.json`: | ||
|
|
||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "slack": { | ||
| "type": "http", | ||
| "url": "https://mcp.slack.com/mcp", | ||
| "oauth": { | ||
| "clientId": "1601185624273.8899143856786", | ||
| "callbackPort": 3118 | ||
| } | ||
| }, | ||
| "slack-channel": { | ||
| "command": "npx", | ||
| "args": ["tsx", "./src/index.ts"], | ||
| "env": { | ||
| "SLACK_BOT_TOKEN": "xoxb-your-token-here", | ||
| "SLACK_APP_TOKEN": "xapp-your-token-here" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## 9. Test Standalone (Without Claude Code) | ||
|
|
||
| Run the server directly to verify the Slack connection works: | ||
|
|
||
| ```bash | ||
| SLACK_BOT_TOKEN=xoxb-... SLACK_APP_TOKEN=xapp-... npx tsx src/index.ts | ||
| ``` | ||
|
|
||
| Expected output on stderr: | ||
| ``` | ||
| [slack-channel] connected to Slack as your-bot-name (U...) | ||
| [slack-channel] bootstrap mode: DM the bot to start pairing | ||
| [slack-channel] ready | ||
| ``` | ||
|
|
||
| If you see `ready`, the Slack connection is working. Press Ctrl+C to stop. | ||
|
|
||
| **Troubleshooting:** | ||
| - `SLACK_BOT_TOKEN is missing or invalid` — Check the token starts with `xoxb-` | ||
| - `SLACK_APP_TOKEN is missing or invalid` — Check the token starts with `xapp-` | ||
| - Connection hangs — Verify Socket Mode is enabled in the Slack app settings | ||
| - `not_authed` error — Reinstall the app to your workspace (step 5) | ||
|
|
||
| ## 10. Test with Claude Code | ||
|
|
||
| ```bash | ||
| claude --dangerously-load-development-channels server:slack-channel | ||
| ``` | ||
|
|
||
| Then in Slack: | ||
| 1. DM the bot — you should see a pairing code as an ephemeral message | ||
| 2. Reply `pair <CODE>` — you should see "Paired successfully" | ||
| 3. Send a message — Claude should receive it and can reply | ||
|
|
||
| ## 11. Invite the Bot to Channels (Optional) | ||
|
|
||
| The bot only receives messages in channels it's been invited to. To monitor a channel: | ||
|
|
||
| 1. Go to the channel in Slack | ||
| 2. Type `/invite @Claude Code Channel` (or whatever you named the bot) | ||
| 3. Or ask Claude to watch it: "start watching #channel-name" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, version needs to be bumped after merging