I'm curious, do you output triggers, store procedures, and such? Many tools seem to stop after you've defined tables, columns, and indices, but I'd love some better tooling to make use of the rest of the DB's features.
And curses. Now I'm going down another rabbit hole rehashing ways to interface with my database in a side project that is doomed to never get past the "there has to be a better way to…" phase ;)
You're adding a round trip to the database and the LLM and inserting a tool call in the conversation before it even starts generating any code.
And the reference Postgres MCP implementation doesn't include Postgres types or materialized views, and is one of the most widely used packages: Zed.dev's MCP server for example, is seemingly just a port of it and has the same problem.
If designed well - by suspending generation in memory and inserting a <function_result>, without restarting generation and fetching cache from disk - the round trip/tool call is better (costs the equivalent of 50 tokens for waiting + function_result tokens).
And you don't have to wonder about "if designed well": the reference implementation that's getting 20k downloads a week and getting embedded in downstream editors is is not designed well and will make the round trip every time and still not give the LLM the full information of the table.
Most MCP implementations are crappy half-assed implementations in similar fashion because everyone was rushing to post how they added <insert DB/API/Data Source> to MCP.
And if you're worried about "context fatigue" (you mean LLMs getting distracted by relevant information...), you should 100% prefer a well known schema format to N MCP prompt definitions with tool usage instructions that weren't even necessarily tuned for the LLM in question.
LLMs are much more easily derailed by the addition of extra tools and having to reason about when to call them and the results of calling them, than they are a prompt caching friendly block of tokens with easy to follow meaning.
It's important to manage your schema in code for various reasons from change control to standing up development databases, etc.
How do you keep that all in sync across your apps?
By “don’t do it,” I mean having multiple apps talk to one DB schema.
Services are slow, restrictive, and don't enjoy the benefits of an actual DBMS, like transactions. You also add additional dependencies and failure points.
All you've done is shifted the dependency and made extra work when schemas change. Now we have schema updates, _and_ service updates.
As I said, you give up transactions, performance, and flexibility. You also increase the workload, and increase failures. There is almost no good reason for what you're proposing.
1. DB -> App = Two updates, the schema and the app
2. DB -> Service -> App = Three updates, the schema, the service, and the app
In both cases, obviously the DB changes.
In both cases, obviously the App changes.
In the second case, you also get to update your services.
The same is true for API contracts but the culture of changing an API is much more understood as something that must be communicated and processes are more rehearsed.
Literally everything you just said applies to services and API contracts as well. You haven't solved anything.
> the culture of changing an API is much more understood as something that must be communicated and processes are more rehearsed
You're just making this up. There are thousands of incidents every day because someone changed an API without communicating to every stakeholder.
"Services are better than databases because service owners are better at communicating changes than database owners" isn't a very compelling argument.
I'd work to fix the communication problem before I adopted a terrible tech solution.
> You're just making this up. There are thousands of incidents every day because someone changed an API without communicating to every stakeholder.
What you wrote isn't a contradiction of what I wrote. I wrote "more understood" not "perfectly solved problem."
> "Services are better than databases because service owners are better at communicating changes than database owners" isn't a very compelling argument.
Except they are because the tooling is better. I can check calls to an API endpoint using the same tooling that I would for checking end user API calls. I can push out comms to use the new API, I can confirm calls go to 0 before deleting the old endpoint.
For checking that a table or column is being accessed before changing / deleting it? Fuck, I don't actually know how I'd orchestrate that. And once I've made that change (vs when I make an API change), well, I hope I got it 100% correct because reverting that change is harder.
Of course in a narrow case where all apps that need the same DB need to be upgraded/fixed in lockstep, maybe you can get away by directly updating the database. But more than 2 teams, it will quickly be a nightmare of conflicting priorities across teams, amount deployment coordination required.
"Oh you cannot change this schema right now because 3 other apps depend on it and they dont have time to make the necessary changes in their app to accommodate this right now, for the next 6 months"
When your apps connect to a DB schema, the change is silent. You just run ALTER TABLE and… whoops, you just brought down a service you didn’t know existed because the contract was implicit.
Jeff Bezos famously said[1] that anyone who does otherwise should be fired, and I agree.
But this is only valid when you're trying to build AWS. Not everyone does that.
Relational databases have extensive permission systems for a reason.
Yeah, and databases expose extensive APIs with extremely battle-tested security and permissions models for multiple consumers.
That code might in turn have plugins or feature flags that mean you don't know the concrete sql schema until runtime.
Same for seed data and migrations.
So it depends on the use-case how useful this format is for tooling and discovery vs an actual connection to the database.
If you are using an ORM, using the same language and mental model to describe your database structure as you do to interact with the database makes a lot of sense.
Often times, the indexes will reflect this. Often times, not.
I'm not sure whether or not it's better to have your editor database-aware or to have your codebase have appropriate context committed. On one hand, less generated code/artifacts make for a cleaner codebase. On the other hand, not everyone uses VC Code or will know how to use this integration. Database browser GUIs have never really had a single winner. That said, VS Code does have enough dominance to potentially make themselves "the standard way to view a database in development"
[1] https://github.com/seveibar/pgstrap