§ 04 · Read

Operator quickstart

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

View as .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 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 is the easiest path:
    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). 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

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.

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

make up

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

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 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:

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:

{
  "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 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:

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

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):

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 pscf-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.
  • Concepts — read the concepts & glossary to understand the moving parts before customising or extending.
  • Architecture — read the system architecture for the full design.