Channels reference
Blog

Channels reference

2026.03.22
ยทWebยทby ์„ฑ์‚ฐ/๋ถ€์‚ฐ/์žก๋ถ€
#Claude Code#MCP#Node.js#Server#Webhook

Key Points

  • 1Channels are MCP servers that integrate external events like webhooks, alerts, and chat messages into a Claude Code session, enabling Claude to react to real-world occurrences.
  • 2Operating as a subprocess, a channel communicates with Claude Code via stdio, declares a `claude/channel` capability, and pushes events using `notifications/claude/channel` with detailed metadata.
  • 3Building a channel involves defining its capabilities and instructions, exposing reply tools for two-way communication, and critically, implementing sender gating to prevent prompt injection.

A Claude Code channel is an [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server designed to push external events, such as webhooks, alerts, or chat messages, into a Claude Code session, enabling Claude to react to real-world occurrences. Implemented using the @modelcontextprotocol/sdk, channels leverage Node.js-compatible runtimes (Bun, Node, Deno) and communicate with Claude Code via stdio transport. Claude Code spawns the channel server as a subprocess, establishing a bridge between external systems and the AI session.

The core methodology for building a channel involves three primary technical steps:

  1. Capability Declaration: The channel server instantiates an MCP.Server object, declaring the capabilities.experimental['claude/channel'] property as an empty object ({}), which signals to Claude Code that it should register a notification listener for this channel. Additionally, an instructions string is provided in the Server constructor, which is appended to Claude's system prompt, guiding Claude on how to interpret incoming events, what attributes to expect on the <channel><channel> tag, and whether a reply is expected. For two-way channels, capabilities.tools must also be declared to enable tool discovery.

The server initialization broadly follows:

typescriptimport { Server } from '@modelcontextprotocol/sdk/server/index.js'; const mcp = new Server( { name: 'your-channel', version: '0.0.1' }, { capabilities: { experimental: { 'claude/channel': {} }, // For channel registration tools: {}, // For two-way communication to expose reply tools }, instructions: 'Messages arrive as <channel source="your-channel" ...>. Reply with the reply tool.', }, );

  1. Event Emission: When an external event occurs (e.g., an incoming HTTP request for a webhook channel), the channel server emits a notification event to Claude Code using mcp.notification(). The method for these events is notifications/claude/channel, and its parameters consist of:
    • content: A string representing the main body of the event, which becomes the inner text of the <channel><channel> tag in Claude's context.
    • meta: An optional Record<string,string>Record<string, string> containing key-value pairs. Each entry in meta is translated into an attribute on the <channel><channel> tag. For instance, meta: { severity: 'high', run_id: '1234' } would result in attributes like severity="high"severity="high" and runid="1234"run_id="1234". The source attribute is automatically derived from the channel server's configured name.

The event payload structure is:

json{ "method": "notifications/claude/channel", "params": { "content": "The main event body.", "meta": { "key1": "value1", "key2": "value2" } } }

This translates into Claude's context as:
xml<channel source="your-channel" key1="value1" key2="value2">The main event body.</channel>

  1. Reply Tool Exposure (for Two-Way Channels): To enable Claude to send messages back, two-way channels must expose standard MCP tools. This involves:
    • Tool Discovery: Registering a ListToolsRequestSchema handler that returns a list of available tools, detailing their name, description, and inputSchema (e.g., for a reply tool, chat_id and text arguments).
    • Tool Invocation: Registering a CallToolRequestSchema handler that defines the logic for invoking the declared tool. When Claude calls the reply tool, this handler receives the chat_id and text arguments and uses the channel's specific platform API to send the message.
    • The instructions string must be updated to inform Claude how and when to use the reply tool, including how to extract necessary parameters (like chat_id) from incoming <channel><channel> tags.

A crucial security consideration is sender gating to prevent prompt injection. Channels should implement an allowlist check for incoming messages, dropping any message from an unapproved sender before calling mcp.notification(), gating on the sender's identity (message.from.id) rather than the chat or room identity.

For local testing during the research preview, channels require the --dangerously-load-development-channels flag with claude CLI. Channels can be packaged as MCP plugins and published to marketplaces for shareability and installability via /plugin install.