homebrew-tap

kavilo-bot tap

This is the public Homebrew tap and APT mirror for the kavilo-bot projects. Three products are published here:

Product What it is brew apt
kavilo A lightweight personal AI assistant — single binary, zero dependencies. brew install kavilo-bot/tap/kavilo sudo apt install kavilo
kavilo-tunnel A cloudflared-style HTTP tunneling client. Exposes a local service via a public URL through a hosted edge. brew install kavilo-bot/tap/kavilo-tunnel sudo apt install kavilo-tunnel
kavilo-hive End-user CLI for an actor-based messaging hub with Signal-protocol E2E encryption. Paired with the kavilo-hived server (Docker image + tarballs in the same releases). brew install kavilo-bot/tap/kavilo-hive sudo apt install kavilo-hive

All three products’ binaries, Homebrew formulas, and .deb packages are hosted in this repo. Client installs from this tap continue to work even when the upstream source repositories (kavilo-bot/kavilo, kavilo-bot/kavilo-tunnel, kavilo-bot/kavilo-hive) go private — everything end-users need is mirrored here under Releases and the GitHub Pages-served APT repo.

Most of this README is the long-form guide for kavilo (the AI assistant). For kavilo-tunnel, jump to the section near the end or read the full user guide. For kavilo-hive, the client and operator guides live under docs/kavilo-hive/ — see user-guide.md for end users and operator-guide.md for running the server.


kavilo

A lightweight personal AI assistant — single binary, zero dependencies.

Contents

Install

macOS / Linux (Homebrew)

brew install kavilo-bot/tap/kavilo

That single command:

  1. taps kavilo-bot/homebrew-tap
  2. downloads the platform-matching binary (darwin_arm64, darwin_amd64, linux_arm64, or linux_amd64) from this repo’s latest release
  3. installs kavilo to $(brew --prefix)/bin/kavilo
  4. registers a brew services definition you can use to keep it running in the background

Direct binary download

Each release ships unversioned aliases so the URLs are stable across versions:

# macOS (Apple Silicon)
curl -LO https://github.com/kavilo-bot/homebrew-tap/releases/latest/download/kavilo_darwin_arm64.zip
unzip kavilo_darwin_arm64.zip && sudo mv kavilo /usr/local/bin/

# macOS (Intel)
curl -LO https://github.com/kavilo-bot/homebrew-tap/releases/latest/download/kavilo_darwin_amd64.zip
unzip kavilo_darwin_amd64.zip && sudo mv kavilo /usr/local/bin/

# Linux (x86_64)
curl -LO https://github.com/kavilo-bot/homebrew-tap/releases/latest/download/kavilo_linux_amd64.tar.gz
tar xzf kavilo_linux_amd64.tar.gz && sudo mv kavilo /usr/local/bin/

# Linux (arm64)
curl -LO https://github.com/kavilo-bot/homebrew-tap/releases/latest/download/kavilo_linux_arm64.tar.gz
tar xzf kavilo_linux_arm64.tar.gz && sudo mv kavilo /usr/local/bin/

# Windows
curl -LO https://github.com/kavilo-bot/homebrew-tap/releases/latest/download/kavilo_windows_amd64.zip

Darwin archives are currently unsigned. macOS Gatekeeper will not block binaries that arrived via brew install, curl, or git, but will warn if you download the .zip from a browser. See Troubleshooting.

Verify the install

kavilo --version
# → 🤖 kavilo v2.0.0-alpha.2

kavilo --help

Quick start

# 1. Initialize ~/.kavilo/ (config, workspace, default skills, templates)
kavilo onboard

# 2. Add a provider API key — open ~/.kavilo/config.json and edit
#    "providers.<name>.apiKey". Common providers:
#
#    openrouter   https://openrouter.ai/keys
#    anthropic    https://console.anthropic.com/settings/keys
#    openai       https://platform.openai.com/api-keys
#    deepseek     https://platform.deepseek.com/api_keys
#    groq         https://console.groq.com/keys
#    gemini       https://aistudio.google.com/apikey

# 3. Talk to the assistant interactively
kavilo agent

# 4. Or one-shot
kavilo agent -m "What is the capital of France?"

# 5. Or run the long-lived service (chat channels, cron, heartbeat)
kavilo start

Out of the box kavilo ships with a sensible default model (anthropic/claude-opus-4-5 via OpenRouter). Override per call with KAVILO_MODEL=... or persistently in config.json under agents.defaults.model.

Run as a background service

Homebrew installs a launchd / systemd service definition so you can keep the runtime alive without a terminal session:

# Start now and on every login
brew services start kavilo

# Check status
brew services list | grep kavilo

# Tail the logs (default Homebrew paths)
tail -f $(brew --prefix)/var/log/kavilo.log
tail -f $(brew --prefix)/var/log/kavilo.err.log

# Stop
brew services stop kavilo

# Restart after editing ~/.kavilo/config.json
brew services restart kavilo

The service runs kavilo start, which spins up:

If you’d rather run it ad-hoc, just run kavilo start in a terminal (or inside tmux so it survives a disconnect).

Configuration

All state lives under ~/.kavilo/:

~/.kavilo/
├── config.json            ← settings, credentials, channels, MCP
├── workspace/             ← prompt files, skills, memory, sessions
│   ├── AGENTS.md          ← system prompt
│   ├── MEMORY.md          ← long-term memory
│   ├── HEARTBEAT.md       ← periodic tasks
│   └── skills/
├── mcp-auth/slack/        ← Slack MCP OAuth tokens (per alias)
├── cron/jobs.json         ← scheduled jobs
├── media/                 ← uploaded media cache
├── usage/                 ← token-usage rollups
├── logs/                  ← runtime logs
└── profiles/<name>/       ← isolated alternate homes (see Profiles)

Minimal config.json

{
  "agents": {
    "defaults": {
      "model": "anthropic/claude-opus-4-5",
      "provider": "auto",
      "maxTokens": 8192,
      "workspace": "~/.kavilo/workspace"
    }
  },
  "providers": {
    "openrouter": { "apiKey": "sk-or-..." },
    "anthropic":  { "apiKey": "sk-ant-..." },
    "openai":     { "apiKey": "sk-..." }
  },
  "runtime": {
    "heartbeat": { "enabled": true, "intervalS": 1800 }
  }
}

provider: "auto" picks the first provider with a configured key at request time. To pin a single provider, set agents.defaults.provider to one of: openai, anthropic, openrouter, deepseek, groq, gemini, dashscope, moonshot, minimax, ollama, vllm, zhipu, etc.

Environment overrides

These shell-env vars override anything in config.json (process-wide, not per-profile):

Variable Effect
KAVILO_MODEL Override agents.defaults.model
KAVILO_PROVIDER Override agents.defaults.provider
KAVILO_API_KEY Override the resolved provider’s API key
KAVILO_API_BASE Override the resolved provider’s base URL
KAVILO_WORKSPACE Override agents.defaults.workspace
KAVILO_HOME Use a different ~/.kavilo root
ANTHROPIC_API_KEY etc. Pick up provider keys from the OS env

Chat channels

kavilo start connects to every enabled channel. Each lives under channels.<name> in config.json and has an enabled flag plus a per-platform allow-list.

Slack (Socket Mode — no public HTTPS)

"channels": {
  "slack": {
    "enabled": true,
    "mode": "socket",
    "botToken": "xoxb-...",
    "appToken": "xapp-...",
    "groupPolicy": "mention",
    "allowFrom": ["U0123ABC"]
  }
}

DMs and @bot mentions become inbound prompts; replies post back into the same thread. Socket Mode means no port forwarding required.

Telegram

"channels": {
  "telegram": {
    "enabled": true,
    "token": "12345:ABC...",
    "allowFrom": ["123456789"],
    "groupPolicy": "mention"
  }
}

Discord

"channels": {
  "discord": {
    "enabled": true,
    "token": "...",
    "allowFrom": ["705222568751267870"],
    "intents": 4609,
    "groupPolicy": "mention"
  }
}

Other supported channels (all opt-in via enabled: true in config.json): dingtalk, email, feishu, mochat, nanorelay, qq, wecom, whatsapp.

groupPolicy accepts mention (default — only respond when @-mentioned in groups) or all. allowFrom is a per-platform allow-list of user IDs or ["*"] to allow everyone.

MCP (Model Context Protocol)

Use kavilo as an MCP server (e.g. in Cursor / Claude Desktop)

kavilo mcp serve <name> runs a built-in MCP server over stdio. Two servers ship out of the box:

Cursor / Claude Desktop entry:

{
  "mcpServers": {
    "kavilo-self": {
      "command": "kavilo",
      "args": ["mcp", "serve", "self"]
    }
  }
}

Connect kavilo to outbound MCP servers

Add entries under tools.mcpServers in config.json:

"tools": {
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp", "--transport", "stdio"],
      "env": { "CONTEXT7_API_KEY": "ctx7sk-..." },
      "toolTimeout": 30,
      "enabledTools": ["resolve-library-id", "query-docs"]
    },
    "my-http-server": {
      "type": "http",
      "url": "https://example.com/mcp",
      "headers": { "Authorization": "Bearer ..." }
    }
  }
}

stdio and streamable-http transports are both supported.

Slack MCP login

# Production (built-in client ID + hosted OAuth callback)
kavilo mcp slack login workspace-alias --team YOUR_TEAM_ID

# Development (your own dev Slack app, loopback callback)
kavilo mcp slack login dev \
    --client-id     YOUR_DEV_CLIENT_ID \
    --client-secret YOUR_DEV_CLIENT_SECRET \
    --redirect-uri  http://127.0.0.1:7898/oauth/callback

kavilo mcp slack status                    # all aliases
kavilo mcp slack status workspace-alias    # one alias
kavilo mcp slack logout workspace-alias    # revoke + delete

Tokens live under ~/.kavilo/mcp-auth/slack/<alias>.json and are injected only at runtime — never written to config.json.

Profiles

Each profile is an isolated KAVILO_HOME directory with its own config, sessions, MCP auth, cron jobs, and workspace.

kavilo profile use work        # sticky switch
kavilo profile show            # active profile + path
kavilo profile list            # all profiles
kavilo profile rm scratch      # delete (asks for confirmation)

# One-shot per-invocation override
kavilo --profile work agent
KAVILO_HOME=/path/to/home kavilo agent

Resolution order, evaluated once at process start:

  1. KAVILO_HOME env (set explicitly or by --profile)
  2. Sticky ~/.kavilo/active_profile
  3. The default ~/.kavilo/

What is and isn’t isolated per profile

Command reference

Command Description
kavilo onboard Initialize ~/.kavilo/
kavilo agent Interactive REPL with the agent
kavilo agent -m "msg" One-shot prompt
kavilo start Start enabled channels + cron + heartbeat
kavilo status Show config / data / workspace / daemon status
kavilo version Print version
kavilo profile {use,show,list,rm} Manage isolated ~/.kavilo/profiles/<name>/ homes
kavilo mcp serve <self\|slack> Run a built-in MCP server over stdio
kavilo mcp slack {login,status,logout} Manage Slack MCP OAuth aliases

All commands accept --profile/-p <name> to pin KAVILO_HOME for that invocation.

Upgrading

brew update
brew upgrade kavilo
brew services restart kavilo   # only if you run it as a service

Uninstalling

brew services stop kavilo
brew uninstall kavilo
brew untap kavilo-bot/tap

# Optional: remove your data
rm -rf ~/.kavilo

Troubleshooting

kavilo: command not found

Check your PATH includes the Homebrew bin directory:

echo $PATH | tr ':' '\n' | grep -E '^/(opt/homebrew|usr/local)/bin$'
which kavilo

If which kavilo returns a stale path (e.g. an old ~/.cargo/bin/kavilo), either remove that copy or reorder your PATH so Homebrew comes first.

kavilo status shows daemon: stopped but you ran kavilo start

The runtime writes a PID file at ~/.kavilo/gateway.pid only on kavilo start. If you started it inside another process manager (or it was killed by SIGHUP when a terminal closed), the file may be missing. Use:

brew services list | grep kavilo
ps -ef | grep '[k]avilo start'

For a persistent foreground run, prefer:

brew services start kavilo      # recommended
# or
nohup kavilo start >> ~/.kavilo/logs/run.log 2>&1 &

macOS “kavilo cannot be opened because the developer cannot be verified”

Darwin binaries in this tap are currently unsigned. Gatekeeper only quarantines binaries that arrived with the com.apple.quarantine extended attribute — typically because you double-clicked a .zip from your browser. brew install, curl, and git do not set that attribute, so binaries installed through them run cleanly.

If you do hit the warning, clear it with:

xattr -dr com.apple.quarantine $(brew --prefix)/bin/kavilo

Provider returns 401 Unauthorized / invalid api key

Check ~/.kavilo/config.jsonproviders.<name>.apiKey, and make sure no shell env var (OPENAI_API_KEY, KAVILO_API_KEY, etc.) is overriding it with a stale value:

env | grep -E '(KAVILO|API_KEY)' 

Logs

Source Where
kavilo start (via brew services) $(brew --prefix)/var/log/kavilo.{log,err.log}
kavilo start (foreground) ~/.kavilo/logs/kavilo-<timestamp>.log
Per-session token usage ~/.kavilo/usage/

Security & sandbox notes


kavilo-tunnel (client CLI)

kavilo-tunnel is the second product in this tap. It’s an entirely separate binary from kavilo and serves a different purpose: expose a local HTTP service on the public internet via a kavilo-tunnel server (cloudflared/ngrok style).

Install

macOS / Linux (Homebrew)

brew install kavilo-bot/tap/kavilo-tunnel

The macOS arm64 binary is codesigned and Apple-notarized, so there’s no Gatekeeper warning on first run.

Debian / Ubuntu (apt)

sudo install -d /etc/apt/keyrings
curl -fsSL https://kavilo-bot.github.io/homebrew-tap/apt/keyring.asc \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kavilo.gpg

echo "deb [signed-by=/etc/apt/keyrings/kavilo.gpg] https://kavilo-bot.github.io/homebrew-tap/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/kavilo.list

sudo apt update
sudo apt install kavilo-tunnel

The same apt repo serves kavilo and kavilo-tunnel; adding the source once gives you both.

Direct binary / .deb download

Versioned assets attached to the kavilo-tunnel-vX.Y.Z tag in the Releases page of this repo. The .deb is also reachable directly from the apt pool: https://kavilo-bot.github.io/homebrew-tap/apt/pool/main/k/kavilo-tunnel/.

Quick start

# 1. Get a token from your kavilo-tunnel operator and log in
kavilo-tunnel login \
  --token <your-token> \
  --endpoint https://<your-base-host>:7777

# 2. Run some local service
python3 -m http.server 3000 &

# 3. Open a named tunnel (stable URL across reconnects)
kavilo-tunnel tunnel --url http://127.0.0.1:3000 --name myapp
# → public URL: https://myapp-<your-slug>.<your-base-host>/

Documentation

See the full user guide in the source repo for:

For operators wanting to run the server side (kavilo-tunneld) or contribute, see the kavilo-bot/kavilo-tunnel repo.


kavilo-hive (E2E messaging hub client)

kavilo-hive is the end-user CLI for an actor-based messaging hub with Signal-protocol end-to-end encryption. You connect to a kavilo-hived server your operator runs and exchange encrypted messages with other actors (people, bots) or fan-out groups over a persistent WSS connection. The server never sees plaintext — every relayed envelope carries opaque libsignal ciphertext.

This tap ships both halves of the system:

Install (client)

macOS / Linux (Homebrew)

brew install kavilo-bot/tap/kavilo-hive

The macOS arm64 binary is codesigned and Apple-notarized, so there’s no Gatekeeper warning on first run.

Debian / Ubuntu (apt)

sudo install -d /etc/apt/keyrings
curl -fsSL https://kavilo-bot.github.io/homebrew-tap/apt/keyring.asc \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kavilo.gpg

echo "deb [signed-by=/etc/apt/keyrings/kavilo.gpg] https://kavilo-bot.github.io/homebrew-tap/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/kavilo.list

sudo apt update
sudo apt install kavilo-hive

The same apt repo serves kavilo, kavilo-tunnel, and kavilo-hive; adding the source once gives you all three.

Direct binary / .deb download

Versioned assets attached to the kavilo-hive-vX.Y.Z tag in the Releases page of this repo. The .deb is also reachable directly from the apt pool: https://kavilo-bot.github.io/homebrew-tap/apt/pool/main/k/kavilo-hive/.

Install (server)

Pull the multi-arch image:

docker pull ghcr.io/kavilo-bot/kavilo-hived:0.1.2

Verify the cosign signature before deploying:

cosign verify \
  --certificate-identity-regexp '^https://github.com/kavilo-bot/homebrew-tap/.github/workflows/build-kavilo-hive-release.yml@.*$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  ghcr.io/kavilo-bot/kavilo-hived:0.1.2

The image ships both /app/kavilo-hived and /app/kavilo-cert-tool (sealed-sender certificate minter), with /app on $PATH.

Quick start

# 1. Operator runs the server, creates a hive + bootstrap code for you
#    (see operator guide).
#
# 2. You initialize a local profile against the server URL.
kavilo-hive config init \
  --server-url https://hive.example.com:8443/h/team-alpha \
  --ca-file ~/Downloads/kavilo-hive-ca.crt \
  --name personal \
  --actor-id alice \
  --actor-role user

# 3. Redeem the bootstrap code (one-shot, short-lived).
kavilo-hive claim --code 123456

# 4. Sanity check.
kavilo-hive health
kavilo-hive whoami

# 5. Send a one-shot message.
kavilo-hive send --to bob --body "ping"

# 6. Or drop into the interactive shell.
kavilo-hive shell

Documentation

For source, protocol design, and threat model, see the kavilo-bot/kavilo-hive repo — in particular docs/adr/0001-signal-level-e2e.md (end-to-end encryption design) and docs/adr/0002-multi-server-federation.md (federation between independent hubs).


License

MIT — see LICENSE.