import { type EntryAvailability } from '@frontmcp/utils'; import { type ToolType } from '../interfaces/tool.interface'; /** * Webhook source — registers an HTTP POST endpoint that receives external events. */ export interface ChannelWebhookSource { type: 'webhook'; /** HTTP path for the webhook endpoint (e.g., '/hooks/deploy') */ path: string; } /** * App event source — subscribes to in-process events via the ChannelEventBus. */ export interface ChannelAppEventSource { type: 'app-event'; /** Event name to subscribe to */ event: string; } /** * Agent completion source — auto-pushes when agents finish execution. */ export interface ChannelAgentCompletionSource { type: 'agent-completion'; /** Optional filter: only notify for these agent IDs */ agentIds?: string[]; } /** * Job completion source — auto-pushes when jobs/workflows complete. */ export interface ChannelJobCompletionSource { type: 'job-completion'; /** Optional filter: only notify for these job names */ jobNames?: string[]; } /** * Manual source — programmatic push only via scope.channelNotifications. */ export interface ChannelManualSource { type: 'manual'; } /** * Service connector source — channel maintains a persistent connection to an external service. * The channel's `onConnect()` establishes the connection and `onDisconnect()` tears it down. * Claude sends messages via the channel's declared tools, and incoming messages trigger `onEvent()`. * * @example WhatsApp service connector * ```typescript * @Channel({ * name: 'whatsapp', * source: { type: 'service', service: 'whatsapp-business' }, * tools: [SendWhatsAppTool], * twoWay: true, * }) * ``` */ export interface ChannelServiceSource { type: 'service'; /** Human-readable service identifier (e.g., 'whatsapp-business', 'telegram-bot', 'slack') */ service: string; } /** * File watcher source — watches file system paths for changes and pushes events. * Uses the channel's `onConnect()` to start watching and `onDisconnect()` to stop. * * @example Watch log files for errors * ```typescript * @Channel({ * name: 'log-watcher', * source: { type: 'file-watcher', paths: ['./logs/*.log'], events: ['change', 'create'] }, * }) * ``` */ export interface ChannelFileWatcherSource { type: 'file-watcher'; /** Glob patterns or specific file paths to watch */ paths: string[]; /** File system events to watch for */ events?: Array<'change' | 'create' | 'delete' | 'rename'>; } /** * Discriminated union of all channel source configurations. */ export type ChannelSourceConfig = ChannelWebhookSource | ChannelAppEventSource | ChannelAgentCompletionSource | ChannelJobCompletionSource | ChannelManualSource | ChannelServiceSource | ChannelFileWatcherSource; /** * The notification payload sent to Claude Code sessions. * Maps to `notifications/claude/channel` params. */ export interface ChannelNotification { /** The notification content (appears inside tags in Claude) */ content: string; /** Optional metadata key-value pairs (become XML attributes on the tag) */ meta?: Record; } declare global { /** * Declarative metadata extends for the Channel decorator. */ interface ExtendFrontMcpChannelMetadata { } } /** * Declarative metadata describing a notification channel. * * @example * ```typescript * @Channel({ * name: 'deploy-alerts', * description: 'CI/CD deployment notifications', * source: { type: 'webhook', path: '/hooks/deploy' }, * twoWay: true, * meta: { team: 'platform' }, * }) * ``` */ export interface ChannelMetadata extends ExtendFrontMcpChannelMetadata { /** * Unique name for the channel. * Used as the source identifier in channel notifications. */ name: string; /** * Human-readable description of what this channel does. * Included in the server instructions sent to Claude Code. */ description?: string; /** * The source that feeds events into this channel. */ source: ChannelSourceConfig; /** * Whether this channel supports two-way communication. * When true, a reply tool is auto-registered so Claude can send messages back. * @default false */ twoWay?: boolean; /** * Static metadata appended to every notification from this channel. * Keys must be valid identifiers (letters, digits, underscores). */ meta?: Record; /** * Event replay configuration. * When enabled, events are buffered so they can be replayed when Claude Code connects. * Use this for channels where events should not be lost if Claude is not connected. * * The buffer is in-memory by default. For persistence across restarts, provide an * external store via `onConnect()`. * * @example * ```typescript * @Channel({ * name: 'ci-alerts', * source: { type: 'webhook', path: '/hooks/ci' }, * replay: { enabled: true, maxEvents: 100 }, * }) * ``` */ replay?: { /** Enable event buffering for replay */ enabled: boolean; /** Maximum number of events to buffer (default: 50) */ maxEvents?: number; }; /** * Tools contributed by this channel. * These tools are auto-registered in the scope's tool registry and give Claude * the ability to send messages or perform actions through the channel's service. * * For service connectors (source: { type: 'service' }), these tools represent the * outbound side of the channel — Claude calls them to send messages, and incoming * responses arrive back through the channel's `onEvent()` as notifications. * * @example * ```typescript * @Channel({ * name: 'whatsapp', * source: { type: 'service', service: 'whatsapp-business' }, * tools: [SendWhatsAppMessageTool], * twoWay: true, * }) * ``` */ tools?: ToolType[]; /** * Tags for categorization and filtering. */ tags?: string[]; /** * Environment availability constraint. */ availableWhen?: EntryAvailability; } export declare const channelSourceConfigSchema: import("@frontmcp/lazy-zod").ZodDiscriminatedUnion<[import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"webhook">; path: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"app-event">; event: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"agent-completion">; agentIds: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"job-completion">; jobNames: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"manual">; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"service">; service: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"file-watcher">; paths: import("@frontmcp/lazy-zod").ZodArray; events: import("@frontmcp/lazy-zod").ZodOptional>>; }, import("zod/v4/core").$strip>], "type">; export declare const frontMcpChannelMetadataSchema: import("@frontmcp/lazy-zod").ZodObject<{ name: import("@frontmcp/lazy-zod").ZodString; description: import("@frontmcp/lazy-zod").ZodOptional; source: import("@frontmcp/lazy-zod").ZodDiscriminatedUnion<[import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"webhook">; path: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"app-event">; event: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"agent-completion">; agentIds: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"job-completion">; jobNames: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"manual">; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"service">; service: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"file-watcher">; paths: import("@frontmcp/lazy-zod").ZodArray; events: import("@frontmcp/lazy-zod").ZodOptional>>; }, import("zod/v4/core").$strip>], "type">; twoWay: import("@frontmcp/lazy-zod").ZodDefault>; meta: import("@frontmcp/lazy-zod").ZodOptional>; replay: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>>; tools: import("@frontmcp/lazy-zod").ZodOptional>; tags: import("@frontmcp/lazy-zod").ZodOptional>; availableWhen: import("@frontmcp/lazy-zod").ZodOptional>; platform: import("@frontmcp/lazy-zod").ZodOptional>; runtime: import("@frontmcp/lazy-zod").ZodOptional>; deployment: import("@frontmcp/lazy-zod").ZodOptional>; provider: import("@frontmcp/lazy-zod").ZodOptional>; target: import("@frontmcp/lazy-zod").ZodOptional>; surface: import("@frontmcp/lazy-zod").ZodOptional>>; env: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strict>>; }, import("zod/v4/core").$loose>; /** * Channel notification payload schema. */ export declare const channelNotificationSchema: import("@frontmcp/lazy-zod").ZodObject<{ content: import("@frontmcp/lazy-zod").ZodString; meta: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>; /** * Channels configuration at the server level. */ export interface ChannelsConfigOptions { /** Enable the channels system */ enabled: boolean; /** Default metadata appended to all channel notifications */ defaultMeta?: Record; } export type ChannelsConfigInput = ChannelsConfigOptions; export declare const channelsConfigSchema: import("@frontmcp/lazy-zod").ZodObject<{ enabled: import("@frontmcp/lazy-zod").ZodBoolean; defaultMeta: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>; //# sourceMappingURL=channel.metadata.d.ts.map