Pretensor
blog

One schema graph for Postgres, Snowflake, and BigQuery

Most AI agents are single-database. Pretensor builds a unified schema graph across Postgres, Snowflake, and BigQuery — same tools, same interface, cross-DB join paths included.

  • mcp
  • cross-database
  • postgres
  • snowflake
  • bigquery
  • schema-graph

Most MCP database tools connect to one database. You configure a Postgres connection string, the agent gets SQL execution, done. If you have Snowflake for analytics and Postgres for the application backend, you configure two separate MCP servers. The agent sees two disconnected worlds.

Pretensor takes a different approach: one graph, multiple databases. Index your Postgres instance, your Snowflake warehouse, and your BigQuery project independently — they land in the same Kuzu graph. The MCP tools don’t care which database a table lives in. The agent queries schema context across systems without switching tools.

This is a structural design choice, not a feature checklist item. The graph is database-agnostic. Here’s why that matters and how it works.

The single-database ceiling

A reasonable setup today: an application on Postgres, analytics in Snowflake, and a BigQuery project for ML pipelines. Three separate databases. Three separate schemas. Three separate sets of MCP tools.

The problem isn’t configuration overhead. It’s that the agent can’t answer cross-database questions:

  • “Our users table is in Postgres, our user_activity is in Snowflake. Which users haven’t been active in 30 days?”
  • “The product_catalog is in BigQuery, order history in Postgres. Show me top-selling products.”
  • “What’s the relationship between Snowflake’s revenue_daily and Postgres’s subscriptions?”

The agent can answer each part separately, but it can’t connect them. The human has to do the mental join — query both systems, correlate results, interpret relationships. The agent is a query executor, not a schema navigator.

How Pretensor handles multi-database

Pretensor’s index command accepts a connection string per database:

Terminal window
pretensor index postgresql://user:pass@host:5432/appdb
pretensor index postgresql://user:pass@host:5432/analytics # same host, different DB
pretensor index snowflake://user:pass@account/warehouse/db
pretensor index bigquery://project/dataset

Each index call introspects that database, builds its portion of the graph, and writes it to the shared Kuzu store. The graph accumulates. Tables from Postgres, Snowflake, and BigQuery coexist as nodes differentiated by a database property.

The MCP tools expose this naturally:

ToolCross-DB behavior
list_databasesLists all indexed databases with table counts per database
schemaShows node labels and properties, including database as a filterable property
contextReturns full table context with database origin in the response
traverseFinds join paths within a database and across databases when FK-referenced columns match
cypherRead-only Cypher queries scoped to one database at a time (use MATCH (t:Table {database: 'postgres'}) to filter)

The key tool is traverse. Given two tables in different databases, it finds whether a join path exists. The path might go through multiple intermediate tables, some in Postgres, some in Snowflake. The agent sees the full chain:

users (postgres.appdb) → orders (postgres.appdb) → revenue_daily (snowflake.analytics)
via FK orders.user_id → users.id
via inferred FK revenue_daily.order_id → orders.id

The agent doesn’t need to know a priori that these systems connect. The graph on disk already knows.

When cross-DB joins are real vs. conceptual

A caveat: cross-database join paths in the graph are metadata-level matches, not query-time federated joins. The graph tells you that snowflake.revenue_daily.order_id references postgres.orders.id — because the column names and types match, and the FK is implied. The agent uses this to understand the schema relationship.

Whether the agent can actually join these tables depends on the query engine. If you’re running queries through Trino or BigQuery Omni, cross-DB joins work at the SQL level. If not, the agent uses the relationship for reasoning but executes queries per-database.

The graph provides awareness. The query engine provides execution. Separating these concerns means the graph stays accurate even when the execution path changes.

Why a unified graph beats multiple MCP servers

You could configure three separate MCP servers — one for Postgres, one for Snowflake, one for BigQuery — and the agent would have three sets of tools. This works for isolated queries. It fails for reasoning across systems.

With separate servers, the agent has to: (1) know which server has which tables, (2) switch tools mid-reasoning, (3) manually correlate schemas from different sources. That’s three failure points.

With Pretensor’s unified graph, the agent queries one set of tools. context returns a table with its database label; traverse crosses database boundaries; schema shows the full graph structure. The agent doesn’t switch contexts — it navigates one schema model that spans databases.

This is the same pattern that makes a data catalog useful: not because it stores data, but because it stores where data lives and how it relates. Pretensor applies that pattern to the AI agent’s schema context.

What this looks like in practice

A real session might look like:

  1. Agent: list_databases → sees postgres.appdb (142 tables), snowflake.analytics (38 tables), bigquery.ml_pipeline (12 tables)
  2. Agent: context(table="users") → gets columns, relationships, cluster membership, plus database: postgres.appdb
  3. Agent: traverse(from="users", to="revenue_daily") → gets the join path, with database labels at each hop
  4. Agent: cypher("MATCH (t:Table {database: 'snowflake.analytics'}) RETURN t.name") → lists all Snowflake tables

The agent reduces context-switching overhead. The human reviews the reasoning, not the tool configuration. The graph on disk is the single source of schema truth.

Getting started

Terminal window
pip install pretensor
# Index each database independently
pretensor index postgresql://user:pass@host:5432/appdb
pretensor index snowflake://user:pass@account/warehouse/analytics
pretensor index bigquery://my-project-id/dataset-name
# Start one MCP server for all
pretensor serve --config-only # merge into Claude/Cursor config

The list_databases tool in your MCP client will show all three. No separate server processes, no per-database tool prefixing. One graph, one server, one agent.


See also: quickstart guide, MCP tools reference, architecture pipeline.