channels-bootstrap
Production-ready channel server implementations — CI webhook receiver, mobile approval relay, Discord/Telegram bridge, and local fakechat dev profile. Copy-paste starter code with sender allowlists, permission relay, and security hardening.
What this skill does
# Channels Bootstrap — Starter Implementations
Four production-ready channel server patterns. Each is runnable with Bun or Node.js,
includes sender allowlists, and handles the security concerns that make channels safe to
deploy. Copy the one that fits your use case, drop it in your repo, and register it in
`.mcp.json`.
> **Prerequisites**: Claude Code v2.1.80+, claude.ai login (not API key), Bun or Node.js
> **Security rule**: Every inbound channel is a prompt injection vector — always gate on
> sender identity before forwarding any content to Claude.
---
## Pattern 1: CI Webhook Receiver
**Use case**: React to CI/CD events (GitHub Actions failures, build completions, deploy
status) without polling. Claude gets notified when a build breaks and can investigate,
post a PR comment, or open a fix branch automatically.
### `channels/ci-webhook.ts`
```typescript
#!/usr/bin/env bun
/**
* CI Webhook Channel — receives POST events from GitHub Actions, GitLab CI,
* Jenkins, or any webhook-capable CI system and pushes them into Claude Code.
*
* Security: webhook HMAC signature verification (GitHub Actions compatible).
* Setup: set WEBHOOK_SECRET env var matching your CI platform's secret.
*
* Register in .mcp.json:
* "ci-webhook": { "command": "bun", "args": ["./channels/ci-webhook.ts"],
* "env": { "WEBHOOK_SECRET": "${WEBHOOK_SECRET}" } }
*
* Start:
* claude --dangerously-load-development-channels server:ci-webhook
*
* Test:
* curl -X POST http://127.0.0.1:8788/webhook \
* -H "Content-Type: application/json" \
* -d '{"action":"completed","workflow_run":{"name":"CI","conclusion":"failure","html_url":"https://github.com/org/repo/actions/runs/123"}}'
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { createHmac, timingSafeEqual } from 'crypto'
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET ?? ''
const PORT = parseInt(process.env.CI_WEBHOOK_PORT ?? '8788', 10)
// Map CI event types to human-readable summaries for Claude
function summarizeEvent(event: string, body: Record<string, unknown>): string | null {
switch (event) {
case 'workflow_run': {
const run = body.workflow_run as Record<string, unknown>
if (!run) return null
if (run.conclusion === 'failure') {
return `CI FAILURE: Workflow "${run.name}" failed on branch "${run.head_branch}". ` +
`Commit: ${String(run.head_sha).slice(0, 7)}. ` +
`Run: ${run.html_url}`
}
if (run.conclusion === 'success') {
return `CI SUCCESS: Workflow "${run.name}" passed on branch "${run.head_branch}".`
}
return null // ignore in-progress events
}
case 'push': {
const commits = (body.commits as unknown[])?.length ?? 0
const ref = String(body.ref ?? '').replace('refs/heads/', '')
const pusher = (body.pusher as Record<string, unknown>)?.name ?? 'unknown'
return `PUSH: ${pusher} pushed ${commits} commit(s) to ${ref}.`
}
case 'pull_request': {
const pr = body.pull_request as Record<string, unknown>
const action = String(body.action ?? '')
if (!['opened', 'ready_for_review', 'closed'].includes(action)) return null
const state = action === 'closed' && body.merged ? 'merged' : action
return `PR ${state.toUpperCase()}: "${pr?.title}" → ${pr?.base?.branch ?? 'main'}. ` +
`URL: ${pr?.html_url}`
}
case 'deployment_status': {
const ds = body.deployment_status as Record<string, unknown>
const env = (body.deployment as Record<string, unknown>)?.environment ?? 'unknown'
if (ds?.state === 'failure') {
return `DEPLOY FAILURE: Deployment to ${env} failed. ` +
`Log: ${ds?.log_url ?? 'no log'}`
}
if (ds?.state === 'success') {
return `DEPLOY SUCCESS: Deployed to ${env}.`
}
return null
}
default:
return null
}
}
// Verify GitHub webhook signature (HMAC-SHA256)
async function verifySignature(body: string, signature: string | null): Promise<boolean> {
if (!WEBHOOK_SECRET) return true // no secret configured — allow all (dev mode)
if (!signature) return false
const expected = 'sha256=' + createHmac('sha256', WEBHOOK_SECRET).update(body).digest('hex')
try {
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
} catch {
return false
}
}
const mcp = new Server(
{ name: 'ci-webhook', version: '1.0.0' },
{
capabilities: { experimental: { 'claude/channel': {} } },
instructions:
'CI and deployment events arrive as <channel source="ci-webhook" event="..." ...>. ' +
'For FAILURE events: investigate the failure, check recent commits, and propose a fix. ' +
'For DEPLOY FAILURE: check logs and determine rollback vs hot-fix. ' +
'For PR events: summarize changes if asked. ' +
'Do not act on SUCCESS events unless explicitly asked.',
},
)
await mcp.connect(new StdioServerTransport())
const server = Bun.serve({
port: PORT,
hostname: '127.0.0.1',
async fetch(req: Request) {
if (new URL(req.url).pathname !== '/webhook') {
return new Response('not found', { status: 404 })
}
if (req.method !== 'POST') {
return new Response('method not allowed', { status: 405 })
}
const rawBody = await req.text()
const sig = req.headers.get('x-hub-signature-256')
if (!(await verifySignature(rawBody, sig))) {
return new Response('forbidden', { status: 403 })
}
const event = req.headers.get('x-github-event') ?? 'unknown'
let parsed: Record<string, unknown>
try {
parsed = JSON.parse(rawBody)
} catch {
return new Response('bad request', { status: 400 })
}
const summary = summarizeEvent(event, parsed)
if (summary === null) {
return new Response('ok (ignored)') // don't forward irrelevant events
}
await mcp.notification({
method: 'notifications/claude/channel',
params: {
content: summary,
meta: { event, severity: summary.startsWith('CI FAILURE') || summary.startsWith('DEPLOY FAILURE') ? 'high' : 'info' },
},
})
return new Response('ok')
},
})
console.error(`CI webhook channel listening on http://127.0.0.1:${PORT}/webhook`)
```
### Registration
```json
{
"mcpServers": {
"ci-webhook": {
"command": "bun",
"args": ["./channels/ci-webhook.ts"],
"env": {
"WEBHOOK_SECRET": "${WEBHOOK_SECRET}",
"CI_WEBHOOK_PORT": "8788"
}
}
}
}
```
### GitHub Actions Setup
Add a webhook in your repository (Settings → Webhooks → Add webhook):
- **Payload URL**: `http://your-tunnel/webhook` (use ngrok or Cloudflare Tunnel to expose local port)
- **Content type**: `application/json`
- **Secret**: same value as `WEBHOOK_SECRET`
- **Events**: Workflow runs, Push, Pull requests, Deployment statuses
```bash
# Quick local tunnel (for dev/testing)
# Requires ngrok: https://ngrok.com
ngrok http 8788
# Cloudflare Tunnel (persistent, no account needed for quick test)
cloudflared tunnel --url http://127.0.0.1:8788
```
### Claude Startup
```bash
# Load channel with development flag (until your channel is in official marketplace)
claude --dangerously-load-development-channels server:ci-webhook
```
---
## Pattern 2: Mobile Approval Relay
**Use case**: Approve or deny Claude's tool calls from your phone when you're away from
your desk. Forwards tool approval prompts to Telegram (or any chat platform), parses
yes/no responses, relays verdicts back to Claude Code.
Requires Claude Code v2.1.81+.
### `channels/mobile-approval.ts`
```typescript
#!/usr/bin/env bun
/**
* Mobile Approval Relay — forwards Claude Code permission prompts to Telegram
* and relays yes/no verdicts back. Lets you approve tool calls from your phone.
*
* Prerequisites:
* - Telegram bot token (BotFather → /newbot)
* - YoRelated in Cloud & DevOps
appbuilder-action-scaffolder
IncludedCreate, implement, deploy, and debug Adobe Runtime actions with consistent layout, validation, and error handling. Use this skill whenever the user needs to add actions to an App Builder project, understand action structure (params, response format, web/raw actions), configure actions in the manifest, use App Builder SDKs (State, Files, Events, database), deploy and invoke actions via CLI, debug action issues, or implement patterns such as webhook receivers, custom event providers, journaling consumers, large payload redirects, action sequence pipelines, and Asset Compute workers. Also trigger when users mention serverless functions in Adobe context, action logging, IMS authentication for actions, or cron-style scheduled actions.
orchestrating-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. Use this skill when the user needs a multi-step Data Cloud pipeline, cross-phase troubleshooting, or data space and data kit management. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase sf data360 workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching phase-specific skill), the task is STDM/session tracing/parquet telemetry (use observing-agentforce), standard CRM SOQL (use querying-soql), or Apex implementation (use generating-apex).
github-project-automation
IncludedAutomate GitHub repository setup with CI/CD workflows, issue templates, Dependabot, and CodeQL security scanning. Includes 12 production-tested workflows and prevents 18 errors: YAML syntax, action pinning, and configuration. Use when: setting up GitHub Actions CI/CD, creating issue/PR templates, enabling Dependabot or CodeQL scanning, deploying to Cloudflare Workers, implementing matrix testing, or troubleshooting YAML indentation, action version pinning, secrets syntax, runner versions, or CodeQL configuration. Keywords: github actions, github workflow, ci/cd, issue templates, pull request templates, dependabot, codeql, security scanning, yaml syntax, github automation, repository setup, workflow templates, github actions matrix, secrets management, branch protection, codeowners, github projects, continuous integration, continuous deployment, workflow syntax error, action version pinning, runner version, github context, yaml indentation error
sf-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase `sf data360` workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching sf-datacloud-* skill), the task is STDM/session tracing/parquet telemetry (use sf-ai-agentforce-observability), standard CRM SOQL (use sf-soql), or Apex implementation (use sf-apex).
fabric-cli
IncludedUse this skill for Fabric.so CLI workflows with the `fabric` terminal command: diagnose/install/login, search or browse a Fabric library, save notes/links/files, create folders, ask the Fabric AI assistant, manage tasks/workspaces, generate shell completion, check subscription usage, produce JSON output, and use Fabric as persistent agent memory. Do not use for Microsoft Fabric/Azure/Power BI `fab`, Daniel Miessler's Fabric framework, Python Fabric SSH, Fabric.js, or textile/fashion fabric.
lark
IncludedLark/Feishu CLI skills: lark-cli operations for docs, markdown, sheets, base, calendar, im, mail, task, okr, drive, wiki, slides, whiteboard, apps, approval, attendance, contact, vc, minutes, event. Use when the user needs to operate Lark/Feishu resources via lark-cli, send messages, manage documents, spreadsheets, calendars, tasks, OKRs, deploy web pages, or any Feishu/Lark workspace operations.