Most “AI agent” posts stop at the loop: send a message, run a tool, feed the result back, repeat. That loop is real — I walked through it in Tool Use in Go — but a loop is not a team. A team needs more than one role, a way to hand work across roles, somewhere for state to live when you close the laptop, and a gate before a bot runs something you would rather approve yourself.
This post is a practical path to that shape without writing the harness yourself. The tool is kwant: an open-source (AGPL-3.0), self-hosted team of AI agents packaged as one Rust binary with the web UI and SQLite database inside it. Data lives under ~/.kwnt. It runs as a Mac app, as a Linux app (beta: .deb or AppImage), or on a VPS. Think of it in the same product category as xAI’s Grok Bot, Anthropic’s Claude Duet, and OpenAI’s dots — persistent teammates — except kwant runs on hardware you control, not the vendor’s cloud.
Install steps and feature claims below come from the kwant README and docs. No invented benchmarks.
What “a team” means here
Three properties separate a self-hosted agent team from a single assistant chat:
- Several bots with roles. Architect, TechLead, DevOps — each with its own instructions, voice and model (or
auto). - Shared context and handoffs. Bots sit in the same channel. One finishes a piece of work and
@mentionsanother; the next bot sees the thread. - Work that continues without you. Routines on a schedule, an inbox of what finished or got stuck, and approvals for the steps that should not run silently.
kwant starts a fresh install with three bots in #general on a @core-engineering team: Architect, TechLead and DevOps. You can add more from presets or from scratch. In a channel, it picks the bot that fits a message and shows a one-line reason under the reply. @Architect addresses one bot directly; @core-engineering can trigger a short team discussion that ends in one summary.
That is the product surface this tutorial aims at. Frameworks you wire in Python or TypeScript can do pieces of the same job; they are a different category (you own the runtime, queue and UI).
Pick an install path
You need at least one AI account eventually: the claude CLI (kwant has a Sign in with Claude button), a signed-in codex or grok CLI, or an Anthropic / OpenAI / xAI API key. OpenAI-compatible servers (local or remote) work too once you add them under Settings → This space → Accounts.
Path A — develop from a clone (any OS with Rust + Node)
git clone https://github.com/alexsergivan/kwant.git
cd kwant
make run # builds the web app, then `cargo run -- serve`
Open http://127.0.0.1:8799. On the machine that runs the process there is nothing to sign in to for the UI itself.
make run is required once so frontend/dist exists; the binary embeds that build. The first start also installs the optional Laya router and downloads its model (~420 MB) in the background. Bots still answer while that runs. To skip Laya: cargo run -- serve --no-laya.
Release binary later:
make build
./target/release/kwnt serve
Path B — Mac app
Download the universal .dmg from the latest release (kwant_universal.dmg), drag it to Applications, and open it. The app uses the same ~/.kwnt folder as kwnt serve and stays in the menu bar when you close the window.
The build is signed ad hoc, not notarized by Apple. On first open, click Done, then System Settings → Privacy & Security → Open Anyway (on older macOS, right-click → Open).
Path C — Linux app (beta, x86_64)
-
Ubuntu 22.04+ / Debian 12+: download
kwant_amd64.deb, then:sudo apt install ./kwant_amd64.deb -
Other distros: download
kwant_x86_64.AppImage, then:chmod +x kwant_x86_64.AppImage ./kwant_x86_64.AppImageThe AppImage expects a normal GTK desktop and FUSE.
Updates are signed and applied in-app (the .deb path asks for your password). Removing the package leaves ~/.kwnt alone. Treat Linux as beta: tray, Wayland and HiDPI can vary; there is no ARM Linux or Windows app yet.
Path D — always-on VPS
For routines that must keep running with the laptop closed, run the binary on a server or use the repo’s Docker Compose stack (kwant + Laya + a private Chromium). A short Compose path:
git clone https://github.com/alexsergivan/kwant.git && cd kwant
KWNT_CLIS=claude,codex docker compose up -d --build
docker compose exec kwnt kwnt doctor
docker compose exec kwnt kwnt signin-link
Put TLS in front of 127.0.0.1:8799 and set KWNT_ALLOWED_ORIGINS to your public origin. Full systemd / proxy notes belong in a dedicated VPS post; the README’s self-hosting section is the source of truth until then.
Add an account
If nothing is configured yet, kwant shows a Get ready banner with Add an account.
| You have… | What to do |
|---|---|
| Claude Code CLI | Sign in with Claude in the UI, open the link, paste the code back |
| Codex or Grok CLI | codex login / grok login on the same machine; kwant picks them up |
| API key | Settings → This space → Accounts — Anthropic, OpenAI or xAI. Keys are write-only after save |
| Local / other OpenAI-compatible server | Same Accounts screen; point at your endpoint |
You can keep several accounts per engine (work + personal), set a default and a fallback order. When one runs out of usage, the turn moves to the next and the chat says so. Pin a bot to one account when you need that.
Optional: run kwnt doctor (or Setup in the app) so missing pieces print an install command instead of failing later.
Ask once, then hand work across bots
Open #general and ask something that fits one role — architecture, a quick prototype, a shell check. Watch which bot answers and the reason line under its name. If it picked wrong, use Wrong bot?; kwant remembers the correction for next time.
Then force a handoff the way a real team works:
@TechLead draft a one-page outline for rate-limiting a Go HTTP API.
When you are done, @DevOps list the nginx and process checks you would run before ship.
What you want to see:
- TechLead writes in the shared channel.
- An
@DevOpsmention appears (from you or from TechLead). - DevOps continues with the full thread visible — no copy-paste into a second chat tab.
That @mention pattern is the whole multi-agent trick for day one. You are not writing a graph library; you are naming who owns the next step. The Mission board can turn hand-offs into cards; a card turns Verified only when kwant runs a check itself (for example a file or test check), not when a bot claims it is done. Evidence attachments are for you to read — they do not mark a card verified on their own.
If you have already built tool loops in Go, this is the layer that sits above the agent loop and the Claude client wiring: routing, persistence, and human gates without another weekend of scaffolding.
Spaces: keep work and home from leaking
Each space has its own bots, channels, routines, accounts and approval rules. Nothing crosses the boundary unless you copy it.
A useful first split:
- Work — company Claude / Codex logins, bots that may touch work repos, stricter approvals.
- Home — personal keys or a local model, bots for mail and side projects.
Switch with the space rail (⌘/Ctrl + 1–9 on desktop). This is the feature to set up before you connect an IMAP inbox or a GitHub token: credentials and memory stay where you put them.
Routines and approvals (the safety net)
Say something like “every weekday at 9, summarise what changed in the deploy channel” and let the bot create a routine card with Undo, Edit and Pause. Come back to the Inbox for what is waiting on you, what finished and what failed.
Approvals default to Ask only when risky (smart) on new spaces: ordinary work runs; steps such as git push, network calls, unknown commands or changes outside the bot’s folder show a card with the exact command — Allow once, Always allow or Deny. Payments always ask, in every mode, including a checkout in the bot’s browser behind a plain “Continue”. You can tighten to Ask before running commands, or loosen to Don’t ask, per space or per bot.
Two advanced systems — Flight School (bots earn more freedom per kind of work) and the Truth Ledger (conflicting facts side by side) — ship off until you turn them on. Skip them for the first week.
What this is not
- Not a replacement for writing your own tool-use loop inside a product you ship as code.
- Not a visual workflow builder in the n8n / Dify sense.
- Not a hosted stand-in for Grok Bot, Claude Duet or OpenAI dots: those run on the vendor’s cloud; kwant runs on hardware you control, and you bring the model accounts.
If you want a fair feature-by-feature comparison with other open-source projects in that category, that is a separate article. For getting a team running today, the install paths above are enough.
Checklist
- Clone +
make run, or install the Mac / Linux app - Add at least one account (CLI or key)
- Ask in
#generaland read the “why this bot” line - Run one deliberate
@mentionhandoff between two bots - Create a second space before mixing work and personal accounts
- Try one routine and one approval on a disposable command
- Star the repo and install from the paths above if the shape fits
Conclusion
A self-hosted AI agent team is not magic — it is roles, shared chats, handoffs, schedules and a gate on the dangerous bits. kwant packages that into one binary you can run on a laptop or a VPS, with data in ~/.kwnt and model accounts you already pay for. Start with Path A or the desktop app, get one handoff working, then decide whether Spaces and a small VPS are worth the next evening.
Site and docs: kwant.si. Source and releases: github.com/alexsergivan/kwant — starring the repo (and installing it) is the shortest way to help it show up for the next person searching for a self-hosted team.