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 tokenprints it again. - Scripts:
kwnt token --rawprints just the token, to send asAuthorization: Bearer <token>. - The token lives in
<data dir>/api-token(mode 0600), or setKWNT_API_TOKEN(16+ characters).
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
| Environment | What it does |
|---|---|
KWNT_DATA_DIR | Where kwant keeps its database (kwnt.db), account profiles and saved passwords. Default ~/.kwnt. |
KWNT_REQUIRE_TOKEN | always requires the token for local requests too; never turns the check off (only behind your own authentication). |
KWNT_API_TOKEN | Use your own API token instead of the generated one. |
KWNT_ALLOWED_ORIGINS | Extra browser origins allowed to call /api, comma separated. |
KWNT_COMPUTER_MODE | local or vm, unless a choice is saved in Settings. |
LAYA_URL | Where the Laya router answers. Default http://127.0.0.1:8000. |
KWNT_LAYA_MANAGED=0 | Don'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.