Skip to content

Installation

boudou edited this page Nov 10, 2026 · 11 revisions

Installation

You need Docker, uv and Git. If you don't have Python 3.12, uv installs it.

flowchart LR
    a["1. Clone"] --> c["2. uv sync"]
    c --> b["3. stratakb db up<br/>Postgres on 5433"]
    b --> d["4. stratakb add<br/>a folder"]
    d --> e["Connect a client"]
Loading

1. Get the code

git clone https://github.com/boudou/StrataKB.git
cd StrataKB

The defaults match the Docker database, so on your own machine you need no settings file. To change the passwords, see Passwords.

2. Install the server

uv sync

This also installs the stratakb command. uv run stratakb add <folder> adds a folder; uv run stratakb receipt <id> opens a receipt (--json for the tool's form); uv run stratakb (or stratakb serve, or python -m stratakb) starts the MCP server.

The server answers its client at once and, with the default local backend, loads the embedding model in the background; a search sent before the model is ready waits for it. The first start downloads the embedding model (about 420 MB) and the first strata_ask downloads the reranker (about 90 MB), both into your Hugging Face cache. After that, both load from the cache, and StrataKB works offline unless you turn on a provider listed in Where your data goes. A model setting that names a folder (EMBEDDING_MODEL=C:\models\mpnet, RERANKING_MODEL=/opt/models/reranker) loads from that folder only: a folder that is missing or holds no model fails with a message naming the setting and the folder, and nothing is downloaded. With HF_HUB_OFFLINE or TRANSFORMERS_OFFLINE set, a model missing from the Hugging Face cache fails with a message naming that variable.

3. Start the database

uv run stratakb db up

This starts PostgreSQL 16 with pgvector in the Docker container stratakb-db, on 127.0.0.1:5433, so it doesn't collide with a PostgreSQL already running on 5432. The data lives in the Docker volume stratakb-data. The command waits until the database accepts connections and builds the schema before it returns.

  • Run it again any time: a running database keeps running and gets any missing schema updates, and a stopped one is started with its data.
  • uv run stratakb db down stops the container and keeps the volume.
  • --port picks another host port when the container is first created.
  • If it prints a DATABASE_URL= line, your settings point at another database: put that line where it says.
  • With no docker on PATH, or the Docker daemon not running, it exits with code 3 and says which.

It creates no strata_readonly role, so strata_db_query and strata_db_explain stay off until you apply db/03_readonly_role.sql (see Roles and Audit); the other strata_db_* tools work without it.

Docker Compose, for development

A checkout also has a docker-compose.yml with the same database on port 5433 (container strata-postgres), which creates the read-only role too. Run docker compose up -d, or stratakb db up, not both on the same port. On the first start of an empty volume, Docker runs these files:

File Creates
src/stratakb/core/sql/01_init.sql Layers, ingestion runs, chunks with their vectors, users and the audit log
src/stratakb/core/sql/02_learning.sql Interactions, feedback, and the synonyms and rewrites the server has learned
db/03_readonly_role.sql The strata_readonly role used by the SQL inspection tools
src/stratakb/core/sql/04_ingested_files.sql The table that tracks each ingested file

The server applies the remaining schema changes itself (see The schema). To start again from scratch, run docker compose down -v. This deletes all data.

Any other PostgreSQL

Any empty PostgreSQL 16 database with pgvector works as well. The server and stratakb add create the schema on first use, as long as the user in DATABASE_URL may create the vector and pg_trgm extensions. Before it creates anything, it names the database it sets up as host:port/database (never the user or password; unknown host when the URL cannot be read safely, such as a password with an unencoded /, ? or #): in the server log (setting_up_database) and on stderr in stratakb add. It refuses to set up in postgres or in a database whose name starts with template, which usually means DATABASE_URL points at the wrong database: create one for StrataKB (CREATE DATABASE strata;) and point DATABASE_URL at it. A StrataKB schema already in such a database keeps working. Use pgvector 0.8 or later for complete results: older versions work, but a filtered search can return fewer results than it asks for, and the server logs hnsw_iterative_scan_unavailable. After upgrading an existing database's image, run ALTER EXTENSION vector UPDATE;. The strata_readonly role is not created for you: apply db/03_readonly_role.sql with psql as the owner of the schemas if you want the SQL tools (see Roles and Audit).

The schema

The schema files ship inside the package. At startup, and before stratakb add writes anything, StrataKB applies every numbered migration the database is missing, in order, and records it in strata_core.schema_migrations. An existing database is brought up to date the same way, so upgrading needs no manual SQL step. If the database user may not change the schema, the error names the SQL file to apply as the database owner; a user without USAGE on the StrataKB schemas is told which privilege is missing. A schema update waits at most 30 seconds for a lock another process holds, then stops and names the lock.

4. Check that it runs

uv run stratakb add path/to/docs

It creates a layer named after the folder and prints what it stored and skipped. See Layers and Presets. No documents at hand? The Python PEPs example fetches a few in seconds. Then connect a client.

Settings

Settings come from four sources, each overriding the one before:

flowchart LR
    d["Defaults"] --> u["User config.env"] --> c["File named by<br/>STRATAKB_CONFIG"] --> e["Environment<br/>variables"]
Loading
Source Where
User config file %APPDATA%\stratakb\config.env on Windows; $XDG_CONFIG_HOME/stratakb/config.env, else ~/.config/stratakb/config.env, elsewhere
STRATAKB_CONFIG Any file you name; a missing file is logged and skipped by the server, and refused by stratakb add
Environment variables Your shell, or the env block of your MCP client's configuration

Copy .env.example to the user config file to start. ./.env is not read unless you set STRATAKB_CONFIG=.env; when the server finds one it does not read, it logs a warning (dotenv_not_read). Keys the server does not know, such as DB_PASSWORD, are ignored, so one file can serve both the server and Docker (see Passwords). Configuration has the full table of settings.

The server keeps the settings it started with for strata_admin_health, strata_search, strata_ask, strata_verify, strata_ingest_documents, strata_apply_preset, query rewriting, the query embedding and the raw-query audit setting: a config file edited while the server runs changes nothing for them until you restart it. The server reads STRATA_USER and STRATA_ROLE once, when it starts; changing either takes a restart.

Passwords

docker compose still reads ./.env itself, for its own variables: DB_PASSWORD, READONLY_DB_PASSWORD and DB_PORT. Unless the server only runs on your own machine, change the passwords before the first docker compose up -d:

cp .env.example .env          # for docker compose

Change DB_PASSWORD and READONLY_DB_PASSWORD in .env, and the matching DATABASE_URL and READONLY_DATABASE_URL in your user config.env (or set STRATAKB_CONFIG=.env so the server reads the same file). The passwords apply when the data volume is created.

Where your data goes

By default nothing leaves this machine except what you choose to send: your documents stay in PostgreSQL, and the embedding and reranking models run in-process. Each other path is off until a setting turns it on.

Path What leaves Turned on by Blocked by STRATA_LOCAL_ONLY
PostgreSQL Documents, chunks, stored queries, audit entries DATABASE_URL (always) No
Your MCP client and its language model Retrieved text, sources Every search and ask No
Anthropic query rewriting Questions and layer descriptions ANTHROPIC_API_KEY Yes
Rewrite endpoint on another host Questions and layer descriptions QUERY_REWRITE_PROVIDER=openai_compatible with QUERY_REWRITE_BASE_URL and QUERY_REWRITE_MODEL set Yes
OpenAI embeddings Documents and questions EMBEDDING_BACKEND=openai without EMBEDDING_BASE_URL Yes
Embedding server on another host Documents and questions EMBEDDING_BACKEND=openai with EMBEDDING_BASE_URL Yes
Hugging Face downloads Nothing about your documents; model files come in The first start, the first stratakb add and the first strata_ask Yes

A rewrite endpoint or embedding server on this machine (127.0.0.1, ::1 or localhost) is allowed with the switch on.

With STRATA_LOCAL_ONLY=true the server refuses to start while any blocked path is configured, and the error names each setting that caused it. strata_search, strata_ask, query rewriting, strata_ingest_documents and strata_apply_preset use the settings the server started with, so a config file edited while the server runs changes nothing for them until a restart. That includes the switch for the outbound providers: turning STRATA_LOCAL_ONLY on in a config file stops them only after a restart, though a model the server has not loaded yet is kept from downloading at once. Models load from local files only; a model that is not installed fails with a message that says how to install it. The switch does not cover the database: DATABASE_URL may point at a shared database on purpose. Every embedding path (strata_search, strata_ask, strata_ingest_documents, strata_apply_preset, stratakb add, scripts/apply_preset.py) checks its setup before any work, so strata_ask never sends a question to the rewrite provider ahead of a search that cannot run: an unknown EMBEDDING_BACKEND, openai without OPENAI_API_KEY or EMBEDDING_BASE_URL, or a blocked path fails and names the setting. stratakb add then refuses with exit 2 (reason local_only or embedding_setup in --json) and writes nothing. The OpenAI and Anthropic SDKs also read OPENAI_BASE_URL and ANTHROPIC_BASE_URL; StrataKB treats them as the destination of those paths, and STRATA_LOCAL_ONLY checks them too. Requests to EMBEDDING_BASE_URL and QUERY_REWRITE_BASE_URL never carry OPENAI_API_KEY, OPENAI_ADMIN_KEY, OPENAI_ORG_ID or OPENAI_PROJECT_ID.

strata_admin_health always lists the switch (local_only) and the active outbound providers (outbound: provider, purpose, what it sends, destination host and the setting that turns it on). The outbound list never shows keys, credentials, paths or ports. An endpoint URL that cannot be read safely (an unencoded /, ? or # in its password, or an @ in its path or query) shows as unknown host and counts as leaving the machine, so STRATA_LOCAL_ONLY refuses it even when it points at this machine; percent-encode such characters.

StrataKB cannot control what your MCP client's language model does with the retrieved text. If the client uses a cloud model, the retrieved text goes to that provider.

Development install

uv sync --extra dev
uv run pytest                  # the integration tests need the database running
uv run ruff check src tests

See CONTRIBUTING.md before opening a pull request.

Clone this wiki locally