Privacy Model
Pretensor is designed to give an agent enough structural understanding of your schema to write correct queries — without ever putting row contents on its lap. This page is the precise boundary.
What Pretensor reads from the database
Section titled “What Pretensor reads from the database”At index time, the connector reads from the database’s system catalog:
- Schema metadata — table and column names, data types, nullability, primary and foreign-key constraints, comments, view definitions, trigger targets.
- Aggregate column statistics — for tables under ~10M rows, distinct counts, min and max values, null percentages, most-common values (capped at ~20), and histogram bounds. These are aggregates, not row samples.
- Catalog metadata — row counts (from
pg_stat_user_tables/INFORMATION_SCHEMA), grants, last-accessed timestamps where the database exposes them. - Optional dbt enrichment — if you pass
--dbt-manifest(and optionally--dbt-sources), the dbt manifest is layered onto the graph asLINEAGEedges and metadata.
What Pretensor does not read: raw row data. There is no SELECT * FROM your_table in any code path.
Where the graph lives
Section titled “Where the graph lives”The result is a Kuzu file under .pretensor/ (or wherever --state-dir points). You own the file. Pretensor does not upload it, sync it, or phone home — the OSS distribution has no network egress at all once indexing finishes. If you delete the file, you delete the graph.
The one place Pretensor writes outside the state directory is MCP client registration during pretensor init. When you confirm a client (or name it with --client), init edits that client’s own config file: Claude Desktop’s claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, ~/.config/Claude/ on Linux, %APPDATA%\Claude\ on Windows) or Cursor’s mcp.json (.cursor/mcp.json in the project or ~/.cursor/mcp.json). Claude Code is registered through its own claude mcp add CLI instead of a config file edit. In every case, init asks per client before writing and takes a timestamped backup of the existing file first.
Indexing also writes a compact agent-guidance file (a SKILL.md) under .claude/skills/pretensor-<name>/ by default. --skills-target cursor or --skills-target /custom/path redirects it. The skill file describes the indexed graph; it does not contain row data.
What flows to your agent
Section titled “What flows to your agent”When pretensor serve is running, your agent invokes MCP tools and gets back results from the Kuzu graph — never a SELECT against your source database. After indexing, no row data ever flows from the source database to the agent: the agent talks to the MCP server, the server reads from the local Kuzu file.
The full tool surface — input parameters, return shapes, and when to use which — lives at MCP Tools. Highlights for the privacy boundary:
- All tools are read-only. The
cyphertool rejects mutating and I/O keywords (CREATE,DELETE,SET,COPY,EXPORT,DROP, …) at the tool layer. - The
detect_changestool compares a live schema to the last indexed snapshot without mutating the graph — it reports what would change, it does not re-index. - Read-only resources at
pretensor://databases,pretensor://db/{name}/overview,pretensor://db/{name}/clusters, andpretensor://db/{name}/metricsreturn aggregated Markdown views built from the same Kuzu file. No row data, no live database access at serve time.
Visibility profiles
Section titled “Visibility profiles”Sensitive tables and columns can be hidden two ways:
- Index-time —
pretensor index --visibility visibility.yml --profile analystdrops hidden objects from the graph entirely. They never get written. - Serve-time —
pretensor serve --visibility visibility.yml --profile analystre-applies the filter to the live graph. The same Kuzu file can be served under different profiles to different agents without re-indexing.
Rules use fnmatch globs and apply at the schema, table, or column level. A visibility.yml looks like:
hidden_schemas: - information_schemahidden_tables: - public.audit_*allowed_tables: - public.customer - public.paymentprofiles: analyst: allowed_tables: - public.customer - public.rentalIf you want to derive role-keyed profiles directly from your database’s GRANTs, pretensor sync-grants --dsn <dsn> --output .pretensor/visibility.yml writes one for you.
An agent on the analyst profile cannot see, traverse, or query objects hidden by that profile — they’re not present in the graph it has access to.
Determinism
Section titled “Determinism”Pretensor’s intelligence pipeline (classification, clustering, join-path precomputation) is deterministic — no runtime LLM calls in the OSS distribution. Heuristic and statistical signals only. Same input, same output.