The schema catalog for an AI assistant is the artefact that answers the question "what does this database look like right now". Whether the database is Postgres, MySQL, SQL Server or Redshift, the shape of the problem is the same: the catalog carries table names, column names, types, keys, and enough relationships to let the assistant write a query that resolves. It lives somewhere between the database and the assistant, has to stay in sync with a database that changes underneath it, and is almost always built the same weekend the team decides they want an AI assistant reading their data. It runs fine for the first three tables. The problems start around the fourth week, and none of them look like the same problem twice.
The distinction worth naming early is between the connection layer (how the assistant reaches the database) and the knowledge layer (what the assistant knows about the database's shape). The connection layer receives most of the attention, because credentials, network isolation and query cost are visible failure modes and easy to argue about. The knowledge layer is where most of the actual quality of the assistant lives, and it decays quietly. The AI database context page covers why this second layer matters at all when the first one exists.
Why not just point the assistant at the database
Connecting the AI directly to production is the shortest path and the one most teams reject after five minutes of thinking about it. The assistant would get read access on tables it should not see, its queries can be arbitrarily expensive, its credentials would live somewhere they should not, and the audit trail becomes hard to reason about. What most teams end up building is a layer in between: a representation of the database that the assistant can read cheaply and safely without ever touching production.
That layer is what this article is about. It is not the connection. It is the catalog.
The five recipes teams build
Ask fifteen senior developers how to build that layer and you get roughly five recipes. Most teams end up combining two or three.
Recipe 1: the JSON catalog file. A script dumps the schema (table names, column names, types) into a JSON file, committed to the same repo as the assistant's prompt config. The assistant reads the file at startup. The simplest thing that works.
Recipe 2: the nightly refresh. Same as recipe 1, but a cron job regenerates the JSON every night from the running database. Sometimes on demand from a slash command in Slack.
Recipe 3: the custom MCP server. A small Model Context Protocol server sits between the AI and the database, exposing a set of typed queries. The assistant calls these instead of writing raw SQL. The MCP process holds the credentials.
Recipe 4: the semantic layer. The catalog is enriched with human notes: which column is a foreign key in disguise, what status = 'C' actually means in this business, which tables are archived. This layer is typically a YAML file or rows in a table.
Recipe 5: the read-only replica. A separate replica of the production database, sometimes with masked columns, that the assistant is allowed to query directly. Solves the credential problem. Does not solve the knowledge problem.
None of these are bad. All of them ship. Most of them stop working around the same point in the same way.
Why all five recipes work in week one
The recipes deliver the same thing on day one: the assistant answers a question about the database, correctly, in front of someone who wanted to see it work. The team walks away with the impression that the layer is done. The layer is not done. The layer is at day zero of a maintenance timeline that nobody has planned for.
Why all five recipes start breaking around week three
Four failure modes, in the order teams usually hit them.
A column gets renamed and nobody updates the catalog. A developer renames user_email to contact_email in a migration. The migration ships. The catalog file still says user_email. The assistant asks for user_email and gets a "column does not exist" error, or worse, silently gets zero rows back and confidently reports "there are no users with an email".
A new column appears and the assistant never learns about it. The nightly refresh (recipe 2) picks it up in fifteen hours. In those fifteen hours the assistant is asked something that would have needed the new column, and answers based on the old shape of the world. No error, no warning, just a wrong answer delivered with the same confidence as a right one.
The semantic notes drift out of sync with reality. The YAML file (recipe 4) said status = 'C' means "cancelled". Someone changed it to mean "completed" six months ago as part of a business logic overhaul. The YAML was never updated. The assistant answers questions about cancelled orders with rows for completed ones.
The MCP typed queries stop matching the schema. A typed query (recipe 3) was written for a table with three columns. The table now has five. The query still runs, still returns rows, and skips the two new columns entirely. The assistant works around a phantom limitation of the database that only exists in the code between the two.
None of these failure modes are exotic. All of them show up on any database older than a year, staffed by more than three developers, without anyone doing anything wrong.
What a layer that survives looks like
Three properties separate a catalog that ages well from one that goes stale in two weeks.
It is regenerated from the running database on a schedule, not from a file. The source of truth for what the assistant sees has to be what the database currently is, not what someone wrote down when they built the layer. If the regeneration is not automated, it will not happen. This is the difference between "the catalog is code" (fragile) and "the catalog is a snapshot" (self healing). The mechanics of doing this well are discussed in more detail in the schema drift detection piece.
It records structural changes as typed events, not as raw diffs. When a column is renamed, someone needs to see "column user_email was renamed to contact_email on 2026-08-14" instead of two hundred lines of unified diff between two JSON files. This is what makes drift readable and reviewable rather than noise to scroll past. The schema change history page shows what this looks like when the events are typed and severity-classified.
It carries human annotations alongside the metadata, and versions them. The semantic notes (which enum values mean what, which two column joins are load bearing, which tables are archived) live next to the raw catalog, versioned together, so that when the schema changes the annotations get flagged for review instead of quietly outliving their referent.
A layer with these three properties is not built in a weekend. Which is why almost nobody has one, and why most teams are running a catalog file that was accurate three weeks ago.
Where Taavik fits
Taavik is one implementation of the three properties above, packaged as a Model Context Protocol (MCP) server that AI assistants and coding agents consume directly. Recipe 3 up in the list (write your own MCP server) is the DIY version of what Taavik ships in the box: catalog scans on the team's cadence, typed rename events in the change history, and human annotations at the column and table level versioned alongside the metadata. Postgres, MySQL, SQL Server and Redshift are supported. Database credentials never leave the private network, which is the topic of a separate piece and not what this one is about.
The choice is not Taavik versus nothing. The choice is whether those three properties end up in the stack, by any route, before the fourth week runs out. Building them in-house costs a few hundred lines of code and one person willing to own them for as long as the database lives. Buying them costs a subscription and one decision meeting. The right answer depends on how many databases are in scope and how many engineers can be pulled away from product work to look after a layer that is technically boring and operationally load bearing.
Originally published on the Taavik blog.
Top comments (0)