Advanced

Headless mode

No UI, background-only — for servers, CI, webhook handlers.

CLI vs headless

The CLI is one-shot — run, exit. Headless is a long-running daemon — it listens on a socket / HTTP port, accepts tasks, keeps sessions warm, persists state. Rule of thumb: CLI for fire-and-forget scripting, headless for webhooks, chatbots, long-running workflows.

Headless skips the renderer and the Electron shell, so it weighs roughly one-fifth of the desktop process and boots in the 200ms range. Comfortable for 24/7 production.

Architecturally, headless is the "backend half" of the desktop app running on its own — agent core, tool runtime, provider routing are all there; only the React UI is missing.

Starting the daemon

# Start headless daemon, bound to a vault
kition daemon start --vault /var/vaults/team --listen 127.0.0.1:7878

# Submit a task to it
kition daemon submit "process pending tickets"

# Stream events from a running task
kition daemon tail task_19af --follow

# Watch the daemon log
kition daemon logs -f

# Stop gracefully (drains in-flight tasks first)
kition daemon stop --drain

HTTP interface

The daemon listens on a local HTTP port and accepts JSON-RPC-style task submissions. Webhook services, Slack bots, internal tools can POST to it directly. Most production setups front it with an auth-aware reverse proxy.

Need an event stream? Set stream: true and the daemon returns NDJSON / SSE — every token and tool call pushed in real time.

curl -s http://127.0.0.1:7878/v1/tasks \
  -H 'content-type: application/json' \
  -d '{
    "prompt": "Triage this issue and label it.",
    "context": { "issue_url": "https://github.com/org/repo/issues/42" },
    "model": "claude-opus-4-7",
    "stream": true
  }'

# Submit and poll
TASK=$(curl -s ... | jq -r '.task_id')
curl -s http://127.0.0.1:7878/v1/tasks/$TASK

Deployment tips

  • Run under systemd / launchd with Restart=on-failure
  • Mount the vault on a persistent volume; snapshot regularly (borgbackup / restic / EBS)
  • Enable the Prometheus exporter (--metrics 127.0.0.1:9090) for QPS, p95, token spend
  • Inject API keys via systemd EnvironmentFile=, never bake them into the unit
  • Front with nginx / Caddy for TLS termination and IP allowlisting
  • Log to stdout; let journald / vector ship it onward
  • An official Docker image ships at ghcr.io/kition-ai/headless:latest

systemd unit example

[Unit]
Description=Kition headless agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=kition
EnvironmentFile=/etc/kition/secrets.env
ExecStart=/usr/local/bin/kition daemon start \
  --vault /var/vaults/team \
  --listen 127.0.0.1:7878 \
  --metrics 127.0.0.1:9090
Restart=on-failure
RestartSec=3
LimitNOFILE=65536
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/vaults/team /var/log/kition

[Install]
WantedBy=multi-user.target

Observability and limits

  • /healthz returns 200 / 503 — slot it into a k8s liveness probe
  • /metrics is Prometheus-formatted: queue depth, active sessions, tokens / minute
  • --max-concurrent N caps concurrent tasks, default 4
  • --task-timeout 10m ceilings a single task to prevent runaways
  • OpenTelemetry: set OTEL_EXPORTER_OTLP_ENDPOINT to auto-export traces
  • Spend budget: --budget-daily 50 caps daily token cost in USD; over-budget submissions return 429

Embedding into your own product

Want to embed the Kition agent inside your own product — without exposing our UI, just borrowing the capability? The headless daemon is the entry point. We also ship a Go sidecar binary (kition-sidecar) that wraps the daemon protocol in gRPC plus a stable SDK, so your Electron / Tauri / server product can integrate cleanly.

This is all part of Kition Pro — the commercial desktop license also covers embedding, billed per end-user seat.

package main

import (
  "context"
  "log"
  "github.com/kition-ai/sidecar-go/kition"
)

func main() {
  c, err := kition.Dial("unix:///run/kition.sock")
  if err != nil { log.Fatal(err) }
  defer c.Close()

  resp, err := c.Run(context.Background(), &kition.RunRequest{
    Vault:  "/var/vaults/team",
    Prompt: "Summarize today's incidents",
    Model:  "claude-opus-4-7",
  })
  if err != nil { log.Fatal(err) }
  log.Println(resp.Text)
}

Related articles

Ready when you are.

Kition is a local-first AI workspace. Markdown documents, structured tables, and an AI agent — running on your own machine, against the model provider you choose.