SQL logoAgents

An Agent Can Write Perfect DDL for the Wrong Database

Language models are unusually good at writing SQL DDL. They have read an enormous amount of it, the grammar is regular, and the output looks right immediately.

An Agent Can Write Perfect DDL for the Wrong Database

Language models are unusually good at writing SQL DDL. They have read an enormous amount of it, the grammar is regular, and the output looks right immediately.

They are also unusually bad at writing DDL that is true, because the correctness of a CREATE TABLE is not a property of its syntax but of its agreement with a system the model has never seen. A statement can parse, run, and be completely wrong.

Watch the specific failures. Asked to add a table that joins to customer, an agent assumes customer_id is an integer — yours is a UUID string. It types status as free text, because that is what status usually is — yours is a governed list of five values. It emits BOOLEAN for a SQL Server target, or DATETIME where the estate standardized on DATETIME2. Each guess looks exactly like knowledge, and none is a reasoning failure: the agent was asked to act on structure it had no way to consult.

The fix is not a smarter model; it is giving the model something true to read.

Grounding: a schema an agent can ask for

CoreModels exposes governed models over MCP, the open protocol agents already speak. An agent connects to https://coremodels.example.com/mcp — OAuth, with spec-compliant clients completing discovery and sign-in on their own — lists the projects its user can see, pulls a project summary, then asks for exactly the artifact the task needs.

For database work that is the export_sql tool, which returns the project's schema as CREATE TABLE DDL. It takes the project id and, optionally, a space id or specific type node ids — so an agent working on one domain pulls only that domain rather than an entire estate.

What has changed is epistemic, not ergonomic. The DDL now in the agent's context is not a plausible reconstruction; it is generated from the governed model itself. The types are the agreed types, the NOT NULL flags the agreed requirements, and the REFERENCES clauses relationships the organization actually governs rather than ones that seemed likely. When the agent drafts a migration on top of that, it is reasoning from record.

The meaning rides inside the DDL

Grounding an agent in structure solves half the problem. Agents also guess meaning: whether this column is the same concept as that one in another system, whether a code list is closed, what a field is for.

SQL has no annotation slot, so our coder uses the one place DDL allows — column comments. A column carrying a mapping to a public vocabulary term is exported with a small machine-readable object in its comment, and re-importing that DDL lifts the mapping straight back into the model. On MySQL the comment is inline; on PostgreSQL and SQL Server it arrives as COMMENT ON COLUMN statements after the tables.

A human skims past that; an agent parses it. The same DDL string now answers both questions agents get wrong: what shape is this column, and what does it mean.

Translation without invention

The other job agents get handed is conversion — turn this JSON Schema into tables, these tables into a record schema for a topic. Left to generate token by token, a model does this fluently, and its failure mode is silent: well-formed output that quietly drops a constraint or invents a type.

Over MCP the agent can call transform_schema instead. SQL works as both source and target: DDL decodes into the neutral model, and any decodable format encodes out to DDL with an explicit vendor choice — postgres by default, mysql, or sqlserver. The dialect becomes a parameter rather than a guess, which alone removes a family of errors. The conversion runs through deterministic coders, not the model's imagination, and the response carries two things a raw generation never gives you: the executed plan, as a replayable artifact, and a lossiness ledger of everything the target could not hold — each entry with a kind, a path to the exact type or element, and a plain-English reason.

That ledger hands agents something they are notoriously short of: calibrated ignorance. When PostgreSQL cannot enforce a governed value list and the coder emits VARCHAR instead, that fact arrives as a structured record — and an agent that reads it can flag it in a pull request, propose a follow-up, or ask its human. An agent without that signal fills the gap with fluent confidence, and it surfaces in production months later.

The same applies to what the model does not represent at all: a table-level PRIMARY KEY, UNIQUE, or CHECK clause comes back as a recorded constraint relaxation, so an agent reading the ledger knows the artifact is not a complete replacement for the original file.

Proposal is allowed; authority is not

There is an AI inside this system too, and how we govern it is the template for governing yours.

The mapping engine's AI-assisted mode lets a server-side model propose how a source schema aligns onto a target — but the proposal is only a plan. Every plan — hand-authored, inferred, or model-proposed — passes the identical validation gate before anything executes, a rejected proposal gets at most one repair attempt, and a rejected repair is a rejection. The gate is never relaxed to make the proposal look smarter, self-reported confidence is advisory only, and execution after the gate is deterministic. That mode also requires Editor or Admin membership, because it spends real budget and sends schema content to an external API — which the tool's own description says plainly.

For external agents the boundary is structural. The public /mcp endpoint serves read-only tools: an agent there can list, summarize, search, export, transform, and validate — and cannot write anything. Write tools live on a separate admin endpoint, where every call is still checked against the caller's real project role. Agents get precise, current, meaningful schema. They do not get authority: changes to meaning still pass through people.

What good looks like

The payoff is not visible in a demo. It shows up in the third week, when the agent-drafted migration matches what the DBA expected because both read the same source, and in the review comment that says this export cannot enforce the status list on PostgreSQL — here are three options instead of a silent downgrade nobody noticed.

Guessed structure fails late and expensively. Consulted structure fails early, out loud, and cheaply — which mostly means it does not fail.

Your databases already know their schema; your governed model can carry its meaning. The missing piece was a way for an agent to ask. To wire that up, see the MCP quickstart in the CoreModels docs.