# How to Build and Run Workflows with TinyFlows Integration in OpenHuman

> Learn to build and run workflows in OpenHuman using TinyFlows integration. Automate tasks with JSON triggers and actions via UI, CLI, or RPC.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: how-to-guide
- Published: 2026-09-01

---

**OpenHuman ships with TinyFlows, a declarative workflow engine that enables automation through JSON-defined triggers and actions, accessible via desktop UI, CLI, or direct RPC calls.**

OpenHuman includes a built-in automation framework called TinyFlows that lets you build and run workflows with TinyFlows integration in OpenHuman using simple configuration files or programmatic interfaces. This engine operates within the `flows::tinyflows` domain and integrates deeply with the core runtime, allowing both headless server deployments and interactive desktop usage. Whether you are automating HTTP requests or chaining complex tool interactions, TinyFlows provides the infrastructure to execute workflows based on event triggers.

## Understanding the TinyFlows Architecture

The TinyFlows stack is organized into distinct layers that separate runtime execution from storage and interface concerns. According to the OpenHuman source code, these components work together to provide a complete automation pipeline.

### Core Runtime Layer

In [`src/openhuman/flows/tinyflows/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/mod.rs), the core runtime registers the TinyFlows domain and initializes the RPC controllers that expose workflow functionality. This module hosts the automation engine and dispatches tool calls when workflows execute.

### RPC Operations Layer

The [`src/openhuman/flows/tinyflows/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/ops.rs) file implements the JSON-RPC methods including `list_flows`, `run_flow`, and `create_flow`. Both the React frontend and command-line interface communicate with the engine through these endpoints.

### Persistent Storage

Workflow definitions reside in the workspace directory under `<workspace>/flows`. The storage layout and versioning logic are demonstrated in [`src/openhuman/flows/tinyflows/tinyflows_tests.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/tinyflows_tests.rs), which shows how the engine loads flow definitions on startup and watches for changes.

### Tool Integration

TinyFlows actions resolve to OpenHuman's standard tool system. The [`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs) file handles registration of available tools like `http_request`, which TinyFlows actions invoke during execution.

## Building OpenHuman with TinyFlows Support

TinyFlows compiles by default with the `flows` feature flag. To build the core binary with automation support:

```bash

# Build the core binary with TinyFlows enabled

cargo build --bin openhuman-core

```

For custom builds where default features may be disabled, explicitly enable the flows feature:

```bash
cargo build --features "flows"

```

The core binary respects the `OPENHUMAN_ACTION_DIR` environment variable to specify a custom workspace location. If unset, it defaults to `~/OpenHuman/projects`.

To start the RPC server for headless operation:

```bash
./target/debug/openhuman-core serve

```

## Creating TinyFlows Workflows

Workflows are declarative JSON documents stored as [`.flow.json`](https://github.com/tinyhumansai/openhuman/blob/main/.flow.json) or [`.flow.yaml`](https://github.com/tinyhumansai/openhuman/blob/main/.flow.yaml) files in the workspace flows directory.

### Manual JSON Definition

Create a file at `<workspace>/flows/example.flow.json`:

```json
{
  "id": "example",
  "name": "Demo workflow",
  "description": "Runs a simple HTTP request when the user sends a message",
  "trigger": {
    "type": "on_message",
    "filter": { "contains": "hello" }
  },
  "actions": [
    {
      "type": "http_request",
      "method": "GET",
      "url": "https://api.example.com/greet",
      "headers": { "Accept": "application/json" }
    }
  ]
}

```

The core watches this directory and hot-reloads workflows on startup.

### CLI-Based Creation

Use the CLI interface defined in [`src/openhuman/flows/tinyflows/cli.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/cli.rs) to generate workflows programmatically:

```bash
openhuman flow create \
  --id example \
  --name "Demo workflow" \
  --trigger on_message \
  --filter 'contains=hello' \
  --action http_request \
  --method GET \
  --url https://api.example.com/greet

```

## Running TinyFlows Workflows

### Desktop UI Method

Navigate to **Settings → Automations → Workflows** in the React frontend ([`app/src/pages/settings/automations/WorkflowEditor.tsx`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/pages/settings/automations/WorkflowEditor.tsx)). Toggle the **Enabled** switch on your workflow to activate automatic trigger evaluation when conditions match.

### Headless CLI Execution

Execute workflows immediately without waiting for triggers:

```bash
openhuman flow run --id example

```

This command invokes the `openhuman.flow_run_flow` RPC method, streaming results back from the TinyFlows engine.

### Direct RPC Invocation

Send raw JSON-RPC requests to the core HTTP endpoint:

```bash
curl -X POST http://127.0.0.1:8000/rpc \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "openhuman.flow_run_flow",
    "params": {"flow_id": "example"}
  }'

```

## Programmatic Workflow Integration

### Rust Embedder Example

Create and execute flows programmatically using the core harness:

```rust
use openhuman_core::Harness;
use openhuman_core::flows::tinyflows::FlowDefinition;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let harness = Harness::builder()
        .workspace(openhuman_core::Workspace::Dir("./my_workspace".into()))
        .build()
        .await?;

    let flow = FlowDefinition {
        id: "example".into(),
        name: "Demo workflow".into(),
        trigger: tinyflows::Trigger::OnMessage {
            filter: Some(tinyflows::MessageFilter {
                contains: Some("hello".into()),
                ..Default::default()
            }),
        },
        actions: vec![tinyflows::Action::HttpRequest {
            method: "GET".into(),
            url: "https://api.example.com/greet".into(),
            headers: None,
            body: None,
        }],
    };

    harness
        .rpc_client()
        .call("openhuman.flow_create_flow", serde_json::json!({ "flow": flow }))
        .await?;

    let result = harness
        .rpc_client()
        .call("openhuman.flow_run_flow", serde_json::json!({ "flow_id": "example" }))
        .await?;
    
    println!("Flow result: {:?}", result);
    Ok(())
}

```

### Shell Automation Example

Trigger workflows from shell scripts using bearer token authentication:

```bash
#!/usr/bin/env bash
FLOW_ID=example
curl -s -X POST "http://127.0.0.1:${OPENHUMAN_CORE_PORT:-8000}/rpc" \
  -H "Authorization: Bearer $OPENHUMAN_CORE_TOKEN" \
  -d "{
    \"jsonrpc\": \"2.0\",
    \"id\": 1,
    \"method\": \"openhuman.flow_run_flow\",
    \"params\": { \"flow_id\": \"$FLOW_ID\" }
  }"

```

## Summary

- **TinyFlows** is OpenHuman's built-in automation engine residing in the `flows::tinyflows` domain, with core registration in [`src/openhuman/flows/tinyflows/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/mod.rs).
- **Build** the core using `cargo build --bin openhuman-core` with the default `flows` feature enabled.
- **Store** workflow definitions as JSON or YAML files in `<workspace>/flows`, or create them via the `openhuman flow create` CLI command.
- **Execute** workflows through the desktop UI at Settings → Automations, via `openhuman flow run --id <name>`, or by calling the `openhuman.flow_run_flow` RPC method directly.
- **Integrate** programmatically using the Rust `Harness` API or HTTP JSON-RPC endpoints for external automation.

## Frequently Asked Questions

### How do I enable TinyFlows if my OpenHuman build does not include it?

Ensure you compile with the `flows` feature flag by running `cargo build --features "flows"` or using the default product profile which includes automation support. The [`src/openhuman/flows/tinyflows/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/mod.rs) file will only register the RPC controllers when this feature is enabled during compilation.

### Where does OpenHuman store TinyFlows workflow definitions?

Workflows persist in the `flows` subdirectory of your workspace, typically `~/OpenHuman/projects/flows` unless overridden by the `OPENHUMAN_ACTION_DIR` environment variable. The storage implementation and versioning logic are detailed in [`src/openhuman/flows/tinyflows/tinyflows_tests.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/tinyflows_tests.rs).

### Can I trigger TinyFlows from external applications?

Yes. Any external application can invoke workflows by sending JSON-RPC requests to the core HTTP endpoint using the `openhuman.flow_run_flow` method. Both the desktop UI ([`app/src/pages/settings/automations/WorkflowEditor.tsx`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/pages/settings/automations/WorkflowEditor.tsx)) and CLI ([`src/openhuman/flows/tinyflows/cli.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/flows/tinyflows/cli.rs)) use this same RPC interface to communicate with the engine.

### What trigger types are available in TinyFlows?

The engine supports built-in triggers like `on_message` with filtering capabilities for message content. When a trigger condition matches, the engine executes the workflow's action chain using tools registered in [`src/openhuman/tools/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/tools/ops.rs), such as `http_request` or custom agent tools.