Source: Anthropic official docs — Channels + Anthropic official docs — Channels reference Type: Product Feature (research preview) Product: Claude Code Requires: Claude Code v2.1.80+ (channels), v2.1.81+ (permission relay), Anthropic authentication (claude.ai or Console API key)
A channel is an MCP server that pushes external events into a running Claude Code session over stdio, so Claude can react to things happening outside the terminal. Channels can be one-way (forward webhooks, alerts, monitoring events) or two-way (chat bridges that also expose a reply tool). A two-way channel with sender authentication can additionally relay permission prompts to a phone or other device. Team and Enterprise organizations must explicitly enable channels.
Auth update (W19, 2026-05-10):
--channelsnow works with Console API key authentication. Previously, channels required claude.ai login. The note “Console and API key authentication is not supported” has been removed from the official docs.
How channels compare with other Claude Code reach-outs
| Feature | What it does | Good for |
|---|---|---|
| Claude Code on the web | Runs in fresh cloud sandbox cloned from GitHub | Self-contained async work checked on later |
| Claude in Slack | Spawns web session from @Claude mention | Tasks starting from team conversation context |
| Standard MCP server | Claude pulls; nothing pushed | On-demand read/query of a system |
| Remote Control | Drive a local session from claude.ai or mobile | Steering an in-progress session while away from desk |
| Channels | External systems push events into your already-running local session | Webhooks, chat bridges, monitoring forwards |
Compared with loop polling, channels are reactive (event-driven) instead of timer-driven.
Built-in channel plugins
All four require Bun and are published as plugins under claude-plugins-official.
Telegram
- Create a bot via BotFather (
/newbot). /plugin install telegram@claude-plugins-official/reload-plugins/telegram:configure <token>— saves to~/.claude/channels/telegram/.env. (Or setTELEGRAM_BOT_TOKENin shell env.)- Restart with
claude --channels plugin:telegram@claude-plugins-official. - DM the bot. It replies with a pairing code.
/telegram:access pair <code>then/telegram:access policy allowlist.
Discord
- Discord Developer Portal → New Application → Bot → Reset Token.
- Enable Message Content Intent under Privileged Gateway Intents.
- OAuth2 URL Generator:
botscope + permissions (View Channels, Send Messages, Send Messages in Threads, Read Message History, Attach Files, Add Reactions). Open the URL to invite. /plugin install discord@claude-plugins-official, then/discord:configure <token>(orDISCORD_BOT_TOKEN).- Restart with
--channels plugin:discord@claude-plugins-official. - DM the bot, get pairing code, run
/discord:access pair <code>and/discord:access policy allowlist.
iMessage (macOS only)
Reads the Messages database directly; sends via AppleScript. No bot token, no external service.
- Grant Full Disk Access to your terminal (System Settings → Privacy & Security → Full Disk Access). Required to read
~/Library/Messages/chat.db. /plugin install imessage@claude-plugins-official.- Restart with
--channels plugin:imessage@claude-plugins-official. - Text yourself from any device on your Apple ID — self-chat bypasses access control.
- First reply triggers a macOS Automation prompt asking if your terminal can control Messages. Click OK.
- Allow other senders by handle:
/imessage:access allow +15551234567oruser@example.com.
fakechat (localhost demo)
A localhost browser UI for trying the channel pattern without a real platform.
/plugin install fakechat@claude-plugins-official.- Restart with
claude --channels plugin:fakechat@claude-plugins-official. - Open
http://localhost:8787and type — messages arrive in your session as<channel source="fakechat">events; Claude’s replies show up in the chat UI.
Building your own channel
A channel is an MCP server that runs over stdio (Claude Code spawns it as a subprocess). Three things are required:
- Declare
claude/channel: {}inexperimentalcapabilities — registers the notification listener. - Emit
notifications/claude/channelevents withcontent(string) andmeta(string→string map). - Connect over
StdioServerTransport.
const mcp = new Server(
{ name: 'webhook', version: '0.0.1' },
{
capabilities: { experimental: { 'claude/channel': {} } },
instructions: 'Events arrive as <channel source="webhook" ...>. One-way, no reply expected.',
},
)
await mcp.connect(new StdioServerTransport())Events arrive in Claude’s context as XML-like tags:
<channel source="your-channel" severity="high" run_id="1234">
build failed on main: https://ci.example.com/run/1234
</channel>Each meta key becomes a tag attribute. Keys must be [a-zA-Z0-9_] — hyphens or other characters are silently dropped.
Two-way channels (reply tool)
Add tools: {} to capabilities, register ListToolsRequestSchema + CallToolRequestSchema handlers for a tool like reply(chat_id, text). The instructions string tells Claude when to call it and which meta attribute (e.g., chat_id) to pass back.
Permission relay
A two-way authenticated channel can opt in to receive tool-approval prompts in parallel with the local terminal dialog. Add 'claude/channel/permission': {} to experimental capabilities.
When Claude calls a tool needing approval:
- Claude Code generates a 5-letter request ID (drawn from
[a-km-z]— nolto avoid confusion with1/Ion phones). - Notifies your server via
notifications/claude/channel/permission_requestwithrequest_id,tool_name,description,input_preview(JSON args truncated to 200 chars). - Your server forwards the prompt + ID to your chat app.
- The remote user replies (e.g.,
yes abcde/no abcde). - Your inbound handler parses, emits
notifications/claude/channel/permissionwithrequest_id+behavior: 'allow'|'deny'.
Local terminal dialog and remote prompt stay live in parallel. First answer wins; the other is dropped. Project-trust and MCP-consent dialogs do not relay — terminal-only.
Only declare permission relay if your channel authenticates the sender (see below). Anyone who can reply through the channel can approve or deny tool use in your session.
Sender gating (security)
Ungated channels are a prompt-injection vector. Anyone who can reach your endpoint can put text in front of Claude.
- Gate on sender identity, not chat/room ID — in group chats these differ, and gating on the room would let anyone in an allowlisted group inject messages.
- Telegram/Discord bootstrap the allowlist via pairing: user DMs the bot → bot returns code → user approves it in their session → sender ID added.
- iMessage detects the user’s own addresses from the Messages DB at startup and lets them through automatically; other senders are added by handle.
When Claude replies, you see the inbound message in your terminal but not the reply text — the terminal shows the tool call and sent confirmation; the actual reply lands on the other platform.
Enterprise controls
On Team and Enterprise plans, channels are off by default. Two managed settings (users cannot override):
| Setting | Purpose | Default |
|---|---|---|
channelsEnabled | Master switch. Must be true for any channel to deliver. Blocks all channels including dev flag when off. | Channels blocked |
allowedChannelPlugins | Replaces the Anthropic allowlist with your own. Each entry: { "marketplace": "...", "plugin": "..." }. Empty array blocks all. | Anthropic default list applies |
Pro and Max users without an organization skip these checks — channels are available; opt in per session with --channels.
Enable from claude.ai → Admin settings → Claude Code → Channels, or set channelsEnabled: true directly.
Research preview
--channelsaccepts only plugins on the Anthropic-maintained allowlist (or your org’sallowedChannelPluginsif set).- To test custom channels you’re building:
claude --dangerously-load-development-channels server:<name>orplugin:<name>@<marketplace>. Bypass is per-entry; combining with--channelsdoesn’t extend bypass to those entries. - Bypass skips the allowlist only — the
channelsEnabledpolicy still applies. - API surface and protocol contract may change based on feedback during the preview.
Permission prompts while you’re away
If Claude hits a permission prompt and you’re away from the terminal:
- A channel with permission relay can forward the prompt to you.
- For unattended use,
--dangerously-skip-permissionsbypasses prompts entirely. Use only in trusted environments.
Key Takeaways
- Channels = MCP servers that push events into a running Claude Code session, not pull.
- Telegram, Discord, iMessage, and fakechat ship as official plugins; build your own with the MCP SDK +
claude/channelcapability. - Sender gating on identity (not room) is mandatory — channels are a direct prompt-injection vector.
- Permission relay is opt-in (
claude/channel/permission) and requires authentication; first answer (terminal vs remote) wins. - Team/Enterprise off by default; admins enable via
channelsEnabledand optionally constrain viaallowedChannelPlugins. - Pairs cleanly with loop (timer-driven) and hooks (lifecycle-driven) — channels are the event-driven leg.
- Research preview — flag-gated, expect API changes.
Try It
- Fakechat in 30 seconds:
/plugin install fakechat@claude-plugins-official, restart withclaude --channels plugin:fakechat@claude-plugins-official, openhttp://localhost:8787, type “what’s in my working directory?” - Telegram bridge for a real workflow: create a bot with BotFather, install + configure as above. Useful pattern: ask “is the deploy still red?” from your phone while Claude has your repo open.
- iMessage if you’re on macOS: install plugin, grant Full Disk Access, text yourself. Self-chat is the lowest-friction smoke test of the entire channel system.
- Custom webhook receiver for CI: follow the channels-reference walkthrough — a single Bun file gives you
curl -X POST localhost:8788 -d "..."reaching Claude in seconds. - Add permission relay to a two-way channel only after you’ve gated senders — anyone who can reply can approve tools.
Related
- Claude Code Scheduled Tasks —
/loopand cron; the timer-driven counterpart to channels. - Claude Code Hooks — pairs with
permissionDecision: "defer"for remote approvals. - Claude Code Agent Teams — channels can push events to a team’s lead.
- Claude Code Plugins and Marketplaces — channels are distributed as plugins.
- Essential MCP Servers for 2026 — channels are a specialized MCP server pattern.
- Claude Managed Agents — for fully unattended cloud agents.
- Claude Code Routines — durable cloud scheduling, when polling beats pushing.
- Hermes Agent — local self-improving agent; precedent for the same pattern (Telegram bridge into a long-running session).
Open Questions
- What is the per-channel rate limit before Claude Code throttles or drops events?
- How does permission relay handle multiple simultaneous tool prompts — one ID per prompt, FIFO ordering, or interleaved?
- Will channels move out of research preview, and what is the migration path if the protocol contract changes?
- Can a single session connect to multiple channels of the same type (e.g., two Telegram bots)?