Operate
This page covers the kindo-cli commands an operator will touch most often after the install completes. Before you pick up this page, the install should already be healthy (see Configure & Validate).
CLI daily-drivers
| Command | Purpose |
|---|---|
kindo status | Install-state summary from the cluster ConfigMap |
kindo config edit | Edit install-contract.yaml and re-sync the cluster secret |
kindo config apply | Regenerate per-app <app>-env Secrets and rollout-restart deployments |
kindo config validate --preflight | Schema check + infrastructure connectivity test |
kindo config override list | set | unset | Manage per-service env var overrides in the centralized config |
kindo config override edit | diff | apply | Bulk-edit overrides, preview changes, and push them to the live Secrets |
kindo db list | Enumerate the six Postgres databases |
kindo db tunnel <database> | Open a port-forward tunnel to a database |
kindo db prompt <database> | Interactive psql session over a tunnel |
kindo db reset [database] | Drop all tables (destructive, requires two confirmations) |
kindo integrations list | Show available and enabled MCP integrations |
kindo integrations enable <name> | Enable an integration in the contract |
kindo integrations disable <name> | Disable an integration in the contract |
kindo integrations apply | Deploy enabled integrations (Nango registration + MCP pods) |
kindo integrations bootstrap | Re-run integration registration against the cluster |
kindo integrations status | Live integration status from the cluster |
kindo uninstall all | applications | peripheries | Tear down a group of releases |
kindo status
Check install state any time. The state lives in the kindo-install-state ConfigMap in kindo-system, so the answer is the same from any workstation with cluster access:
kindo statusExpect a table with one row per install step (generate-secrets, merge-bindings, setup-registry, db-bootstrap, peripheries, hatchet-token, migrations, applications, post-install). Anything other than completed for all rows on a fresh install is a signal to stop and investigate — kindo install --resume picks up from the failed step.
kindo config edit and kindo config apply
These two commands are the safe path for changing any non-infrastructure setting after the install. edit opens install-contract.yaml in $EDITOR, validates the result against the schema, and re-syncs the updated contract into the kindo-secrets-config Secret in kindo-system. apply reads that Secret, regenerates the per-app <app>-env Kubernetes Secret for every application whose inputs changed, and issues kubectl rollout restart deployment/<app> so each pod picks up the new values without downtime.
# Edit SMTP settings, admin email, a model, or an integration flagkindo config edit
# Push the changes to the cluster: rebuilds <app>-env Secrets and restarts podskindo config applykindo config apply is also the recommended follow-up after any manual edit of the contract file. If you only changed one service, narrow the blast radius:
kindo config apply --app apikindo config validate --preflight is the pre-flight check you can run before committing a change — it verifies schema validity and reruns the connectivity tests against Postgres, Redis, RabbitMQ, and object storage.
kindo config override
Use kindo config override when you want to change a single env var on a running service without editing the contract or running a full upgrade. Common cases: shortening SESSION_MAX_AGE_HOURS, pointing NEXT_PUBLIC_NANGO_CONNECT_URL at a different hostname, rotating a third-party API key. Overrides live under serviceOverrides.<service>.<ENV_KEY> in the centralized kindo-secrets-config Secret and are honored on every subsequent upgrade — precedence is overrides > live secret > generated defaults.
# Set one or more env vars on a service (scriptable)kindo config override set next SESSION_MAX_AGE_HOURS=4
# Push the staged change into the live <service>-env Secret and rollout podskindo config override apply next
# Preview what `apply` would change against the live cluster (values redacted)kindo config override diff next
# Bulk-edit the whole overrides subtree (or just one service) in $EDITORkindo config override editkindo config override edit next
# Remove an override; the next `apply` deletes the key from the live Secretkindo config override unset next SESSION_MAX_AGE_HOURSkindo config override apply next
# Inspect what is currently stagedkindo config override listkindo config override list next --format=yamlapply records the keys it writes in a kindo.ai/override-keys annotation on the live Secret, so unset followed by apply correctly removes the key — merge patches alone could not. Keys that already exist in the live Secret but are not in the override set (e.g. chart defaults, values applied manually via kubectl patch) are reported as “stray” and left untouched; pass --force to apply anyway. See Overrides runbook for the validation rules, troubleshooting table, and end-to-end examples.
kindo db
Six databases are deployed. The names are stable — use them with tunnel, prompt, and reset.
| Database | Backs |
|---|---|
main | api, credits, external-sync, external-poller, task-worker-ts, audit-log-exporter, cerbos |
ssoready | SSO authentication service |
litellm | LiteLLM proxy and model catalog |
hatchet | Hatchet workflow engine |
nango | Nango OAuth integration service |
unleash | Unleash feature flags |
kindo db tunnel launches a disposable alpine/socat pod in the cluster, port-forwards from localhost:15432 (override with --port), and prints a ready-to-use psql URL. The tunnel stays up until you Ctrl+C:
kindo db tunnel main# ✓ Tunnel active on localhost:15432# Connect with:# psql 'postgresql://admin:***@localhost:15432/kindo_apps?sslmode=require'kindo db prompt wraps the tunnel + psql handoff in one command. Use it for quick inspections:
kindo db prompt litellmkindo db reset drops every table, sequence, and enum type in the public schema of the named database. It is the right answer when a dev environment’s data is corrupt and the wrong answer for anything production-adjacent. Two confirmations are required for --all:
# Reset a single DB (one confirmation)kindo db reset hatchet
# Reset every DB (two confirmations)kindo db reset --allAfter a reset, re-run kindo install --step migrations to recreate the schema and kindo install --step post-install to rebootstrap admin users, models, and feature flags.
kindo integrations
MCP integrations (Slack, GitHub, Jira, …) are declared in install-contract.yaml under the integrations: block. The CLI is the source of truth for enabling and disabling them; edit the contract directly only if you know what you are doing.
# See what is available and which are enabledkindo integrations list
# Enable two integrations (prompts for OAuth creds where needed)kindo integrations enable github slack
# Deploy: registers integrations with Nango and deploys any legacy MCP podskindo integrations apply
# Re-run integration registration without deploying pods (e.g. after a Nango reset)kindo integrations bootstrap
# Live status from the cluster: unified-MCP health + per-legacy-MCP Helm releaseskindo integrations status
# Turn one offkindo integrations disable slackkindo integrations applyMost integrations run inside the shared mcp-unified pod in the mcp namespace. A small number of legacy TypeScript MCPs still ship as their own Helm release — kindo integrations status shows both.
kindo uninstall
Three scopes are available. Each is confirmed interactively unless you pass --force:
# Tear down applications only (keeps peripheries and databases running)kindo uninstall applications
# Tear down peripheries only (Unleash, Qdrant, Presidio, Speaches, Hatchet)kindo uninstall peripheries
# Full teardown, preserving PVCs and the kindo-secrets-config Secretkindo uninstall all --keep-data
# Full teardown including secrets config and all Kindo namespaceskindo uninstall all --delete-namespacesuninstall all reverses install order: post-install → applications → peripheries → bootstrap. The kindo-secrets-config Secret and the kindo-install-state ConfigMap are preserved by default so you can reinstall against the same infrastructure without regenerating credentials. Pass --delete-namespaces for a fully clean slate.