Repository navigation
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"]
git clone https://github.com/boudou/StrataKB.git
cd StrataKBThe defaults match the Docker database, so on your own machine you need no settings file. To change the passwords, see Passwords.
uv syncThis also installs the stratakb command. uv run stratakb add <folder> adds a folder; uv run stratakb (or stratakb serve, or python -m stratakb) starts the MCP server.
The server answers its client at once and 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.
uv run stratakb db upThis 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 is left alone, and a stopped one is started with its data.
-
uv run stratakb db downstops the container and keeps the volume. -
--portpicks 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
dockeronPATH, or the Docker daemon not running, it exits with code 3 and says which.
It creates no strata_readonly role, so the SQL inspection tools stay off until you apply db/03_readonly_role.sql (see Roles and Audit).
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 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. 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 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.
uv run stratakb add path/to/docsIt 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 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"]
| 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). The README has the full table of settings.
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 composeChange 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.
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
|
Yes |
| OpenAI embeddings | Documents and questions |
EMBEDDING_BACKEND=openai without EMBEDDING_BASE_URL
|
Yes |
| Embedding server on another host | Documents and questions | 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. The embedding calls and query rewriting check the switch again on every call. 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 team server on purpose.
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). It never shows keys, credentials, paths or ports.
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.
uv sync --extra dev
uv run pytest # the integration tests need the database running
uv run ruff check src testsSee CONTRIBUTING.md before opening a pull request.
Getting started
Using StrataKB
Reference
Help