Docs

Install & run

kwnt is one self-contained binary with the web app and SQLite built in. Build it once, then run it on your own computer or on a server.

Build the release binary

make build
./target/release/kwnt serve

The binary embeds the web app, so the machine that runs it needs no Node.js. Docker is only needed for VM mode and the bots' shared browser (see Browser).

On your own computer

Run kwnt serve and open http://127.0.0.1:8799. There's nothing to sign in to: requests from this machine need no token, and kwnt serve prints nothing about one.

"This machine" means a loopback connection with a loopback Host and no proxy headers. A VPS you reach through an SSH tunnel counts too:

ssh -L 8799:127.0.0.1:8799 user@your-vps

On a VPS

# 1. Copy the binary to your server
scp target/release/kwnt user@your-vps:/usr/local/bin/kwnt

# 2. Run it
ssh user@your-vps "kwnt serve --host 0.0.0.0 --port 8799"

On a bind other than loopback, kwnt serve prints a ready-to-open sign-in link on its output, never in the log:

http://<this-host>:8799/#kwnt_token=…

Swap <this-host> for the server's address and open the link once. The page signs in with an HttpOnly cookie that lasts a year and clears the address bar.

  • Lost the link? kwnt token prints it again.
  • Scripts: kwnt token --raw prints just the token, to send as Authorization: Bearer <token>.
  • The token lives in <data dir>/api-token (mode 0600), or set KWNT_API_TOKEN (16+ characters).
The link signs in as you. Anyone who can read the server's output, or docker compose logs with Docker, can use it. Keep that output private.

As a systemd service

Create a dedicated user (useradd --system --create-home --home-dir /var/lib/kwnt kwnt), then sign the CLIs in as that user, or add API keys in the app.

# /etc/systemd/system/kwnt.service
[Unit]
Description=Kwant AI agent platform
After=network.target

[Service]
Type=simple
User=kwnt
ExecStart=/usr/local/bin/kwnt serve --host 0.0.0.0 --port 8799
Restart=always
Environment=KWNT_DATA_DIR=/var/lib/kwnt
Environment=LAYA_URL=http://127.0.0.1:8000

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now kwnt

With Docker Compose

docker-compose.yml runs kwant next to a Laya image with the model weights baked in, so the server never downloads them at runtime:

docker compose up -d --build                  # UI on http://127.0.0.1:8799
docker compose logs kwnt | grep kwnt_token    # open that link once
docker compose exec kwnt kwnt token           # print it again later

Requests through Docker's published port arrive from the bridge network, so they count as remote: open the startup link once, using 127.0.0.1 as the host. Data persists in the kwnt-data volume.

Behind an HTTPS reverse proxy

Only the HTTPS port needs to be reachable from outside. Forward the original Host header, because the live browser stream checks Origin against it, and allow WebSocket upgrades:

location / {
    proxy_pass http://127.0.0.1:8799;
    proxy_http_version 1.1;
    proxy_set_header Host $http_host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_read_timeout 90s;
}

Requests carrying proxy headers count as remote, so they need the sign-in link even if the proxy runs on the same machine. Never publish Chromium's debugging port or the Docker socket.

Settings

EnvironmentWhat it does
KWNT_DATA_DIRWhere kwant keeps its database (kwnt.db), account profiles and saved passwords. Default ~/.kwnt.
KWNT_REQUIRE_TOKENalways requires the token for local requests too; never turns the check off (only behind your own authentication).
KWNT_API_TOKENUse your own API token instead of the generated one.
KWNT_ALLOWED_ORIGINSExtra browser origins allowed to call /api, comma separated.
KWNT_COMPUTER_MODElocal or vm, unless a choice is saved in Settings.
LAYA_URLWhere the Laya router answers. Default http://127.0.0.1:8000.
KWNT_LAYA_MANAGED=0Don't install or run Laya; use your own. kwnt serve --no-laya skips it.

~/.kwnt/config.toml can also set host, port, data_dir and the Laya options (laya_url, laya_managed, laya_models). More on Laya is in Models & routing.