Skip to content
ChannelDesk
Flow Engine v2

Triggers → conditions → LLM → actions.

The Flow Engine is the beating heart of ChannelDesk. It is where your cron schedules, webhooks, device events and Claude sessions meet — composable, resumable, observable.

/flows/github-deploy-on-push · visual editor with branching nodes
ChannelDesk Flow editor — GitHub Deploy on Push: trigger → condition (yes/no) → ssh-command → delay → http-request → notification (success / failure branches)

Trigger anything

Four kinds: manual (a button), cron, webhook (POST to /api/flows/webhook/{token}), and event (FlowEventBus matches on system activity).

Claude-step in-line

Drop a Claude step into a flow and get a fresh session spawned, tools wired, and its structured output piped into the next step.

Device actions

Call any capability on any entity. Dim lights, toggle a Wi-Fi network, change a thermostat — the flow doesn't care how.

Durable

Flows and their run history live in PostgreSQL. Crash-safe: on restart, in-flight runs resume.

Observable

Every run is a first-class record — status, duration, step-by-step output, Claude token usage.

Flow-tools MCP

A built-in MCP server lets a Claude session introspect, trigger, or author flows itself. Claude can build your automations with you.
Node palette

Thirteen node types. One canvas.

Trigger, agent, condition — and ten more building blocks. Drop them on the canvas, wire them up, run.

trigger quick-action agent condition notification email http-request delay transform for-each ssh-command integration-command sub-flow

Outputs flow forward through a results map — every step can reference any earlier step's output.

No code, no YAML

Don't write flows. Ask for them.

Every flow has a chat tab wired to a flow-tools MCP server. Describe what you want, Claude adds the nodes, and the canvas reloads with the result.

/flows/morning-routine · chat
Weekday mornings at 07:00: turn on the kitchen ceiling, run the bedroom sunrise scene, ask Claude for a 2-sentence brief from my PRs and calendar, and DM it to me on Telegram.
Built morning-routine. Trigger: cron 0 7 * * 1-5. Steps: hue scene kitchen.ceiling.on → hue scene bedroom:sunrise → Claude step (flow-tools, github, calendar MCPs) → telegram.reply with the summary. Reload canvas →
All 4 nodes live on the canvas above. Edit them visually or ask for changes.
Skip it on public holidays.
Added a condition node after the trigger that calls the nl-holidays MCP and short-circuits when today is a public holiday.
Composition, not copy-paste

Flows can call other flows.

Drop a sub-flow node onto the canvas and it runs another flow as a step — synchronously, with its outputs piped into the next node's results map. Build a primitive once, call it from anywhere.

  • vacuum-journald built once — called from disk-pressure, weekly-cleanup, and post-deploy
  • • Sub-flow runs land in FlowRunEntity.triggeredBy = sub-flow so you can audit who called whom
  • • Edit the child once; every parent picks up the change next run
  • • Wraps as cleanly inside a for-each as any other node — fan out a sub-flow per worker
/flows/disk-pressure · canvas
cron · 0 */15 * * *ssh-command (df -h) → condition (any > 85%) → for-each (host) → sub-flow: vacuum-journaldnotification.
The vacuum-journald flow is also wired to weekly-cleanup and post-deploy. Three callers, one definition.
Worked example

A flow that fixes its own pull requests.

Webhook fires when a PR is opened. Tests run. SonarQube runs. If anything fails, the flow routes to a Claude agent that reads the report, edits the code, pushes a fix, and loops back to the top — until everything is green or it gives up and asks for help.

/flows/pr-auto-fix · canvas
Trigger · webhook from GitHub (pull_request.opened)
ssh-command · npm test on the build host
integration-command · run SonarQube scan, fetch issues
condition · all green?
— yes →
notification · “ready for human review” in chat
— no →
agent · spawns Claude with the failure report attached. Claude reads the diff, edits the code, runs the affected tests locally, and pushes a fix commit. Sub-flow loops back to npm test.
— after 3 failed loops →
notification · “giving up, here's what I tried” with the full transcript.

Every primitive earns its place

  • Webhook trigger — GitHub fires on PR opened
  • ssh-command — runs the test suite on a real machine
  • integration-command — calls the Sonar scanner
  • condition — green / not green branch
  • agent — Claude session with the failure report + repo
  • sub-flow — re-runs the test+sonar block after the fix
  • approval gate — agent asks before git push

Where it ends up

You wake up. Either the PR is green and tagged for human review, or there's a chat message with three diffs the agent tried, why each failed, and the question that stumped it.

Browse

One page, every automation.

The flow list shows trigger type, enabled state and the last successful run. Toggle a flow off without losing its definition; clone it to draft a variant.

  • • Cron, webhook, manual, device — colour-coded by trigger type
  • • Disabled flows stay searchable and editable
  • • Per-flow chat dock so Claude can rewrite the flow itself
/flows
ChannelDesk Flows — list of automations with cron, webhook and manual triggers, plus enabled/disabled state

Don't write the automation. Describe it.

ChannelDesk's flow editor has a chat tab. Tell Claude what you want, watch the canvas update.