Running rowlab
rowlab is one Python package with two modes.
Local (the default) is one person on their own machine: no sign-in, the server’s own files readable and writable, one SQLite file and one data folder.
uvx rowlab # or: pip install rowlab && rowlab serverowlab serve --host 0.0.0.0 --port 8000Hosted is a shared server: people sign in with WorkOS, everything belongs
to an organisation, and the protections a shared server needs are on: no reading the server’s disk,
no requests to private addresses, saved keys encrypted, runs taking turns. It wants Postgres, S3 and
the hosted extra:
pip install "rowlab[hosted]"See A shared server for the setup, and Configuration for every setting.
With Docker
Section titled “With Docker”The image is ghcr.io/row-and-reason/rowlab, for amd64 and arm64. On its own it is local mode, with
its state in /data:
docker run -p 127.0.0.1:8000:8000 -v rowlab:/data ghcr.io/row-and-reason/rowlabThe repository’s
docker-compose.yml runs
it the way a shared server does: the API and a separate runner, Postgres, and S3 storage
(VersityGW on a folder). It starts in local mode; put
ROWLAB_MODE=hosted and the hosted settings in a .env file next to it to share it.
docker compose upCommands
Section titled “Commands”| Command | |
|---|---|
rowlab serve |
the API, the web app and, unless --no-runner, the runner that processes runs |
rowlab runner |
a runner on its own; with Postgres, start as many as you like |
rowlab mcp |
the MCP server over stdio, for an agent on this machine |
rowlab openapi |
the OpenAPI spec as JSON |
Where things are
Section titled “Where things are”Locally, ~/.rowlab (or ROWLAB_DATA_DIR) holds the SQLite database, the datasets as Parquet and
temporary files. Back it up like any folder; delete it to start over. A saved OpenRouter key is in
the database, never returned by the API, and encrypted when ROWLAB_SECRET_KEY is set.
rowlab sends nothing home: no telemetry, no update checks. Model calls go to OpenRouter with your key, and nowhere else.