# Operator quickstart

> Bring Conversational Factory up on a workstation in about ten minutes — and ask your plant a question.

*Canonical HTML: https://www.conversationalfactory.com/docs/quickstart*
*Markdown source: https://www.conversationalfactory.com/docs/quickstart.md*

---

**Bring Conversational Factory up on a workstation in about ten minutes — and ask your plant a question.**

This is the operator runbook. You don't need to know Rust, Python, or how the internals work. You'll use Docker, a web browser, and Claude Desktop.

If you're a developer who wants the chain running from source, see the [dev quickstart](/docs/dev-quickstart) instead.

## What you'll have at the end

- The **witness** running locally, watching whatever traffic you point it at.
- A **conversational gateway** exposing 10 tools to any AI client that speaks MCP.
- **Claude Desktop** connected to the gateway. You can ask *"what's on the network?"* and it will answer with grounded data.
- An **audit log** capturing every tool call, so you can always trace why the AI said what it said.

## Before you start

You need:

- **A workstation.** macOS or Linux. 8 GB RAM, ~20 GB free disk.
- **Docker.** On macOS, [Colima](https://github.com/abiosoft/colima) is the easiest path:
  ```sh
  brew install colima docker docker-compose
  colima start
  ```
  On Linux, install Docker Engine via your distro's package manager.
- **Git** to clone the repo.
- **Claude Desktop** installed ([download](https://claude.ai/download)). Optional but expected for the conversational layer.

You do **not** need:

- Rust, Python, or any language toolchain installed locally.
- Network access during the bring-up — once the images are pulled, the entire stack runs offline on your laptop.
- A real plant network. The witness can replay PCAP files for testing.

## Step 1 — Get the code

```sh
git clone https://github.com/riverman-io/conversational-factory.git
cd conversational-factory
```

If you don't have access to the repo, contact `river@riverman.io`.

## Step 2 — One-time bootstrap

Run the bootstrap script. This handles everything that has to happen exactly once: secrets, database schema, organization setup, and the API key the gateway uses to talk to the witness.

```sh
make first-run
```

Expected output (abridged):

```
==> Step 1/6 — Ensuring witness secrets are set
  ok   appended DB_PASSWORD to services/witness/.env
  ok   appended SECRET_KEY to services/witness/.env
  ...
==> Step 2/6 — Bringing up the witness stack (db, redis, app, workers)
  ok   db reachable
==> Step 3/6 — Running database migrations (alembic upgrade head)
  ok   migrations applied
==> Step 4/6 — Starting the witness app
  ok   app healthy
==> Step 5/6 — Provisioning default org + i3X API key
  ok   provisioned new i3X API key
==> Step 6/6 — Writing WITNESS_API_KEY to ./.env
  ok   wrote WITNESS_API_KEY to ./.env

First-run complete.
```

Re-running `make first-run` is safe — it skips work that's already done.

> **Heads up — first run is slow.** Building the witness's Docker image takes about 10 minutes the first time. After that, restarts are seconds.

## Step 3 — Bring up the full chain

```sh
make up
```

This starts everything — witness, query plane, gateway, and supporting services — as Docker containers. Verify with:

```sh
make ps
```

You should see something like:

```
NAME                       STATUS         PORTS
eriswitness-dev-app        Up (healthy)   127.0.0.1:5001->5001/tcp
eriswitness-dev-db         Up (healthy)   5432/tcp
eriswitness-dev-redis      Up (healthy)   6379/tcp
cf-query-plane             Up             127.0.0.1:8090->8090/tcp
cf-gateway                 Up             127.0.0.1:8091->8091/tcp
... (15 worker containers)
```

If anything is restarting or unhealthy, see [Troubleshooting](#troubleshooting) at the bottom.

## Step 4 — Open the witness console

Open `http://127.0.0.1:5001` in your browser.

Log in:

- **Username:** `admin`
- **Password:** `admin-dev-password` *(set in `services/witness/.env` — change it for any non-dev use)*

After login you land on the asset map. The witness can populate its asset database two ways: by capturing live network traffic (requires admin privileges and a network interface to listen on), or by replaying a PCAP file. The fastest demo path is replay.

## Step 5 — Load a sample PCAP

Pick a fixture from the bundled `presets/` directory. The witness ships with realistic ICS/OT captures:

- **`presets/ics-ot/modbus-scan.pcap`** — Modbus/TCP traffic between a SCADA polling client and three PLCs. Good for first-run because it produces clean, recognisable assets.
- **`presets/ics-ot/ethernetip.pcap`** — Allen-Bradley EtherNet/IP traffic.
- **`presets/ics-ot/opcua-discovery.pcap`** — OPC UA discovery and browse.

Then in the witness UI:

1. Click **New Scan** in the top-right of the assets page.
2. Click **Upload PCAP**.
3. Browse to your repo: `services/witness/presets/ics-ot/modbus-scan.pcap`.
4. Click **Start scan**.

Wait ~30 seconds for the scan to complete. Then click back to **Assets** — you'll see entries with vendor (Allen-Bradley, Siemens), role (PLC, HMI), and Purdue level annotations.

Confirm the gateway can see these assets too:

```sh
open http://127.0.0.1:8091/tools
```

You should see a JSON response listing 10 tools (`get_current_state`, `list_objects`, `get_history`, etc.). That's the MCP surface Claude Desktop will use.

## Step 6 — Connect Claude Desktop

Open the Claude Desktop config file:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json`

If the file doesn't exist, create it. Add (or merge into) this block:

```json
{
  "mcpServers": {
    "factory": {
      "command": "curl",
      "args": [
        "-N", "-s",
        "-H", "content-type: application/json",
        "--data-binary", "@-",
        "http://127.0.0.1:8091/mcp"
      ]
    }
  }
}
```

> **Note.** This wires Claude Desktop to the gateway over HTTP. If you'd rather run the gateway as a stdio subprocess (less moving parts, but requires building from source), see the [dev quickstart](/docs/dev-quickstart) Step 5.

Restart Claude Desktop. In a new conversation, click the tools icon — you should see **factory** listed with 10 tools available.

## Step 7 — Ask your plant a question

In Claude Desktop, in the conversation:

> *"Use the factory MCP server. What objects are visible right now? For each one, get its current state."*

Claude will call `list_objects` first, then `get_current_state` on each result, then compose an answer like:

> "I can see four objects on the network. The first is an Allen-Bradley PLC at 10.5.0.10 (vendor confirmed, role identified as PLC), currently active with risk score 0. The second is a Siemens HMI at..."

Try other questions:

- *"Show me history for the Allen-Bradley PLC over the last hour."*
- *"What relationships exist between these assets?"*
- *"Are any objects showing degraded quality right now?"*

Each tool call writes to the audit log. Inspect it any time:

```sh
docker exec cf-gateway cat /var/log/cf/gateway-audit.jsonl | tail -5
```

Each line records: the natural-language question (when the AI provided it), the exact tool dispatched, the parameters, the downstream witness call (path, latency, status), and the result returned to the AI. This is the forensic record — *"why did the AI tell me X?"* is always answerable.

## Daily lifecycle

```sh
make up         # bring up after a reboot
make down       # shut down (preserves data)
make logs       # tail logs from all services
make ps         # status check
```

To start fresh (wipe all data, keep code):

```sh
make down
docker volume rm conversational-factory_eriswitness-dev-data \
                conversational-factory_eriswitness-dev-pgdata \
                conversational-factory_cf-audit
make first-run
make up
```

## Troubleshooting

**`make first-run` fails at "could not start witness db+redis. Is Docker running?"**
On macOS, run `colima start`. On Linux, `sudo systemctl start docker`. Then re-run.

**`make up` fails with `WITNESS_API_KEY: variable required`.**
You haven't run `make first-run` yet, or the `.env` file at the repo root is missing. Re-run `make first-run`.

**Witness UI loads but assets list is empty after a PCAP upload.**
Check the scan finished: in the witness UI, click **Scans** to see status. If it failed, the log tab shows why. The most common cause is uploading a non-PCAP file (e.g. a CSV).

**Claude Desktop shows the factory server but tools fail with "connection refused."**
The gateway isn't running. Verify with `make ps` — `cf-gateway` should be up. If not, `docker compose up -d gateway` and check `docker logs cf-gateway`.

**Port already in use.**
Something else is bound to 5001, 8090, or 8091. Stop the conflicting process, or edit `docker-compose.yml` and `services/witness/docker-compose.yml` to change the host-side port.

**The witness build takes longer than 10 minutes.**
First-time builds compile the Cython extensions, which is slow. Subsequent `make up` runs are seconds because the image is cached. If you want to skip the build, contact us about pre-built images (Tier 2 work).

## What's next

- **Replay more PCAPs** to populate the asset database with realistic plant traffic.
- **Live capture** by giving the witness container a real network interface — see the [system architecture](/docs/architecture).
- **Concepts** — read the [concepts &amp; glossary](/docs/concepts) to understand the moving parts before customising or extending.
- **Architecture** — read the [system architecture](/docs/architecture) for the full design.
