← Claude Code Hub
✦ Tip #088 Jun 1, 2026

Channels en Claude Code más allá del chat: que tu CI, deploy o errores entren como eventos en tu sesión

El uso conocido de Channels es el chat, pero en el fondo es un receptor de eventos: tu CI, Sentry o un deploy pueden empujar un webhook a la sesión de Claude Code que ya tienes abierta. Los plugins de chat vienen hechos; el receptor de webhooks lo montas con un MCP server de ~30 líneas.

Channels como receptor de eventos: un webhook de CI, Sentry o deploy entra en tu sesión de Claude Code ya abierta

TL;DR El uso conocido de Channels es el chat: le escribes desde Telegram y Claude responde. Pero un channel es, en el fondo, un receptor de eventos: cualquier sistema — tu CI, Sentry, un deploy, un curl — puede empujar un evento a la sesión que ya tienes abierta, con tus archivos cargados y el contexto de lo que estabas depurando. Los plugins de chat vienen hechos; el receptor de webhooks lo montas tú con un MCP server de ~30 líneas.

Si ya leíste cómo controlar Claude Code desde Telegram o Discord, conoces el lado chat-bridge: preguntas, Claude responde. Este tip va del otro lado del mismo motor: una máquina dispara el mensaje y Claude reacciona sin que escribas nada.

De pull a push

La diferencia es quién empieza la conversación:

  • Chat-bridge (lo conocido): tú haces pull. Le escribes "¿hay tests fallando?" y Claude mira.
  • Receptor de eventos (esto): el mundo te hace push. Tu CI falla → un webhook entra en tu sesión → Claude, que ya tenía el archivo abierto, lee el log y propone el fix.

Un channel puede ser de una vía (reenvía alertas o webhooks para que Claude actúe, sin responder) o de dos vías (además expone una herramienta de respuesta, como el chat). Para eventos de CI o monitorización, con una vía basta.

Cómo es un receptor de eventos

Los plugins de chat (Telegram, Discord, iMessage) vienen hechos. Para webhooks no hay plugin de un clic: montas un channel propio, que no es más que un MCP server mínimo. Esto es el receptor entero — escucha HTTP en local y empuja cada POST a Claude:

#!/usr/bin/env bun
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' },
  {
    // esta clave es lo que lo convierte en channel
    capabilities: { experimental: { 'claude/channel': {} } },
    instructions: 'Los eventos llegan como <channel source="webhook" ...>. Son de una vía: léelos y actúa.',
  },
)
await mcp.connect(new StdioServerTransport())

Bun.serve({
  port: 8788,
  hostname: '127.0.0.1', // solo localhost: nada de fuera puede POSTear
  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')
  },
})

Lo registras en .mcp.json y arrancas con el flag de desarrollo (los channels propios aún no están en la allowlist del research preview):

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

Ahora cualquier cosa que haga un POST entra en tu sesión. Simula un fallo de CI:

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

Y a Claude le llega esto, en mitad de tu sesión, con tus archivos ya abiertos:

<channel source="webhook" path="/" method="POST">build failed on main: https://ci.example.com/run/1234</channel>

El source sale del nombre del server; cada clave de meta se convierte en un atributo del tag.

Por qué importa: aterriza en la sesión que YA tienes abierta

Claude Code tiene varias formas de conectarse con el mundo fuera del terminal. Channels es el único que empuja un evento a tu sesión local viva:

Función Qué hace Por qué no es lo mismo
Claude Code on the web Lanza la tarea en un sandbox nuevo en la nube Sesión fresca, sin tu contexto local
Claude en Slack Crea una sesión web desde un @Claude Otra sesión nueva, no la tuya abierta
MCP normal Claude consulta el sistema cuando quiere Es pull: nada se empuja a la sesión
Remote Control Conduces tu sesión local desde el móvil Manual; tú actúas, no reacciona a un evento
Channels Empuja un evento externo a tu sesión abierta Claude reacciona con tu contexto y tus archivos

Ese es el valor: el webhook de CI no abre un clon nuevo del repo — llega donde Claude ya recuerda qué estabas depurando.

Bonus: aprueba permisos desde el móvil

Si reaccionas a eventos mientras no estás, ¿qué pasa cuando Claude necesita aprobar un Bash o un Write? Un channel de dos vías puede declarar la capability claude/channel/permission y reenviarte el prompt de permiso (requiere v2.1.81+). Te llega "Claude quiere ejecutar Bash: … responde sí/no" con un ID corto; respondes desde el chat y Claude aplica el veredicto. El diálogo local sigue abierto en paralelo: gana la primera respuesta que llegue. Actívalo solo si filtras al remitente — quien pueda responder, puede aprobar comandos en tu sesión.

Cuidado con

  • La sesión tiene que estar abierta. Channels no es un servicio persistente; si Claude Code no está corriendo (o tu organización lo bloquea), el evento se descarta en silencio, sin error.
  • Filtra al remitente. Un endpoint sin control es un vector de prompt injection: cualquiera que llegue a él mete texto delante de Claude. Comprueba la identidad de quien envía (no la sala o el grupo) antes de empujar nada.
  • Los eventos se encolan. Si llegan varios mientras Claude trabaja, se entregan juntos en el siguiente turno. Para flujos independientes en paralelo, usa sesiones separadas.

Referencia

Aspecto Detalle
Tipos Una vía (alertas/webhooks) · Dos vías (chat, con tool de respuesta)
Plugins hechos Telegram, Discord, iMessage, fakechat (todos de chat)
Webhook/CI Build-your-own: MCP server con capabilities.experimental['claude/channel']
Evento entrante <channel source="..." …>cuerpo</channel> (método notifications/claude/channel)
Permission relay Capability claude/channel/permission (v2.1.81+) — aprueba en remoto
Probar uno propio claude --dangerously-load-development-channels server:<nombre>
Runtime @modelcontextprotocol/sdk + Bun, Node o Deno
Seguridad Filtra por identidad del remitente; si no, prompt injection

Documentación oficial: Channels · Channels reference — build a webhook receiver

Relacionado: Controla Claude Code desde Telegram o Discord · el mapa de las primitivas autonomous

Guía gratuita

51 tips para dominar Claude Code.

Una página por tip. Cinco capítulos. Lo que de verdad uso a diario en producción — sin teoría, sin humo.

  • I. Empieza bien 10 tips
  • II. Conciencia 3 tips
  • III. Maestría 22 tips
  • IV. Autonomía 10 tips
  • V. Comparativa 6 tips
¿Eres desarrollador/a Web profesional?

Recibirás la guía por email · Te unes a la newsletter Gravitas · Cancela cuando quieras

de 51
#

Wmedia · 51 Tips
Guía gratuita · 51 tips · 5 capítulos

51 tips para dominar Claude Code.

¿Eres desarrollador/a Web profesional? · Cancela cuando quieras