Skip to main content
Glama
elys0912

claude-slack-channel

by elys0912

claude-slack-channel

Slack の DM をローカルで動いている Claude Code のセッションへ中継する MCP channel サーバー。 Slack から話しかけると、手元の claude.exe セッションが応答する。 返信・リアクション・実行許可の確認まで、Slack 側だけで完結する。

仕組み

Slack (DM)
   │  Socket Mode(WebSocket、外向きの穴あけ不要)
   ▼
claude-slack-channel(このリポジトリ / dist/src/main.js)
   │  MCP(標準入出力・experimental "channels" 機能)
   ▼
Claude Code(claude.exe、手元のセッション)
  • Slack 側の送受信は Socket Mode(Slack → サーバーへの Web hook 受信ではなく、サーバー側から WebSocket を張りに行く方式)なので、ポート開放やトンネルは不要。

  • このサーバーは MCP の channel サーバーとして Claude Code に読み込まれ、Slack のメッセージを Claude のセッションへ直接注入する。Claude からの返信・リアクション・メッセージ編集は reply / react / edit_message の3ツールとして Claude 側から呼び出される。

  • ファイル書き込みなどの実行許可(permission)が必要な操作は、通常ならローカルの確認ダイアログに 出るところを、Slack のボタンまたは yes xxxxx / no xxxxx の返信でも承認・拒否できる。

Related MCP server: Claude Code Slack Channel

必要なもの

  • Node.js 22.12 以上

  • Claude Code v2.1.234 以上(Slack 側での実行許可承認に必要)

  • Claude の Pro 以上のサブスクリプション

  • Slack ワークスペースの管理権限(アプリのインストールに必要)

セットアップ手順

1. 依存関係のインストールとビルド

好きな場所に clone してから(以下、clone 先を <repo> と書く):

git clone https://github.com/<owner>/claude-slack-channel.git
cd claude-slack-channel
npm install
npm run build

dist/src/main.js が作られる。以後 scripts\start.cmd から起動できる。

2. Slack アプリを manifest から作る

api.slack.com/apps → Create New App → From an app manifest を選び、対象のワークスペースを選択してから、このリポジトリの slack-app-manifest.yaml の中身を 貼り付けて作成する。DM 専用・Socket Mode 有効・必要最小限のスコープ(chat:write / im:history / im:write / reactions:write)だけを持つアプリができる。

3. App-Level Token(connections:write)の発行

作成したアプリの Basic Information → App-Level Tokens から Generate Token and Scopes を選び、スコープに connections:write を追加してトークンを発行する。ここで発行される xapp- から始まるトークンが Socket Mode の接続に使う SLACK_APP_TOKEN。

4. ワークスペースへのインストールとスコープの確認

OAuth & Permissions → Install to Workspace でインストールする。完了すると xoxb- から始まる Bot User OAuth Token が発行される。これが SLACK_BOT_TOKEN。 Scopes の欄に manifest 通りの4つ(chat:write / im:history / im:write / reactions:write)が入っているか確認する。

5. 自分の member ID の調べ方

Slack のワークスペースで自分のプロフィールを開き、その他 メニューから メンバーIDをコピー を選ぶ(U から始まる ID)。この ID を access.json の allowFrom に入れる。ここに入っていない相手からの DM は無視される。

6. .env と access.json をメモ帳で作る

状態ディレクトリは既定で %USERPROFILE%\.claude\channels\slack(SLACK_CHANNEL_STATE_DIR 環境変数で変更可)。ここに次の2ファイルを作る。

%USERPROFILE%\.claude\channels\slack\.env(config\env.example の形式):

SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...

%USERPROFILE%\.claude\channels\slack\access.json(config\access.example.json の形式):

{
  "teamId": "T00000000",
  "allowFrom": ["U00000000"]
}

Claude に作らせない理由: この2ファイルはトークンと許可リストそのもので、Claude Code の プロジェクトディレクトリの外・状態ディレクトリに置く。Claude(このリポジトリの他のセッション 含む)にトークンを扱わせると、ログや会話履歴に混入する経路が増える。手で作り、Claude には 存在確認(中身は読まない)だけさせる設計にしている。

7. npm run check で確認する

npm run check

auth.test を呼び、ワークスペース名・team ID・ボットの user ID を表示する。access.json の allowFrom があれば、そこに書いた ID の表示名も引いて出す(失敗しても止まらない)。 access.json の teamId と実際の team_id が食い違っていれば警告が出る。 トークンそのものは画面に出ない(xoxb-*** のように接頭辞だけ表示する)。

8. 起動する

Windows Terminal から(VS Code 拡張の中の統合ターミナルでは動かない。理由は 権限の設計を参照):

まず config\projects.example.json を config\projects.json にコピーして、Claude Code を 起動したいプロジェクトを並べる(projects.json は各自の環境依存なので git 管理外):

{
  "projects": [
    { "name": "my-app", "path": "C:\\path\\to\\my-app" }
  ]
}

そのうえで起動する:

<repo>\scripts\start.cmd

projects.json のプロジェクトが番号付きで表示されるので、番号を入力して作業ディレクトリを 選ぶ(空 Enter で先頭、q で起動せずに終了)。

選択を飛ばして直接指定したい場合:

scripts\start.cmd -Project C:\path\to\project

起動のたびに全画面の警告ダイアログ(experimental channels の確認)が出るので、 「1」(I am using this for local development)を選ぶ。

使い方

Slack のアプリ一覧からこのボットに DM を送ると、手元のセッションに届く。返信は元のメッセージの スレッドに返る。ファイル編集など実行許可が必要な操作は、Slack にボタン付きメッセージが届くので ボタンで答えるか、yes xxxxx / no xxxxx(xxxxx は表示された5文字の ID、l を除く a-z のみ)で返信する。

セッションは1つで、Slack 側から複数の会話を並行して持てるわけではない。文脈は共有される。 Slack からは /clear できない(ローカルのターミナルで操作する必要がある)。

権限の設計

起動スクリプトは Claude Code を次のフラグで起動する。MCP 設定(slackbridge サーバーの定義)は clone 先の絶対パスを含むため、起動のたびに %TEMP%\claude-slack-channel\mcp.json へ生成する。

--mcp-config %TEMP%\claude-slack-channel\mcp.json
--setting-sources project,local
--settings config\channel-settings.json
--permission-mode default
--dangerously-load-development-channels server:slackbridge
  • --setting-sources project,local: ユーザー設定(~/.claude/settings.json)を 読み込まない。ユーザー設定には便利さのために緩い許可(Bash(*) や Write の無確認実行など) が入っていることが多く、Slack 経由で届く指示がそれに乗って無確認で実行されるのを防ぐ。

  • --settings config\channel-settings.json: channel セッション専用の許可リストを、 ユーザー・プロジェクト・ローカルのどの設定より上位に重ねて適用する。

config/channel-settings.json の内訳:

  • allow: Read / Glob / Grep(読み取り全般)、このサーバー自身の3ツール (reply / react / edit_message)、git status / git diff / git log (Bash・PowerShell 両方の形で登録。Windows では既定でどちらのツールが使われるか 環境依存のため)。

  • deny: 状態ディレクトリ(~/.claude/channels/**)そのものへの読み書き、 ~/.claude.json、~/.ssh/**、プロジェクト内の .env 系ファイル、 git push --force / -f、git reset --hard。

  • permissions.disableBypassPermissionsMode: "disable": bypassPermissions モードへの切り替えを禁止する。

  • disableClaudeAiConnectors: true: claude.ai 側の connector を取得しない。

deny ルールは allow ルールより必ず優先される(Claude Code の評価順は deny → ask → allow)ので、 上の allow に Read を許可していても、deny に挙げたパスは読めない。

制限: Bash(git push --force:*) の deny は、sh -c 'git push --force ...' のような 間接呼び出しを塞がない(Claude Code のパターンマッチの既知の制限)。channel セッションの allow には Bash(*) が入っていないため sh -c 自体が確認待ちになるが、迂回が不可能なわけ ではない。

起動には Windows Terminal から claude.exe を直接叩く運用にしている。VS Code 拡張の中の 統合ターミナルでは、--dangerously-load-development-channels の起動時警告ダイアログや channels(experimental)の動作を確認できていない(docs/phase0.md のスパイクは素の ターミナルで検証したもの)ため、対象外にしている。

セキュリティ

  • 送信者の許可判定は Slack のユーザー ID(access.json の allowFrom)で行う。表示名や メールアドレスでは判定しない。

  • トークン(SLACK_BOT_TOKEN / SLACK_APP_TOKEN)は状態ディレクトリの .env だけに置く。 環境変数にも MCP 設定ファイルにも書かない。

  • Slack から届くメッセージは信頼できない入力として扱う。届いた指示をそのまま実行するかどうかは 上記の権限設計(deny 優先、ユーザー設定を読まない)で制限している。

トークンが漏れたときの手順

  1. api.slack.com でアプリを開き、Basic Information → App-Level Tokens から該当トークンを Revoke。

  2. OAuth & Permissions でボットトークンを失効させる(またはアプリを一度アンインストールして 再インストールし、新しいトークンを発行する)。

  3. %USERPROFILE%\.claude\channels\slack\.env を新しいトークンで書き直す。

  4. npm run check で疎通を確認してから、scripts\start.cmd で再起動する。

許可リストから外すときの手順

access.json の allowFrom から該当の member ID を削除して保存する。サーバーは起動中の ファイル内容までは自動で再読み込みしないため、反映するにはセッションを再起動する。

トラブルシューティング

  • ログ: %USERPROFILE%\.claude\channels\slack\logs\bridge.log。トークンはログ内で マスクされる(xoxb-*** 等)。

  • 二重起動: instance.lock により多重起動は検知される。別インスタンスが動いている場合、 新しいプロセスは Slack には接続せず MCP サーバーのみを縮退モードで起動する (ツール呼び出しはエラーを返す)。

  • invalid_auth: SLACK_BOT_TOKEN が無効。npm run check で確認し、トークンを 取り直す。

  • missing_scope: OAuth スコープが不足している。OAuth & Permissions で slack-app-manifest.yaml 記載の4スコープが揃っているか確認し、揃っていなければ 再インストールする。

  • 再接続 / スリープで切れる: Socket Mode はスリープ復帰後に自動再接続を試みるが、 しばらく応答が無い場合はログを確認し、必要なら起動し直す。

  • 接続状態の確認: セッション内で /mcp を実行すると slackbridge の接続状態が見える。

  • 実機での動作確認手順やチェックリストは docs/phase0.md を参照 (echo channel を使ったスパイクの手順で、Slack を使わずに channels 機能自体の動作確認ができる)。

開発

npm test         # vitest(159件)
npm run typecheck # tsc --noEmit

ファイル構成

  • src/main.ts — エントリポイント。stateDir・ロック・トークン読み込み・Slack/MCP の配線

  • src/config.ts — stateDir・.env パーサー・access.json のスキーマ検証

  • src/slack.ts — Slack Socket Mode / Web API まわり

  • src/mcp.ts — MCP channel サーバー(reply / react / edit_message ツール)

  • src/gate.ts — 受信メッセージを中継すべきか判定する純関数群

  • src/permission.ts — 実行許可リレー(Slack のボタン・yes/no 返信)のロジック

  • src/format.ts — メッセージ整形(@here 等のブロードキャスト無害化など)

  • src/chunk.ts — 長文の分割送信

  • src/lock.ts — 単一インスタンス実行のファイルロック

  • src/log.ts — ログ出力(トークンのマスク込み)

  • src/stdio-guard.ts — stdout を MCP 専用に保つためのガード

  • src/types.ts — 共有型定義

  • scripts/check.ts — npm run check の実体。Slack への疎通確認

  • scripts/start.ps1 / start.cmd — 起動スクリプト(プロジェクト選択付き)

  • config/projects.json — 起動時に選べるプロジェクトの一覧(各自作成・git 管理外)

  • config/channel-settings.json — channel セッション専用の権限設定

  • config/projects.example.json — projects.json のひな形

  • config/access.example.json / config/env.example — access.json / .env のひな形

  • slack-app-manifest.yaml — Slack アプリの manifest

  • docs/phase0.md — channels 機能そのものの実機確認手順(スパイク)

ライセンス

MIT

Related MCP Connectors

Related MCP Servers