Local operations
How to run the local stack, find its credentials, and diagnose the failures people hit most often. Variables are defined in the environment reference; the security rationale is in the security model.
What runs
Section titled “What runs”| Process | Default | Started by | Notes |
|---|---|---|---|
| API (uvicorn) | 127.0.0.1:8000 |
kontext serve |
Serves the API and, when a build exists, the React app. |
| Vite dev app | 127.0.0.1:8002 |
pnpm run dev:local |
Separate from the API; API URL is injected. |
| Job worker | Child process | kontext serve |
Polls queued runs from SQLite; --no-worker disables it. |
| Python kernels | Child processes | Worker | One-shot run kernels and persistent session kernels. |
| Project database | ~/.kontext/kontext.db |
API/worker | SQLite in local mode. |
| Lake/storage | ~/.kontext |
API/worker | KONTEXT_LAKE_PATH or --lake-path overrides the lake root. |
Start and stop
Section titled “Start and stop”Repository checkout:
pnpm run dev:local # API on :8000, Vite on :8002pnpm run dev:app # app only; expects an APIInstalled package:
kontext servekontext serve --open # open the tokenized URLkontext serve --host 127.0.0.1 --port 8000kontext serve --lake-path ./workspacekontext serve --no-worker # API onlykontext serve --reload # uvicorn reloadCtrl-C stops the server and its worker. The worker supervisor restarts a
crashed worker up to five times; KONTEXT_LOCAL_WORKER_ENABLED=false or
--no-worker turns it off.
Launch URL and token
Section titled “Launch URL and token”kontext serve prints the URL to open, the latest token file, and a
tokenized URL of the form http://127.0.0.1:8000/#token=.... The dev launcher
prints the same banner again once both services answer and writes the app URL
to ~/.kontext/runtime/launch.url (plus launch-8002.url).
Recovery files:
| File | Contents |
|---|---|
~/.kontext/runtime/launch.url |
Latest tokenized app URL. |
~/.kontext/runtime/launch.token |
Latest launch token (owner-only). |
~/.kontext/runtime/launch-<port>.token |
Token for a specific API port. |
Open the printed URL rather than the bare host. Use the same origin as the app
(localhost vs 127.0.0.1 are different origins for sessionStorage). The app
reads the fragment, strips it from the address bar, and keeps the token in
sessionStorage for the tab. A new tab can re-bootstrap with the HttpOnly
session cookie.
Restarting the server rotates the launch token, so open the new printed URL.
Previously issued JWTs remain valid until they expire or the signing key is
rotated. To revoke all local sessions, stop the server, delete
~/.kontext/local.key, and restart (or rotate the KONTEXT_JWT_SECRET_KEY /
JWT_SECRET_KEY value if one is set).
Several instances share the same ~/.kontext by default. Use the per-port
launch-<port>.token for recovery, and override HOME, PROJECT_DB_URL, or
--lake-path if the instances must not share a database/storage root.
Common failures
Section titled “Common failures”| Symptom | Likely cause | Fix |
|---|---|---|
401 Missing or invalid local launch token |
Bare URL, an old tab, or a token from a previous run | Open the printed tokenized URL; cat ~/.kontext/runtime/launch.url; restart and use the new URL. |
403 Request rejected: local server host validation failed |
Non-loopback hostname, reverse proxy, or DNS rebinding attempt | Use localhost/127.0.0.1, or add the hostname to KONTEXT_ALLOWED_HOSTS. |
| Login and setup pages bounce | A stale stored token or a mismatched profile/setup state | Open the newly printed URL; hard-reload; clear site data for the origin if needed. |
| Address already in use | API or Vite port conflict | Change --port/KONTEXT_PORT or VITE_PORT; keep the Vite origin in CORS_ALLOWED_ORIGINS (8002/8003/8006 by default). |
| SPA returns 503 | No built app | pnpm --filter @kontext-tech/app build, or pass --dist-dir. |
Jobs stay Queued |
Worker disabled, crashed, or not inherited the database | Check KONTEXT_LOCAL_WORKER_ENABLED, start without --no-worker, and inspect the worker log. |
| SQLite lock or startup timeout | Two processes initializing, or an unsupported SQLite build | Stop both, check ~/.kontext/local-init.lock, restart one server; SQLite 3.51.0/3.51.1 is rejected. |
| Kernel failures | Managed Python environment or repeated infrastructure errors | Check the worker log and KONTEXT_PYTHON_MAX_CONSECUTIVE_KERNEL_FAILURES; a dead session kernel restarts with a fresh namespace. |
| File access denied | The path is outside managed storage and KONTEXT_ALLOWED_PATHS |
Add the directory to KONTEXT_ALLOWED_PATHS or copy the file into managed storage. |
| Model provider errors | Missing/invalid key or endpoint | Set the provider variables in .env.local; see model provider configuration. |
| CORS error in the dev app | API and app origins disagree | Use the documented ports, or extend CORS_ALLOWED_ORIGINS; keep credentials out of a * wildcard. |
Diagnostics
Section titled “Diagnostics”# Is the API up?curl -s http://127.0.0.1:8000/health
# Does the launch token work?curl -s -H "X-Kontext-Launch-Token: $(cat ~/.kontext/runtime/launch.token)" \ http://127.0.0.1:8000/host/auth/bootstrap
# Who holds the port?lsof -nP -iTCP:8000 -sTCP:LISTEN
# What is on disk?ls -la ~/.kontext ~/.kontext/runtimesqlite3 ~/.kontext/kontext.db '.tables'Logs go to the terminal that started the server. Use KONTEXT_LOG_LEVEL and
KONTEXT_LOG_FORMAT for more (or more structured) output; OTEL_* exports
traces to a collector when configured. Avoid DEBUG with real provider keys in
shared logs.
Reset and backup
Section titled “Reset and backup”- Stop the server (and the worker).
- Copy or move
~/.kontextto back up the profile, database, storage, and runtime tokens. - Delete only what you intend to lose:
~/.kontext/kontext.db— projects, runs, chats, connections.~/.kontext/storage— managed files and artifacts.~/.kontext/local.key— invalidates every issued local token when no env JWT secret is configured; rotate the env secret instead when one is set.~/.kontext/runtime— launch URLs/tokens; regenerated on start.
- Restart. A fresh workspace seeds the placeholder profile and project and offers setup again.
Do not delete local-init.lock while a server is starting; investigate the
process holding it first.
Related documentation
Section titled “Related documentation”- Security model — why these controls exist.
- Environment reference — every variable and default.
- Install and start — user-facing setup.
- Python package boundaries — worker/kernel topology and confinement.