---
title: "Running the Fabro Server"
description: "Run Fabro as an API server with a web UI, concurrent runs, and team access"
---

<Warning>
  The server interface is in private early access. Contact [bryan@qlty.sh](mailto:bryan@qlty.sh) if you're interested in trying it.
</Warning>

Fabro has two interfaces to the same workflow engine. You can run a workflow directly in the CLI with `fabro run`, or start the HTTP server with `fabro server start` to queue runs, stream events, and serve the web UI.

Both interfaces use the same workflow engine, the same Graphviz files, and the same sandbox providers. The difference is how you interact with them.

## Direct CLI Runs vs. Server Interface

| | Direct CLI runs | Server interface |
|---|---|---|
| **Command** | `fabro run workflow.fabro` | `fabro server start` |
| **Best for** | Local development, one-off runs, CI/CD | Production, team use, running at scale |
| **Execution** | Synchronous, one run per process | Asynchronous, queued with configurable concurrency |
| **Human-in-the-loop** | Terminal prompts | Web UI or HTTP endpoints |
| **Events** | Printed to stderr | Streamed via SSE |
| **Persistence** | Checkpoint files only | Persistent run store + checkpoint files |
| **Web UI** | Not available | Full React interface |
| **Authentication** | None | JWT and/or mTLS |

## Starting the server

```bash
fabro server start
```

This starts the server on a Unix socket at `~/.fabro/fabro.sock` by default. Use `--bind 127.0.0.1` for TCP. To also run the web UI:

```bash
fabro server start                 # API on port 3000
cd apps/fabro-web && bun run dev   # rebuilds web assets on change; refresh the browser
```

Common flags:

| Flag | Default | Description |
|---|---|---|
| `--bind` | `~/.fabro/fabro.sock` | Address to bind: `IP` or `IP:port` for TCP, or a path for Unix socket |
| `--model` | — | Override default LLM model |
| `--sandbox` | — | Override default sandbox provider |
| `--max-concurrent-runs` | `5` | Maximum concurrent run executions |

See [Server Configuration](/administration/server-configuration) for the full `settings.toml` reference.

## Submitting runs

In the server interface, workflows are submitted via the REST API and executed in the background. The exact request body is documented in the API reference:

```bash
curl -X POST http://localhost:3000/api/v1/runs
```

The server returns immediately with a run ID. A background scheduler promotes queued runs to `Running` in FIFO order, up to the concurrency limit.

## Run lifecycle

1. **Submit** — `POST /api/v1/runs` creates the run with status `Queued`.
2. **Schedule** — The scheduler picks up queued runs up to `max_concurrent_runs`.
3. **Execute** — The engine walks the graph, streaming events to all subscribers.
4. **Complete** — The run transitions to `Completed`, `Failed`, or `Cancelled`.

## Web UI

The web UI connects to the API server and provides:

- **Runs board** — Monitor all active runs organized by status
- **Run detail** — Real-time stage progress, event stream, diffs, and usage stats
- **Start new run** — Submit workflows from the browser
- **Human-in-the-loop** — Answer agent questions through the web interface
- **Workflows** — Browse available workflows, view their graphs, and see run history
- **Insights** — SQL-based analysis across runs via DuckDB

<Frame caption="The Runs board shows all active runs organized by status.">
  <img src="/images/web/runs-board.png" alt="Fabro web UI Runs board with Working, Pending, Verify, and Merge columns" />
</Frame>

<Frame caption="The run detail view shows stage progress alongside the workflow graph.">
  <img src="/images/web/run-overview.png" alt="Fabro web UI run detail showing stages and workflow graph" />
</Frame>

## Event streaming

The API streams run events via [Server-Sent Events (SSE)](/api-reference/runs/stream-run-events). Every stage start, LLM call, tool invocation, and edge selection is emitted as a structured JSON event. Any HTTP client that supports SSE can subscribe — the web UI is just one consumer.

## Human-in-the-loop

In the server interface, human-in-the-loop questions are served over HTTP instead of terminal prompts. The engine blocks the current stage until an answer is submitted, then continues execution. See the [list questions](/api-reference/human-in-the-loop/list-run-questions) and [submit answer](/api-reference/human-in-the-loop/submit-run-answer) API reference pages.

## Authentication

The server configures auth with `server.auth.methods`:

- **`dev-token`** — Operators can call the API directly with `Authorization: Bearer fabro_dev_...`, and the web login page can accept the dev token too.
- **`github`** — End users sign in through GitHub OAuth and receive a browser session cookie.

Both methods can be enabled simultaneously:

```toml title="settings.toml"
[server.auth]
methods = ["dev-token", "github"]

[server.auth.github]
allowed_usernames = ["alice", "bob"]
```

## Demo mode

Send the `X-Fabro-Demo: 1` header on any API request to get static mock data with authentication disabled. The web UI enables this automatically with the `FABRO_DEMO=1` environment variable. This lets you explore the UI without API keys or real workflow execution. See [Demo Mode](/api-reference/demo-mode) for details.

## Pointing the CLI at a server

The CLI can target a running Fabro server for commands that support a remote API. Configure `~/.fabro/settings.toml`:

```toml title="settings.toml"
[server]
target = "https://fabro.example.com:3000/api/v1"
```

Or use the `--server` flag:

```bash
fabro model list --server https://fabro.example.com:3000/api/v1
```

`fabro model list` and `fabro model test` honor `[server].target` by default unless you explicitly pass `--storage-dir`. `fabro exec` remains a local agent session and only uses the server when you pass `--server`.

See [User Configuration](/reference/user-configuration#server-section) for the full connection options, including mTLS setup.

## Next steps

<Columns cols={2}>
  <Card title="Server Configuration" icon="gear" href="/administration/server-configuration">
    Full settings.toml reference — authentication, TLS, run defaults, and more.
  </Card>
  <Card title="Deploy to Railway" icon="train" href="/administration/deploy-railway">
    Step-by-step guide for deploying Fabro on Railway.
  </Card>
  <Card title="API Reference" icon="code" href="/api-reference/overview">
    REST API for submitting runs, streaming events, and managing resources.
  </Card>
  <Card title="How Fabro Works" icon="lightbulb" href="/core-concepts/how-fabro-works">
    The workflow engine that powers both interfaces.
  </Card>
</Columns>
