Use Cases
Pretensor is most valuable when an agent has a question that’s answerable from schema structure alone — joins, lineage, blast-radius, “what’s even in this database.” Each section below pairs a real task with the tool that handles it. Tool inputs, return shapes, and full reference live at MCP Tools.
Find a join path you don’t know
Section titled “Find a join path you don’t know”Task. An agent needs to JOIN orders to customer_demographics but the FK is implicit — they share a customer_id but no constraint enforces it across schemas.
Call. traverse with from_table=orders, to_table=customer_demographics, database=warehouse. Pretensor returns the best-cost path drawn from precomputed FK and inferred-join edges:
{ "from": "orders", "to": "customer_demographics", "database": "warehouse", "paths": [ { "confidence": 0.92, "ambiguous": false, "semantic_label": "orders placed by a demographic segment", "steps": [ /* one hop per join, FK before inferred */ ], "sql_hint": "JOIN customer USING (customer_id) JOIN customer_demographics USING (customer_id)" } ], "used_precomputed": true}Why it matters. No more “the model invented a JOIN that doesn’t exist” — the path comes from the indexed graph, with FK paths preferred over inferred ones, and inferred hops capped via max_inferred_hops.
Scope the blast radius of a schema change
Section titled “Scope the blast radius of a schema change”Task. A DBA is about to drop customer.legacy_id. What downstream tables and dbt models break?
Call. impact with table=customer, column=legacy_id, database=prod, max_depth=4. The response groups affected tables by hop distance and confidence:
{ "target": { "table": "customer", "column": "legacy_id" }, "database": "prod", "impact": { "direct": [ /* FK children, each with its code `consumers` if analyzed */ ], "two_hop": [ /* second-degree downstream */ ], "three_hop": [ /* third-degree downstream */ ], "low_confidence": [ /* inferred-edge matches below the confidence bar */ ] }, "total_affected": 17}Why it matters. Same boundary an experienced engineer would reason about — but instant, comprehensive, and resilient to renames (the indexer matches on column-content patterns, not just names).
Discover the right table for a fuzzy business question
Section titled “Discover the right table for a fuzzy business question”Task. A product manager asks the agent for “customer revenue last quarter.” The agent doesn’t know whether the data lives in daily_sales, customer_invoice_summary, or some dbt mart.
Call. query with q="customer revenue". BM25-ranked hits over table descriptions, dbt aliases, column comments, and entity metadata:
{ "query": "customer revenue", "db": "analytics", "results": [ { "node_type": "SchemaTable", "name": "fct_customer_revenue_daily", "database_name": "analytics", "connection_name": "warehouse", "description": "Daily revenue per customer (dbt)", "snippet": "…revenue_usd…", "score": 8.3 }, { "node_type": "SchemaTable", "name": "stg_invoices", "database_name": "analytics", "connection_name": "warehouse", "description": "Staged invoice lines", "snippet": "…invoice amount…", "score": 6.1 } ]}The agent then calls context on the top candidate to get columns, joins, lineage, and cluster — enough to write a correct query without guessing.
Validate an LLM-authored query before execution
Section titled “Validate an LLM-authored query before execution”Task. An agent has just written a SQL statement to answer a user’s question. Before showing it to the user (or, worse, running it), you want a structural sanity check.
Call. validate_sql with the SQL and the target database. The response calls out missing tables, missing columns, and broken joins, with nearest-name suggestions:
{ "valid": false, "missing_tables": [], "missing_columns": [ "orders.cust_id" ], "invalid_joins": [], "suggestions": [ "Column 'cust_id' not found on 'orders' — did you mean 'customer_id'?" ]}Why it matters. Cheaper than a query-failure round-trip against the warehouse, and it catches typos and stale-schema drift the model has no way to know about on its own.
Detect schema drift before trusting the graph
Section titled “Detect schema drift before trusting the graph”Task. A scheduled agent runs nightly. Today’s prompt asks it to JOIN through tables that may have been renamed since the last index.
Call. detect_changes against the live database. It diffs INFORMATION_SCHEMA (or the Snowflake/BigQuery equivalent) against the snapshot the indexer wrote, and returns a structured changelist:
{ "database": "prod", "last_indexed": "2026-08-01T02:00:00Z", "checked_at": "2026-08-15T02:00:00Z", "changes": [ { "type": "table_added", "target": "public.customer_v2", "schema": "public", "table": "customer_v2" }, { "type": "column_dropped", "target": "public.customer.legacy_id", "schema": "public", "table": "customer" } ], "graph_impact": { /* affected nodes and edges */ }, "affected_join_paths": [], "affected_metrics": [], "summary": "1 table added, 1 column dropped", "recommendation": "Run `pretensor reindex` to pick up 2 schema changes."}When nothing changed, the response is compact and carries up_to_date: true instead.
The tool is read-only — it doesn’t re-index. The agent decides whether to call pretensor reindex or fall back to a different strategy.
Trace a metric back to its source tables
Section titled “Trace a metric back to its source tables”Task. A finance analyst wants to know how daily_revenue_per_region is actually computed. Which raw tables, which transformations, which dbt models?
Call. context with table=daily_revenue_per_region, db=analytics, detail=full. The response includes columns, classification (role + confidence), incoming LINEAGE edges (the source tables and dbt models that feed it), outgoing LINEAGE edges (downstream consumers), and cluster membership.
For the metric definition itself, read the pretensor://db/analytics/metrics resource — it returns the MetricTemplate nodes the indexer found, along with the compiled SQL for each.
Which services touch this table?
Section titled “Which services touch this table?”Task. Before the customer.legacy_id drop above ships, the DBA also wants to know which applications read or write customer — not just which tables join to it.
Call. First record consumers. With repositories configured under repositories: in config.yaml (pretensor init writes these as you link each one), pretensor analyze --all re-scans every one of them in a single call and keeps them all current. For a one-off repository, or one not yet in config, run pretensor analyze directly (pretensor analyze ~/code/billing-api --connection prod --service billing-api). Then consumers with table=customer, database=prod returns every recorded code location — service, file, line range, read vs write, and match confidence. Filter with op=write to see only the writers.
Why it matters. Schema-graph blast radius (impact) plus code-level blast radius (consumers) is the full picture an engineer actually needs before a breaking change.
Reach across databases
Section titled “Reach across databases”Task. Your orders table lives in Postgres; customer_segments lives in your Snowflake warehouse, and both are indexed into a shared graph (pretensor index --unified).
Call. traverse with from_table=orders, database=postgres_prod, to_table=customer_segments, to_database=snowflake_warehouse. When cross-database edges exist in the graph, Pretensor returns the path the agent would need to materialize the join (e.g., via a federated query, a sync, or a manual export). Automatic cross-database entity resolution — discovering those links without hand-curation — is part of the hosted offering.
Where to next
Section titled “Where to next”- Connecting your database — DSN forms, config-file profiles, PAT and env-var patterns.
- MCP Tools — full input/output reference.
- Schema Graph — what gets indexed, and why each tool above is shaped the way it is.