Claude Code Channelsで外部からセッションにイベントをプッシュする
Claude Code v2.1.80からresearch previewとして「Channels」が導入された。MCPサーバーを通じて、実行中のClaude Codeセッションに外部からリアルタイムにメッセージをプッシュする機能だ。対応プラットフォームはTelegramとDiscord(ファーストパーティプラグイン提供)、あとlocalhost上で動作するデモ用のfakechat。
自分はかなチャットでtmuxブリッジを使って似たことをやっていた。iPhoneからTailscale経由でFastAPIに接続し、tmux send-keysでClaude Codeセッションにメッセージを注入、tmuxペインキャプチャで応答を読み取る方式だ。Channelsはこの「外部→セッションへのメッセージ注入」をMCPプロトコルで公式に実現している。
ただし、かなチャットは2月の記事時点からさらに変わっている。tmuxブリッジによるリアルタイム中継は残しているが、定型タスクについてはジョブ指示ファイル方式に移行した。Markdownで書いた指示ファイルをClaude Codeに渡して実行させ、結果をファイルに書き出す。会話的なやりとりが不要なタスクでは、リアルタイム通信よりこのバッチ的なアプローチのほうが安定する。
Channelsが解決するのは「リアルタイムの双方向通信」で、バッチ的に指示ファイルを投げるほうが向いているタスクにはChannelsは不要だ。かなチャットが両方を使い分けているのもそういう理由。
動作モデル
チャンネルはMCPサーバーの一種で、Claude Codeセッションが起動しているあいだ、外部サービスからのメッセージを受け取ってセッション内にイベントとして挿入する。
flowchart LR
A[Telegram DM] --> B[Telegramボット]
B --> C[Channelプラグイン<br/>MCPサーバー]
C -->|イベントプッシュ| D[Claude Code<br/>セッション]
D --> E{Claudeが処理}
E -->|replyツール| C
C --> B
B --> A
双方向通信になっているのがポイントで、Claudeは受け取ったイベントを処理した後、チャンネルの reply ツールで返答を元のプラットフォームに送り返せる。ターミナル側では返信内容そのものは表示されず、ツール呼び出しと「sent」確認が表示される。
イベントが届くのはセッションが開いているあいだのみ。バックグラウンドで常時待機させるには、Claude Codeをバックグラウンドプロセスや永続ターミナル(tmux、screenなど)で動かす必要がある。
かなチャットのtmuxブリッジとの違いを整理するとこうなる。
| 項目 | Channels | tmuxブリッジ (かなチャット) |
|---|---|---|
| プロトコル | MCP (公式サポート) | tmux send-keys + ペインキャプチャ |
| メッセージ注入 | MCPイベントとしてセッションに挿入 | キー入力として直接注入 |
| 応答の取得 | replyツールで構造化された返答 | ターミナル出力のテキスト解析 |
| 認証 | ペアリング + 許可リスト | Tailscale VPN + アプリ層認証 |
| CLIバージョン依存 | MCP仕様に依存 | ターミナル表示のみ参照、内部変更に強い |
Channelsはプロトコルレベルで統合されているので、応答のパースが不要で信頼性が高い。tmuxブリッジは汎用性が強みで、Claude Code以外のCLI(Codex、Gemini CLI)にも同じ仕組みで接続できる。
セットアップ (Telegram)
Channelsの起動にはBunが必要。
bun --version # なければ bun.sh からインストール
Telegramの場合の手順は次のとおり。
- TelegramのBotFatherで
/newbotを実行してボットとトークンを取得 - Claude Codeセッション内でプラグインをインストール
/plugin install telegram@claude-plugins-official
- トークンを設定
/telegram:configure <token>
設定はプロジェクトの .claude/channels/telegram/.env に保存される。
- Channelsフラグつきで再起動
claude --channels plugin:telegram@claude-plugins-official
- ボットにTelegramからDMを送るとペアリングコードが返ってくる
/telegram:access pair <code>
/telegram:access policy allowlist
allowlist 設定で、登録済みのアカウントのみがメッセージを送れるようになる。
Discordも同様の流れで、Developer Portalでボットを作成→プラグインインストール→トークン設定→ペアリングという手順。
セキュリティモデル
外部からClaude Codeセッションにコマンドを送り込める仕組みなので、セキュリティ周りはかなり気を使っている。
プラグイン許可リスト
research previewの現状では、--channels に渡せるプラグインはAnthropic管理の許可リスト内に限定されている(claude-plugins-official リポジトリのもの)。自作チャンネルのテストには --dangerously-load-development-channels フラグが必要。
送信者の許可リスト
各チャンネルプラグインはペアリングで認証したIDのみを受け付け、未登録のメッセージはサイレントに破棄する。/telegram:access policy allowlist で明示的にロックダウンする手順はセットアップの必須ステップとして文書化されている。
セッション単位の有効化
.mcp.json にサーバーが記述されているだけではチャンネルとして機能しない。--channels フラグで明示的に指定した場合のみ有効になる。
権限プロンプト
既存の動作が維持される。Claudeが許可を求める操作に達した場合、セッションはローカルの承認待ちで一時停止する。無人実行には --dangerously-skip-permissions を使う選択肢があるが、信頼できる環境に限定すべきだ。
かなチャットのツール承認ゲートと同じ発想で、読み取り系は通しても書き込み・実行系は止めるのが基本。--dangerously-skip-permissions はかなチャットでいう全ツール自動approveに相当するので、よほどの理由がない限り使わないほうがいい。
Enterprise向け設定
| プランタイプ | デフォルト動作 |
|---|---|
| Pro/Max (組織なし) | Channels利用可能。ユーザーが --channels でオプトイン |
| Team/Enterprise | 管理者が明示的に有効化するまで無効 |
Team/Enterpriseでは、管理者が claude.ai → Admin settings → Claude Code → Channels から有効化するか、managed settingsで channelsEnabled: true を設定する必要がある。無効状態でもMCPサーバーは接続してツールは動作するが、チャンネルメッセージは届かない。
自作チャンネルの構築
Telegram・Discordプラグインのソースは anthropics/claude-plugins-official リポジトリで公開されており、Bunスクリプトとして実装されている。カスタムチャンネルを構築する場合はこれを参照する。
research preview段階なので --channels フラグの構文やプロトコル仕様は変わる可能性がある。フィードバックはClaude CodeのGitHub Issueへ。