What I learned reading and building with Kuru, an open-source agent platform
Description and use
Kuru adds approval cards for risky actions and secure desktop streaming via phone, improving safety and usability for single-owner deployments.
Problem
Need a self-hosted agent platform that allows safe, human-approvable actions and live desktop control via phone.
Outcome
Kuru adds human-in-the-loop approval for destructive actions and secure, non-exposed desktop access, improving safety and usability for single-owner deployments.
Workflow
- 1. Agent requests a risky tool call.
- 2. auto-review.ts classifies risk and hashes the call.
- 3. If risky, a pending approval row is created and a card is sent to the chat.
- 4. Human approves or denies via the card; approval is single-use.
- 5. Approved call is retried with approval ID and executed.
- 6. For desktop control, phone connects through core server via Cloudflare Tunnel.
- 7. screen-proxy.ts verifies ownership, starts desktop session, and proxies VNC over the tunnel.
Evidence
When an agent wants to do something risky — rm -rf outside its own folders, dd if=, git push --force, curl | sh, dropping a database, deleting a YouTube video — the call doesn't run. Instead a card appears in the chat: "Needs approval", with the exact tool call and its arguments, and buttons to approve, deny, or "Always allow".
Approvals are single-use. An approved row carries a usedAt timestamp; the second identical call hits "That approval was already used. Ask the person again."
Workers pause instead of dying. There's a comment in the file explaining that a blocked background worker used to get stopped and restarted blank once the person tapped Approve — losing everything it had done.
Every agent gets a Linux container with a real desktop (not a headless shell — X, a browser, a visible window manager). The phone app has a "watch this screen" view that streams the desktop over VNC and lets you take over the mouse and keyboard if the agent is stuck in a dialog loop.
- Record date: 2026-11-03T07:28:50.436Z