Self-hosting Khiip
Khiip is self-hosted by design — the daemon runs entirely on your machine, against your own accounts and rate-limit budgets, and your data stays in your filesystem. There is no hosted capture service.
Install
Today Khiip installs from source (PyPI publish is on the roadmap):
git clone https://github.com/KhiipAI/khiip.git ~/projects/khiipcd ~/projects/khiippip install -e ".[dev]"Requires Python 3.10+. See Installation for per-source credentials.
Run the daemon
khiipd serve # 127.0.0.1:8478 by defaultkhiipd serve --host 0.0.0.0 --port 8478 # bind on your LAN (see the security note below)The daemon stays in the foreground. To keep it running:
- Quick/dev:
khiipd serve &(backgrounds it in the current shell) - Durable: run it under your OS process manager so it restarts on boot/crash — see Run as a managed service below.
Run as a managed service
For a daemon that restarts on boot or crash, run khiipd serve under your OS process
manager. Find the absolute path to khiipd first with which khiipd — neither systemd
nor launchd inherits your interactive shell PATH, and a virtualenv install puts the
binary under that env’s bin/. Keep your per-source credentials in
~/.config/khiip/config.toml rather than environment variables: the daemon reads that file
no matter how it’s launched, which sidesteps the fact that service managers don’t inherit
your shell environment. (KHIIP_HOME is a dev/test override only — production services
should not set it.)
Linux — systemd user service
Write ~/.config/systemd/user/khiip.service:
[Unit]Description=Khiip capture daemonAfter=network-online.targetWants=network-online.target
[Service]ExecStart=%h/.local/bin/khiipd serveRestart=on-failureRestartSec=5
[Install]WantedBy=default.targetReplace ExecStart with your real which khiipd path (e.g. a virtualenv’s bin/khiipd),
then enable it:
systemctl --user daemon-reloadsystemctl --user enable --now khiip # start now, and on every loginloginctl enable-linger "$USER" # keep running without an active login sessionsystemctl --user status khiip # confirm it's upjournalctl --user -u khiip -f # follow logsmacOS — launchd agent
Write ~/Library/LaunchAgents/ai.khiip.daemon.plist (replace the /Users/you/… paths):
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>Label</key> <string>ai.khiip.daemon</string> <key>ProgramArguments</key> <array> <string>/Users/you/projects/khiip/.venv/bin/khiipd</string> <string>serve</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/Users/you/Library/Logs/khiip.log</string> <key>StandardErrorPath</key> <string>/Users/you/Library/Logs/khiip.err.log</string></dict></plist>Then load it:
launchctl load ~/Library/LaunchAgents/ai.khiip.daemon.plist # start now, and on loginlaunchctl list | grep khiip # confirm it's loadedtail -f ~/Library/Logs/khiip.log # follow logslaunchctl unload ~/Library/LaunchAgents/ai.khiip.daemon.plist # stopBoth services bind 127.0.0.1:8478 by default. To reach the daemon from another machine,
add --host 0.0.0.0 to the serve arguments and read the binding caution above first.
Where your data lives
| What | Default path | Notes |
|---|---|---|
| Config + auth token | ~/.config/khiip/ | config.toml + auth.toml (the API key) |
| SQLite index | ~/.local/share/khiip/index.db | derived cache (vault is canonical; a rebuild-from-vault command is planned — back it up for now, see below) |
| Vault (Markdown captures) | ~/khiip-vault/ | canonical — your source of truth |
| Source-tier raw bytes | [storage] data_root (defaults under ~/.local/share/khiip/) | gzipped originals; insurance against upstream rot |
See Configuration for overrides.
Cross-machine sync
Khiip has no sync server — you bring your own. Point the vault and data_root at synced
storage:
[daemon]vault_path = "~/Library/Mobile Documents/com~apple~CloudDocs/khiip-vault" # iCloud, e.g.
[storage]data_root = "/Volumes/SSD/khiip-data" # external SSD / Dropbox / network mountRun the daemon on one machine at a time against a given vault to avoid write conflicts.
Backup
Because the vault is canonical and the index is derived, a minimal backup is:
~/khiip-vault/— your captures (Markdown + frontmatter). The important one.data_root— the Source-tier raw bytes, if you want the originals preserved.~/.config/khiip/auth.toml— the API key (or just rotate it after a restore withkhiipd auth rotate).
Also back up ~/.local/share/khiip/index.db for now. By design (ADR-0009) it’s a
derived cache reconstructable from the vault — a khiipd rebuild-index command is planned
for exactly that — but that command isn’t shipped yet, so don’t rely on regenerating it.
After any restore, run khiipd validate to check vault ↔ index consistency.
Automating it
A vault backup is just a file copy, so any scheduler works. A nightly rsync to an
external disk via cron, for example:
# crontab -e → run at 02:30 daily30 2 * * * rsync -a "$HOME/khiip-vault/" /Volumes/Backup/khiip-vault/Add your data_root to the same job if you want the Source-tier originals mirrored too.
Upgrading
cd ~/projects/khiipgit pullpip install -e ".[dev]" # picks up new/updated depskhiipd validate # sanity-check the vault ↔ index after upgradeRoadmap
- PyPI publish (
pip install khiip) — planned for the public launch - Docker image + compose — planned; not yet available (install from source for now)