
Channels reference
핵심 포인트
- 1Claude Code의 Channels는 외부 시스템(예: 웹훅, 알림, 채팅 메시지)에서 발생하는 이벤트를 Claude 세션으로 푸시하여 Claude가 이에 반응하도록 돕는 MCP 서버입니다.
- 2Channels 서버를 구축하려면 `@modelcontextprotocol/sdk`를 사용하여 `claude/channel` capability를 선언하고, `notifications/claude/channel` 형식으로 이벤트를 전송해야 합니다.
- 3양방향 Channels는 Claude가 메시지를 다시 보낼 수 있도록 MCP tool을 노출하며, prompt injection을 막기 위해 수신 메시지에 대한 sender gating이 필수적입니다.
이 문서는 Claude Code 세션으로 웹훅(webhooks), 알림(alerts), 채팅 메시지 등을 푸시할 수 있는 MCP(Model Context Protocol) 서버인 '채널(Channels)'을 구축하는 방법을 설명합니다. 채널은 외부 시스템과 Claude Code 세션 사이의 브리지 역할을 하며, 현재 연구 미리보기(research preview) 단계에 있습니다.
핵심 개념 및 구조:
채널은 Claude Code와 동일한 머신에서 실행되는 MCP 서버입니다. Claude Code는 이 채널 서버를 서브프로세스(subprocess)로 스폰(spawn)하며, 표준 입출력(stdio)을 통해 통신합니다. 이는 외부 시스템(예: 채팅 플랫폼, CI/CD 파이프라인, 모니터링 시스템)에서 발생하는 이벤트를 Claude Code 세션으로 전달하는 역할을 합니다.
구현 방법론:
채널 서버를 구축하기 위해서는 @modelcontextprotocol/sdk 패키지와 Node.js 호환 런타임(Bun, Node, Deno)이 필요합니다. 핵심적인 구현 단계는 다음과 같습니다:
- 채널 기능 선언 (Capability Declaration):
Server constructor)를 생성할 때, capabilities.experimental['claude/channel'] 필드를 {}로 설정하여 이 서버가 채널임을 Claude Code에 알려야 합니다. 이는 Claude Code가 해당 서버의 알림(notification) 리스너(listener)를 등록하도록 합니다.
const mcp = new Server(
{ name: 'your-channel', version: '0.0.1' },
{
capabilities: {
experimental: { 'claude/channel': {} }, // 채널 리스너 등록
// 추가적으로 양방향 통신을 위해 tools: {} 선언
},
instructions: '...', // Claude에 대한 지침
},
);- 표준 I/O를 통한 연결 (Stdio Transport Connection):
StdioServerTransport를 사용하여 Claude Code와 표준 입출력 스트림을 통해 연결합니다. 이는 Claude Code가 서버를 서브프로세스로 실행할 때 자동으로 설정되는 통신 방식입니다.
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
await mcp.connect(new StdioServerTransport());- 알림 이벤트 발생 (Notification Event Emission):
mcp.notification() 메서드를 호출하여 이를 Claude Code 세션으로 푸시합니다. 이때 method는 'notifications/claude/channel'로 고정되며, params는 content와 meta 필드를 포함합니다.content: 이벤트의 본문(body)이며, Claude의 컨텍스트에서는 태그의 내용으로 전달됩니다.meta: 선택적 필드로, 타입입니다. 여기에 포함된 각 키-값 쌍은 태그의 속성(attribute)으로 변환되어, Claude가 이벤트를 라우팅하거나 처리하는 데 필요한 추가적인 컨텍스트(예:chat_id,severity)를 제공합니다. 키는 식별자 규칙(문자, 숫자, 밑줄만 허용)을 따라야 합니다.
예시:
await mcp.notification({
method: 'notifications/claude/channel',
params: {
content: 'build failed on main: https://ci.example.com/run/1234',
meta: { severity: 'high', run_id: '1234' },
},
});Claude 세션에 전달되는 형식:
<channel source="your-channel" severity="high" run_id="1234">
build failed on main: https://ci.example.com/run/1234
</channel>여기서
source 속성은 서버의 설정된 이름(Server constructor의 name 필드)으로부터 자동으로 설정됩니다.- Claude에 대한 지침 (Instructions):
Server constructor의 instructions 필드는 Claude의 시스템 프롬프트(system prompt)에 추가될 텍스트를 제공합니다. 이 지침은 Claude에게 어떤 종류의 이벤트가 도착할지, 태그의 속성들이 무엇을 의미하는지, 그리고 응답해야 하는 경우 어떤 도구(tool)를 사용하고 어떤 속성(예: chat_id)을 전달해야 하는지에 대한 정보를 알려줍니다.- 양방향 통신 및 응답 도구 (Two-way Communication & Reply Tools):
capabilities.tools: {}를Serverconstructor에 추가하여 도구 발견(tool discovery)을 활성화합니다.ListToolsRequestSchema핸들러를 구현하여 Claude에게 제공하는 도구의 목록과 스키마(schema)를 정의합니다. (예:reply도구에chat_id와text입력 필드 정의).CallToolRequestSchema핸들러를 구현하여 Claude가 해당 도구를 호출했을 때 실제로 메시지를 보내는 로직(예: 외부 플랫폼의 전송 API 호출)을 처리합니다.instructions를 업데이트하여 Claude가 적절한 상황에서 이 도구를 사용하도록 안내합니다.
- 인바운드 메시지 게이트(Gate Inbound Messages):
mcp.notification()을 호출하기 전에 송신자(sender)를 허용 목록(allowlist)과 비교하여 유효성을 검사해야 합니다. 이는 보안상 매우 중요합니다.- 테스트 및 배포:
--dangerously-load-development-channels 플래그를 사용하여 개발 중인 채널을 로드해야 합니다. 채널을 쉽게 설치하고 공유할 수 있도록 플러그인(plugin)으로 패키징하여 마켓플레이스(marketplace)에 게시할 수 있습니다.