Featured image of post Claude Code Channels ── MCPサーバーからセッションにイベントをプッシュする

Claude Code Channels ── MCPサーバーからセッションにイベントをプッシュする

2026年3月20日、Anthropicが「Claude Code Channels」をリサーチプレビューとして公開した。--channels フラグを付けてセッションを起動すると、MCPサーバーから Claude にイベントをプッシュできる。Telegram のメッセージでも CI の失敗通知でも、Claude がターミナルを離れずに拾う。

必要なバージョンは Claude Code v2.1.80 以降。API キー認証は非対応で、claude.ai アカウントでのログインが必要。

仕組み

チャネルは「特定の capability を持つ MCP サーバー」として実装される。Claude Code がサブプロセスとして起動し、stdio 経由で通信する。用途によって2通りのアプローチがある。

Telegram や Discord のようなチャットプラットフォームなら、プラグインがローカルでポーリングする。外部に URL を公開しなくてよい。CI や監視ツールからの通知には、ローカルの HTTP ポートで POST を受け取る Webhook 方式が合う。

どちらの場合も、イベントは <channel> タグとして Claude のコンテキストに届く:

<channel source="webhook" severity="high" run_id="1234">
build failed on main: https://ci.example.com/run/1234
</channel>

fakechat デモで動作を確認する

カスタム実装の前に、公式の fakechat デモで試せる:

1
2
3
4
5
# プラグインをインストール
/plugin install fakechat@claude-plugins-official

# チャネルを有効にして起動
claude --channels plugin:fakechat@claude-plugins-official

起動後、http://localhost:8787 からメッセージを送ると Claude が応答する。Telegram を用意しなくても、双方向チャネルの動作をひと通り確認できる。

Webhook チャネルを自分で作る

ファイル1つで動く。Bun を使った最小構成:

1
2
mkdir webhook-channel && cd webhook-channel
bun add @modelcontextprotocol/sdk
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env bun
// webhook.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

const mcp = new Server(
  { name: 'webhook', version: '0.0.1' },
  {
    // この capability の宣言がチャネル登録のトリガー
    capabilities: { experimental: { 'claude/channel': {} } },
    instructions: 'webhook チャネルからのイベントは <channel source="webhook" ...> で届く。一方向なので返信不要。',
  },
)

await mcp.connect(new StdioServerTransport())

Bun.serve({
  port: 8788,
  hostname: '127.0.0.1',  // ローカル限定
  async fetch(req) {
    const body = await req.text()
    await mcp.notification({
      method: 'notifications/claude/channel',
      params: {
        content: body,
        meta: { path: new URL(req.url).pathname, method: req.method },
      },
    })
    return new Response('ok')
  },
})

MCP の設定ファイルに登録する:

1
2
3
4
5
{
  "mcpServers": {
    "webhook": { "command": "bun", "args": ["./webhook.ts"] }
  }
}

自作チャネルはリサーチプレビュー期間中は許可リスト外なので、起動時に --dangerously-load-development-channels が要る:

1
claude --dangerously-load-development-channels server:webhook

あとは別ターミナルから POST を投げるだけ:

1
curl -X POST localhost:8788 -d "build failed on main: https://ci.example.com/run/1234"

双方向チャネル(返信ツール)

Telegram ブリッジのように Claude から返信したい場合は、MCP ツールを追加で定義する。capabilitiestools: {} を追加し、ListToolsRequestSchemaCallToolRequestSchema のハンドラーを登録すれば、Claude がそのツールを呼べる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [{
    name: 'reply',
    description: 'このチャネル経由でメッセージを返信する',
    inputSchema: {
      type: 'object',
      properties: {
        chat_id: { type: 'string' },
        text: { type: 'string' },
      },
      required: ['chat_id', 'text'],
    },
  }],
}))

セキュリティ:送信者の制限

ゲーティングなしで動かすと、エンドポイントに届いたテキストがそのまま Claude へのプロンプトになる。許可リストで送信者を確認してから mcp.notification() を呼ぶこと:

1
2
3
4
5
6
const allowed = new Set(loadAllowlist())

if (!allowed.has(message.from.id)) {  // ルーム ID ではなく送信者 ID で判定
  return  // サイレントに捨てる
}
await mcp.notification({ ... })

グループチャットでは chat.id(ルーム)ではなく from.id(送信者)で判定する。ルームで絞ると、そのルームに入れる人なら誰でも注入できてしまうから。

今の状況

試せるかどうかはアカウント次第で、動かなくても自分のせいではない可能性が高い。Anthropic がサーバーサイドで管理する tengu_harbor というフィーチャーフラグが false のアカウントでは「Channels are not currently available」と表示され、通知は届くが Claude が反応しない。GitHub にバグレポートが上がっていて、Anthropic 側での有効化待ち。

Team・Enterprise 組織は管理者が明示的にチャネル機能を有効化する必要がある。

参考

Next Action

おすすめリンク

この記事に合わせて、関連アイテムを探しやすいリンクをまとめています。

Affiliate Links

外部ストアへのアフィリエイトリンクです。気になるものだけ開けば十分です。

Hugo で構築されています。
テーマ StackJimmy によって設計されています。
B!