Installation
Valved is a Python CLI plus a Postgres-backed state store. It is Postgres-from-day-one — there is no SQLite fallback.
Requirements
Section titled “Requirements”- Python 3.11+
- Postgres 14+ — either the bundled
docker-compose.yml(recommended for local dev) or your own (managed RDS, Cloud SQL, Supabase, etc.) - Docker — only if you use the bundled Postgres path.
valved initchecks for it up front: no Docker and no--external-postgresand it exits3with a message telling you to do one or the other, before writing anything. - An Anthropic API key (or Claude OAuth token) for the AI harness — see Configuration
Install
Section titled “Install”Pick your favorite Python tool:
pipx install valved# oruv tool install valved# orpip install --user valvedAfter install, valved version should work.
First run with bundled Postgres
Section titled “First run with bundled Postgres”mkdir my-valved-project && cd my-valved-projectvalved init # writes valved.toml, valved/, .env.example, .gitignore, docker-compose.ymldocker compose up -d # starts Postgres on 127.0.0.1:5432valved serve # API + scheduler + reaper + archiver + worker poolBehind the scenes:
valved initwritesvalved.toml, thevalved/config dir (connections.toml,models.toml,runner.toml, and the memory files),.env.example,.gitignore, an emptyel/, anddocker-compose.yml(the bundled-Postgres template). It also runsgit initunless you pass--no-git-init.valved initthen tries to bring the state-store schema to head. With bundled Postgres it usually can’t — the compose file was only just written — so it printsPostgres isn't running yet — schema not initializedand moves on. That is expected, not an error.docker compose up -dbrings up Postgres at the URL the.envtemplate expects:postgresql+psycopg://valved:valved@127.0.0.1:5432/valved.valved servebrings the schema to head, then starts accepting CLI / REST / MCP requests.
valved init takes --project-name <name> to override the project name (there is no --name), --default-target <name> to name the default target something other than dev, and --with-dbt / --with-dlt (or the --dbt-path / --dbt-url / --dlt-path / --dlt-url brownfield variants) to scaffold or adopt components.
Running more than one Valved project on one machine
Section titled “Running more than one Valved project on one machine”Containers and volumes are namespaced per project, but the host port is not: every bundled project’s DATABASE_URL defaults to 127.0.0.1:5432/valved. The second project’s Postgres cannot bind the port, and its commands resolve to whichever store is already listening there.
Give each project its own port before valved init, setting both values in that project’s .env — they have to agree:
VALVED_POSTGRES_PORT=5433DATABASE_URL=postgresql+psycopg://valved:valved@127.0.0.1:5433/valvedIf you skip this, valved init notices rather than proceeding. Since 0.4.4 it refuses to run migrations against a database that already holds a Valved schema, exiting 2 and naming what it found. Pass --adopt-existing only if sharing that store is genuinely what you want — and note that pipelines are keyed by name alone, so two projects’ pipelines with the same name are the same row.
Re-running valved init in a directory that already has a valved.toml is unaffected: that is the project’s own claim on its store, so upgrades still work without a flag.
First run with external Postgres
Section titled “First run with external Postgres”If you already operate Postgres (managed RDS / Cloud SQL / Supabase / a local install):
valved init --external-postgres "postgresql+psycopg://user:pass@host:5432/db"# add the DATABASE_URL line init prints to .env, then:valved serve--external-postgres does two things: it skips the docker-compose.yml scaffolding, and it treats that Postgres as already-running — init connects and runs the migrations immediately. If the host is unreachable or the user can’t CREATE TABLE, init exits 3 after writing the project files.
It does not write your connection string into .env. Deliberately: the URL carries a password and .env.example is a committed file. init prints the line for you to paste into the gitignored .env, and leaves only a commented placeholder in .env.example:
! External Postgres: bundled docker-compose not generated. Valved will notmanage your Postgres lifecycle (backups, upgrades, tuning are yours). Add this line to your .env (gitignored): DATABASE_URL=postgresql+psycopg://user:pass@host:5432/dbThe URL is used as-is for that one migration and stored nowhere. Afterwards every command resolves the state store from the DATABASE_URL env var, falling back to the bundled default postgresql+psycopg://valved:valved@localhost:5432/valved. So until you add that line to .env, valved serve points at a bundled Postgres you never started.
Set your model credentials
Section titled “Set your model credentials”The harness needs a model provider. Set one before you plan or build:
cp .env.example .env# then edit .env to add ANTHROPIC_API_KEY (or a Claude OAuth token)valved auth status # verify the harness can see a credentialSee Configuration → valved/models.toml for API-key vs OAuth and model tiers.
Verify the install
Section titled “Verify the install”curl -s http://127.0.0.1:8765/healthz # livenesscurl -s http://127.0.0.1:8765/readyz # readiness (200 once migrations are at head)valved runsreadyz is 200 only when Postgres is reachable and the schema is at head. Anything else is a 503 whose body names the reason — database unreachable: <ExceptionClass> (usually a DATABASE_URL pointing somewhere that isn’t there) or migrations not at head (at <rev>, head <rev>). Both /healthz and /readyz are unauthenticated probes.
If you scaffolded a dbt project
Section titled “If you scaffolded a dbt project”valved init --with-dbt gets you a dbt project, but not a runnable one. Two things are still missing and neither is written for you:
- A
[components.dbt]block invalved.toml, andvalved connect dbtto install and pin the engine. Without it the dbt engineer is never granted itsdbt_verifytool, so it authors models without executing them. - A
profiles.yml. Nothing in Valved generates one.dbtrun by hand fails until you supply it.
Both are covered in step 4 of the Quickstart.
Where to go next
Section titled “Where to go next”- Quickstart — build your first pipeline end-to-end
- The core loop — how plan → build → run → deploy fit together
- MCP server — drive Valved from Claude Desktop / Cursor / Claude Code