Skip to content
Open
Show file tree
Hide file tree
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 Mar 26, 2026
a8a5bf5
docs: address spec review feedback for channels design
marciogranzotto Mar 26, 2026
67e979d
docs: add implementation plan for Slack channels support
marciogranzotto Mar 26, 2026
892e14d
chore: initialize project with bun, bolt, mcp sdk, and zod
marciogranzotto Mar 27, 2026
5738952
feat: add settings module with read/write and schema validation
marciogranzotto Mar 27, 2026
b67af46
feat: add gating module with allowlist and pairing flow
marciogranzotto Mar 27, 2026
4d58042
feat: add MCP server module with tool definitions and permission relay
marciogranzotto Mar 27, 2026
0d4cf0c
feat: add bridge module with event transformation and tool handling
marciogranzotto Mar 27, 2026
49f59ff
fix: rewrite bridge module to match spec — notification format, permi…
marciogranzotto Mar 27, 2026
7c40b29
feat: add Slack module with Socket Mode and event handlers
marciogranzotto Mar 27, 2026
0eeba18
feat: add entry point and register channel server in .mcp.json
marciogranzotto Mar 27, 2026
2797fc4
docs: add channel setup instructions to README
marciogranzotto Mar 27, 2026
6b8f779
test: add end-to-end integration tests for channel flows
marciogranzotto Mar 27, 2026
e0c1c05
fix: address all code review findings
marciogranzotto Mar 27, 2026
7fe6ee1
fix: handle conversations.join gracefully and add channels:join scope
marciogranzotto Mar 27, 2026
df990ee
feat: add interactive Approve/Deny buttons for permission relay
marciogranzotto Mar 27, 2026
d8925f8
docs: update CLAUDE.md, plugin.json, and messaging skill for channels
marciogranzotto Mar 27, 2026
b762219
chore: add .env to gitignore
marciogranzotto Mar 27, 2026
2229830
chore: add node_modules to gitignore
marciogranzotto Mar 27, 2026
45cf8b9
chore: trigger CLA check after signing agreement
marciogranzotto Mar 27, 2026
31758f9
fix: address PR review comments
marciogranzotto Mar 27, 2026
a3cf06f
chore: remove development artifacts from docs/
marciogranzotto Apr 1, 2026
bd6036b
chore: migrate from bun to npm/tsx/vitest
marciogranzotto Apr 2, 2026
790e1b9
test: migrate test files from bun:test to vitest
marciogranzotto Apr 2, 2026
8323955
docs: clarify Channels is Claude Code-specific, remove bun references
marciogranzotto Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/plugin.json
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",

Copy link
Copy Markdown
Author

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

"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"
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.claude/
.env
node_modules/
bun.lock
8 changes: 8 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
"clientId": "1601185624273.8899143856786",
"callbackPort": 3118
}
},
"slack-channel": {
"command": "npx",
"args": ["tsx", "./src/index.ts"],
"env": {
"SLACK_BOT_TOKEN": "",
"SLACK_APP_TOKEN": ""
}
}
}
}
27 changes: 26 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Slack Plugin

This plugin integrates Slack with Claude Code, providing tools to search, read, and send messages in Slack.
This plugin integrates Slack with Claude Code, providing tools to search, read, and send messages in Slack. It also includes a **channel server** for real-time bidirectional Slack messaging via Socket Mode.

## Commands

Expand All @@ -14,3 +14,28 @@ This plugin integrates Slack with Claude Code, providing tools to search, read,

- **slack-messaging** — Guidance for composing well-formatted Slack messages using standard markdown
- **slack-search** — Guidance for effectively searching Slack to find messages, files, channels, and people

## Channel Server (Research Preview)

The `slack-channel` MCP server enables real-time Slack messaging as a Claude Code Channel. It runs as a local subprocess using Socket Mode — no public URL needed.

### Tools

- **reply** — Send a message to a Slack channel or thread (`channel_id`, `text`, optional `thread_ts`)
- **react** — Add an emoji reaction to a message (`channel_id`, `timestamp`, `emoji`)
- **manage_access** — Add, remove, or pair users in the access allowlist (`action`: `add_user` / `remove_user` / `pair_user`, `value`: Slack user ID)
- **manage_channels** — Watch or unwatch channels (`action`: `watch` / `unwatch`, `channel_id`)

### Setup

Requires a Slack app with Socket Mode and two tokens:
- `SLACK_BOT_TOKEN` (`xoxb-...`) — Bot User OAuth Token
- `SLACK_APP_TOKEN` (`xapp-...`) — App-Level Token for Socket Mode

See `docs/slack-app-setup.md` for detailed Slack app creation instructions.

### Running

```
claude --dangerously-load-development-channels server:slack-channel
```
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,82 @@ Add the following configuration to connect to the remote Slack MCP server:

Save the configuration. You will also see a connect button once added. Click that to authenticate into your Slack Workspace.

## Channels for Claude Code (Research Preview)

The Channels feature lets Claude Code receive and respond to messages directly in Slack—via DMs or channel mentions—using a locally-run bot server.

### Slack App Setup

1. Create a new Slack app at [api.slack.com/apps](https://api.slack.com/apps) and select **Socket Mode**.
2. Under **OAuth & Permissions**, add the following bot token scopes:
- `chat:write`, `reactions:write`
- `channels:join`, `channels:read`, `channels:history`
- `groups:read`, `im:read`, `im:history`
- `users:read`, `app_mentions:read`
3. Under **Socket Mode**, enable it and generate an **App-Level Token** with the `connections:write` scope. This token begins with `xapp-`.
4. Under **Event Subscriptions → Subscribe to bot events**, add:
- `message.im`, `message.channels`, `app_mention`, `reaction_added`
5. Install the app to your workspace and copy the **Bot User OAuth Token** (`xoxb-...`).

### Configuration

Add the `slack-channel` server entry to your `.mcp.json` alongside the existing `slack` remote server:

```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-bot-token",
"SLACK_APP_TOKEN": "xapp-your-app-token"
}
}
}
}
```
Comment thread
marciogranzotto marked this conversation as resolved.

Alternatively, set `SLACK_BOT_TOKEN` and `SLACK_APP_TOKEN` as environment variables.

To pre-configure which Slack users are allowed to interact with the bot, create `~/.slack-channel/settings.json`:

```json
{
"gating": {
"mode": "per-user",
"allowedUsers": ["U012AB3CD", "U098ZY7WX"]
},
"watchedChannels": []
}
```

### Running

Start Claude Code with the channel server enabled:

```
claude --dangerously-load-development-channels server:slack-channel
```

### Pairing

On the first run with an empty allowlist, DM the bot in Slack. It will reply with a pairing code. Send:

```
pair <CODE>
```

This completes pairing and adds you to the allowlist. Once paired, you can ask Claude to pair additional users on your behalf.

## Usage Examples

Once configured, you can interact with Slack through your AI assistant using natural language:
Expand Down
151 changes: 151 additions & 0 deletions docs/slack-app-setup.md
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"
Loading