An exported .flow.json doesn’t have to stay something you run by hand. heliox serve turns it
into a live endpoint — either a small HTTP API or an MCP tool — that other systems can call.
heliox serve
heliox serve <flow.json> [--port 7878] [--host 127.0.0.1] [--token <token>] \
[--model <id>] [--mcp] [--select best-score|cheapest|fastest|best-value]The flow file is loaded and its DAG validated immediately — a malformed export fails fast, before any port is bound or transport started.
HTTP transport (default)
Three routes:
| Route | Method | Auth | Behavior |
|---|---|---|---|
/health | GET | none | 200 { ok: true } — liveness check. |
/flow | GET | Bearer | Returns the loaded flow’s { id, name, rootStepId, steps }. |
/run | POST | Bearer | Executes the flow; returns { completedStepIds, stepOutputs, finalOutput }. |
Auth. /run and /flow require an Authorization: Bearer <token> header. The token comes
from --token, else the HELIOX_SERVE_TOKEN environment variable, else a random 256-bit token
generated at startup and printed to stdout — there is no code path that leaves /run reachable
without one.
Networking. The server binds 127.0.0.1 (loopback) by default. Reaching it from another
machine requires explicitly passing --host 0.0.0.0 (or another address) — wide binding is never
the default, and doing so prints a warning to keep the auth token secret.
Streaming. Send Accept: text/event-stream on POST /run to get the run streamed as
Server-Sent Events (one event: harness message per execution event) instead of waiting for the
buffered JSON response, followed by a terminal event: done (or event: error).
MCP transport (--mcp)
Pass --mcp to expose the flow as a single MCP tool over stdio instead of HTTP — the flow becomes
callable from Claude Desktop, an IDE, N8N, or any other MCP-compatible client. The tool is named
after the flow’s id, described by its step sequence, and takes one optional string input. Running
the flow through MCP delegates to the exact same execution core as the HTTP path — there’s no
forked logic between the two transports.
Arena-informed model selection (--select)
Instead of (or overriding) a fixed --model, pass --select best-score | cheapest | fastest | best-value to resolve a Benchmarked model from the latest Arena leaderboard for that strategy at
startup. An explicit --model always wins over --select. See
Architecture for what the
Arena benchmarks.
Triggers
Beyond calling /run directly, a served flow can react to external events on its own:
Webhook triggers
Mount an additional route on the same server that fires the flow when called:
path— the HTTP path it listens on (e.g./triggers/my-flow).secret— a shared value requests must present (X-Heliox-Secretheader or?secret=query param) or get rejected with401.mode—asyncresponds202 { runId }immediately and runs the flow in the background;syncawaits the full execution and responds200 { output, runId }.
Cron / interval triggers
Fire a flow on a recurring schedule, in either of two forms:
everyMs— a simple interval (e.g.300000for every 5 minutes).cron— a standard 5-field POSIX expression (minute hour day month weekday), supporting*, ranges (1-5), and steps (*/15).
Triggers persist across restarts and can be enabled or disabled independently; when the serve process boots, every enabled trigger starts automatically.
Next steps
- Provider Connections — configure the model credentials a served flow executes against.
- API Reference — the full HTTP contract and
.flow.jsonschema.