Documentation menu
Getting Started

Advanced install

The Quickstart commits to one path: the reference stack with local embeddings, ready in one command. This page is for when you want to go the other way — step by step, from the minimum: run just the engine against your own Postgres, build the image from source, verify the supply chain, and know every knob. Pick the pieces you need.

Platform-only — your own Postgres, the minimum

The leanest footprint: clone the engine on its own and start it with Docker Compose. This is the right choice when you already run Postgres, or simply want the smallest possible thing on disk. Either way the stack is Node 20 + Fastify + PostgreSQL 16 + pgvector, and the database migrations run automatically on first boot.

git clone https://github.com/KvendraAI/kvendra-platform
cd kvendra-platform && docker compose up -d

Verify it is healthy:

curl http://localhost:7777/healthz   # {"status":"ok","schema_version":"v1.0"}

The Platform-only compose ships with EMBEDDINGS_PROVIDER=mock (deterministic stub vectors) so it boots with no external dependency. That is fine for a first health check, but search is non-semantic until you point it at a real provider — see Environment variables below.

Reading the auth token — two different commands

The engine bootstraps a bearer token at /data/auth.token (mode 0600) on first boot, and gates every tools/call on it. Where you read it from depends on how /data is mounted — and the two supported stacks differ:

  • Platform-only (bind-mount): the kvendra-platform compose file mounts ./data:/data, so the token is a real file on your host. Read it directly:
    cat ./data/auth.token
  • Reference stack (named volume): the reference stack mounts a named Docker volume at /data, so there is no ./data/auth.token on the host to cat. Read it out of the running container instead:
    docker exec kvendra-ref-platform cat /data/auth.token

Then register the Platform with your agent. The /setup wizard does all of this for you — what follows is the by-hand equivalent:

TOKEN=$(docker exec kvendra-ref-platform cat /data/auth.token)

claude mcp add kvendra-platform http://localhost:7777/mcp \
  -H "Authorization: Bearer $TOKEN"

Or add the equivalent block to .mcp.json at your project root (or ~/.claude/settings.json):

{
  "mcpServers": {
    "kvendra-platform": {
      "type": "http",
      "url": "http://localhost:7777/mcp",
      "headers": { "Authorization": "Bearer <your token>" }
    }
  }
}

Restart Claude Code (or run /mcp reconnect kvendra-platform) to activate it, then confirm by calling whoami. Once connected, the agent gains 14 MCP tools: entity_get, entity_create, entity_update, entity_archive, entity_related, entity_query, entity_search, txn_create, txn_activate, txn_cancel, txn_check_interrupted, whoami, config_get and help.

Build from source

There is no separate compile-from-source toolchain to learn: building Kvendra Platform means building its Docker image. The image itself is a multi-stage Node 20 build (install production deps, compile TypeScript, assemble a minimal runtime), so a plain docker build against the cloned repo is the from-source build:

git clone https://github.com/KvendraAI/kvendra-platform
cd kvendra-platform && docker build -t kvendra-platform:local .

The reference stack wraps exactly this for regulated environments that must compile every Kvendra-controlled component from public source before running anything. Its scripts/build-from-source.sh clones kvendra-platform, runs docker build, and writes a docker-compose.override.yml pointing the kvendra-platform service at your locally-built image — so the usual ./scripts/up.sh picks it up with no registry pull of the Kvendra bits:

cd kvendra-reference-stack
./scripts/build-from-source.sh
./scripts/up.sh   # uses the override automatically

The upstream base images (node:20-alpine, pgvector/pgvector:pg16, ollama/ollama, postgres:16-alpine) are still pulled from their public registries — they are themselves open-source projects, not Kvendra builds. Rebuilding those from source too is a rarely-needed extra step documented in the reference stack's troubleshooting notes.

Published Docker images are signed

You do not have to build from source to trust the images. Each released Kvendra image is signed with Sigstore/cosign keyless (via GitHub Actions OIDC — there is no long-lived signing key to manage or leak), and each release also attaches a signed SBOM attestation (SPDX JSON, generated by Syft). The Fulcio certificate ties every signature to the KvendraAI/kvendra-platform GitHub Actions workflow, and the signature lands in Sigstore's transparency log (Rekor). Signing has covered every release from the first published tag onwards.

The reference stack ships a one-shot verifier:

cd kvendra-reference-stack
./scripts/verify.sh   # fails if any pinned image signature does not check out

Or verify by hand with cosign (brew install cosign on macOS):

IMG=docker.io/kvendra/kvendra-platform:<version>

# 1. image signature
cosign verify "$IMG" \
  --certificate-identity-regexp '^https://github.com/KvendraAI/kvendra-platform/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

# 2. SBOM attestation
cosign verify-attestation "$IMG" \
  --certificate-identity-regexp '^https://github.com/KvendraAI/kvendra-platform/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --type spdxjson

Both commands exit 0 with a JSON payload when the signature is valid. The SBOM is also attached as a GitHub Release asset for archival and compliance.

Environment variables

Everything is configured through environment variables (the reference stack reads them from .env; the Platform-only compose sets them inline or via its own .env). Most have sane defaults. The full surface:

Embeddings

The provider is resolved at startup. Allowed values are openai-compatible and mock — a third, bedrock, is intentionally not available in the open-core Platform. With openai-compatible you can point at Ollama, vLLM, llama.cpp or any other OpenAI-compatible /embeddings endpoint; what you point it at decides whether anything leaves your infrastructure. Vectors are validated as 1024-dim, so use a 1024-dim model (e.g. mxbai-embed-large); other dimensions fail at request time.

The Quickstart's --with-ollama sets these for you. If you are not using that flag — running the engine on its own, or against an existing Ollama you manage — point embeddings at the local container by hand:

# in .env
EMBEDDINGS_PROVIDER=openai-compatible
EMBEDDINGS_BASE_URL=http://kvendra-ollama:11434/v1
EMBEDDINGS_MODEL=mxbai-embed-large

To use managed embeddings instead of running a model locally, point the same openai-compatible provider at a hosted endpoint and supply a key. For Kvendra Cloud embeddings that is the cloud base URL plus an EMBEDDINGS_API_KEY:

# in .env — managed embeddings (e.g. Kvendra Cloud)
EMBEDDINGS_PROVIDER=openai-compatible
EMBEDDINGS_BASE_URL=https://api.kvendra.cloud/v1
EMBEDDINGS_MODEL=mxbai-embed-large
EMBEDDINGS_API_KEY=<your key>

After editing .env, re-run the stack (or restart the Platform container) so the provider is picked up.

Embeddings are model-specific: vectors are not portable across models (a property of embedding spaces, not a Kvendra limitation). Pick a model and stay on it — switching models, or moving a corpus to a managed provider on a different model, means re-embedding the corpus.

VariableDefaultNotes
EMBEDDINGS_PROVIDER mock (Platform-only) openai-compatible or mock.
EMBEDDINGS_BASE_URL Required for openai-compatible. E.g. http://kvendra-ollama:11434/v1.
EMBEDDINGS_MODEL Required for openai-compatible. E.g. mxbai-embed-large (1024-dim).
EMBEDDINGS_API_KEY unset Bearer token. Omit for local Ollama, which needs no auth.
EMBEDDINGS_TIMEOUT_MS 30000 Per-request timeout in milliseconds.

Postgres & engine

VariableDefaultNotes
POSTGRES_USER kvendra Reference-stack Postgres user.
POSTGRES_PASSWORD kvendra Change it for anything beyond local.
POSTGRES_DB kvendra_platform Database name.
DATABASE_URL Platform-only connection string, e.g. postgres://kvendra:kvendra@db:5432/kvendra_platform.
PORT 7777 Port the engine listens on inside the container.
PLATFORM_HOST_PORT 7777 Reference-stack host-side mapping. Change it if 7777 is taken on your host.
HOST 0.0.0.0 Listen address.
AUTH_TOKEN_FILE /data/auth.token Where the bearer token is generated and read from.
LOG_LEVEL info trace | debug | … | fatal.
STAGE local local | staging | prod.
PG_POOL_MAX 10 Postgres connection-pool size.

Backup sidecar & Ollama (reference stack)

VariableDefaultNotes
BACKUP_CRON 30 3 * * * Cron schedule for the pg_dump sidecar (daily 03:30).
BACKUP_RETENTION_DAYS 14 How many days of dumps to keep before pruning.
OLLAMA_MODELS_PRELOAD llama3.1:8b,mxbai-embed-large Comma-separated models up.sh --with-ollama pulls on first run. Includes the embedding model; trim it if you only need embeddings.
OLLAMA_HOST_PORT 11434 Host-side port for the Ollama container.

Volumes

  • Platform-only bind-mounts ./data:/data (so the token is a host file) and keeps Postgres data in a named volume kvendra_platform_pgdata.
  • Reference stack uses named volumes throughout — kvendra_ref_platform_data (engine /data, incl. the token), kvendra_ref_pgdata (Postgres) and kvendra_ref_ollama_models (Ollama weights) — plus a host ./backups directory for the sidecar's dumps.

Just want it running? Go back to the Quickstart — one command, local embeddings, no signup.