Skip to main content
Skip to Content
DocsServe & Deploy

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:

RouteMethodAuthBehavior
/healthGETnone200 { ok: true } — liveness check.
/flowGETBearerReturns the loaded flow’s { id, name, rootStepId, steps }.
/runPOSTBearerExecutes 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-Secret header or ?secret= query param) or get rejected with 401.
  • modeasync responds 202 { runId } immediately and runs the flow in the background; sync awaits the full execution and responds 200 { output, runId }.

Cron / interval triggers

Fire a flow on a recurring schedule, in either of two forms:

  • everyMs — a simple interval (e.g. 300000 for 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

Last updated on