Get started
From empty laptop to a scoped, leak-proof query in five minutes
This is the one path we recommend you take first. Five commands, every decision already made for you, copy-paste top to bottom. By the end you'll have booted Verity, ingested a real directory, run a permission-filtered query, watched a second agent get zero results on the same data, and wired a live agent over MCP. No menus, no branching — when you want the depth behind a step, follow the link at the end of it.
cargo) and Docker running — that's it. dev pulls a Postgres image, builds the server, and writes its config to ~/.verity/config.toml; you don't install a database or edit a config by hand.
1 · Boot the whole local plane
One command stands up everything Verity needs and leaves you with a working, org-wide scope handle already saved. It is fully idempotent — re-run it anytime.
cargo run --release -p verity-cli -- devwhat you'll see
verity dev — local memory plane, five minutes
✓ postgres docker compose up -d (paradedb pg17)
✓ server http://127.0.0.1:7717 (/healthz ok)
✓ tenant "dev" → c1e6…
✓ scope handle saved to ~/.verity/config.toml (org-wide, principals [1])
✓ config ~/.verity/config.toml
Verity is up.
server http://127.0.0.1:7717
tenant (dev) c1e6…
scope handle saved to ~/.verity/config.toml (org-wide, principals [1])You just booted a Postgres, the Rust server, a dev tenant, and an org-wide scope handle (principals [1]) — the one credential Verity issues. Every command below reuses the handle from that config; you never paste it.
What each piece is, and how to run against an existing server instead: Ingestion → verity-cli.
2 · Ingest something real
Point add at a directory. It recurses over text-like files (.txt/.md/.json/.csv/.html), chunks and embeds each, and uploads them under a scope whose principals are exactly your --visibility tokens. --visibility has no default — Verity never guesses who may see a memory, so you always name it. Here, 1 is the org-wide token from step 1.
verity-cli add ./docs --visibility 1what you'll see
ingesting ./docs (recursive over .txt/.md/.json/.csv/.html, ≤200 files)
1/9 ingestion.html → 34 chunk(s)
2/9 permissions.html → 28 chunk(s)
…
✓ 214 chunk(s) indexed from 9 file(s) — try verity-cli query "<something in it>"You just filled the memory with real, permission-tagged content — and saw the exact chunk count go in. Every one of those chunks carries admin-assigned provenance: the visibility was an explicit decision (--visibility 1), not a mirrored source ACL.
Files, URLs, stdin, entity tags, and narrower visibility: Ingestion → add. Connecting a live SaaS source instead of files: Connecting your systems.
3 · Query it back — scoped, with provenance
Ask a natural-language question. query uses the handle dev saved, runs scoped hybrid recall, and prints each hit with its score, kind, and ACL-provenance tag.
verity-cli query "what does an entity tag do?"what you'll see
1. 0.782 [content] [admin-assigned] Memory is tagged with the entities it concerns (account:acme…
entities account:acme · provenance cli:add
2. 0.741 [content] [admin-assigned] a chunk touching two entities is retrievable only in a scope that…
provenance cli:add
every hit passed the scope's visibility pre-filter in-index — nothing above is post-filtered.You just got a scoped hit back with its provenance visible on the line — admin-assigned tells you exactly how much to trust the filter. There is no post-hoc filtering step to forget: the scope was compiled into the index query itself.
Custom k, raw JSON, and the four provenance tags: Ingestion → query and ACL provenance.
4 · The “aha”: watch the wall hold
Now the thing Verity actually exists to do. Tag a memory to one account, then mint a second scope handle — same org, different entity scope — and prove it can't see it. This is the eve-bot guarantee in miniature, done prescriptively.
First, write a memory tagged to account:acme under your org handle, then mint an Acme scope and a Globex scope from the same principals — entity scope is the only difference:
# read the values dev saved (server, tenant, and the org-wide handle)
export V=http://127.0.0.1:7717
export TENANT=$(grep tenant_id ~/.verity/config.toml | cut -d'"' -f2)
export H=$(grep scope_handle ~/.verity/config.toml | cut -d'"' -f2)
# a memory only an Acme-scoped agent should ever see
curl -s -X POST "$V/v1/episodes" -H 'content-type: application/json' -d "{
\"scope_handle\":\"$H\",
\"observation\":\"Acme's renewal quote is \$84,000 net-30.\",
\"entities\":[\"account:acme\"]}"
# two handles, SAME principals [1], different entity scope — that is the whole trick
mint() { curl -s -X POST "$V/v1/scopes" -H 'content-type: application/json' \
-d "{\"tenant_id\":\"$TENANT\",\"principals\":[1],\"entity_scope\":$1,\"actor_azp\":\"$2\"}" | jq -r .scope_handle; }
ACME=$(mint '["account:acme"]' agent:sales-bot)
GLOBEX=$(mint '["account:globex"]' agent:eve-bot)Now run the same recall under each handle:
# the Acme-scoped agent finds it
curl -s -X POST "$V/v1/recall" -H 'content-type: application/json' \
-d "{\"scope_handle\":\"$ACME\",\"text\":\"acme renewal quote\",\"k\":5}" | jq length
# → 1
# the Globex-scoped agent — same org token, different entity scope — sees nothing
curl -s -X POST "$V/v1/recall" -H 'content-type: application/json' \
-d "{\"scope_handle\":\"$GLOBEX\",\"text\":\"acme renewal quote\",\"k\":5}" | jq length
# → 0You just proved the core property yourself: the second agent holds a legitimate org credential — it is not an outsider — yet it got 0 results, not because a model chose to withhold, but because the entity-scope filter excluded every Acme chunk inside the index query. A prompt-injected “ignore your scope” can't widen it, because the filter was never in the prompt to override.
grep lines above pull $TENANT and $H straight out of the config dev wrote — the same values printed in the step 1 summary. The full multi-agent version — adding restricted pricing, a support purpose-clamp, and org-wide analytics — is the Permissions walkthrough.5 · Connect a real agent over MCP
Finally, hand this memory to an agent. mcp install prints the exact claude mcp add line for your config — identity (tenant, principals, actor) is baked into the environment, never a tool argument the agent can talk its way around.
verity-cli mcp installwhat you'll see
Wire Claude Code to Verity:
claude mcp add verity \
-e VERITY_URL=http://127.0.0.1:7717 \
-e VERITY_TENANT_ID=c1e6… \
-e VERITY_PRINCIPALS=1 \
-e VERITY_ACTOR_SUB=user:me \
-e VERITY_ACTOR_AZP=agent:claude-code \
-- /path/to/verity/target/release/verity-mcp
tools: memory_open_scope, memory_recall, memory_get, memory_remember,
memory_record_action, memory_activity, memory_brief, the ingest trio,
memory_forget, memory_whoami.
re-run with --run to execute this command now.You just got the exact command to give any MCP-capable agent (Claude Code, Cursor, …) permission-aware memory. Run that claude mcp add line — or verity-cli mcp install --run to have it executed for you — and the agent opens a scope with memory_open_scope, then recalls, remembers, and records actions through the same in-index enforcement you just tested.
All 14 MCP tools and when to reach for each: API reference → MCP tools.
Where to next
You have a working, scoped, agent-connected memory. Pick the tier that matches what you're actually doing — each goes as deep as you need and no deeper.
Connect a real system
Trade the file drop for live truth: HubSpot, Salesforce, Google Drive, Postgres. Create a first-party credential, run the backfill, verify it landed scoped, turn on sync.
when you want real source data flowing in, with source ACLs and push freshness. understandUnderstand scoping
The full model behind step 4: principals, entity scope, confidentiality ceilings, HMAC handles, fail-closed semantics, and the exact scoping recipes.
when you need to say precisely who can see what, and prove it. the differentiatorThe knowledge layer
Learn across your customers without leaking them — de-identified, human-gated generalizations that are the one thing safe to cross scopes. No other OSS memory system does this.
when you want org-wide learning, not just per-customer recall.