Read-only MCP
Safe, until the agent needs to fix what it just diagnosed, and you're pasting SQL by hand.
Self-hosted. Fail closed.
A self-hosted Go proxy you run in your infra. Tablebelt holds DROP, TRUNCATE, ALTER ... DROP and unscoped writes, snapshots the affected tables first, and restores them with one command.
We'll email your install command.
Check your inbox for your install command. An API key is only for hosted approvals on Pro or Team.
Share on XThe problem
Then it decided the users table looked like leftover test data. Same cause every time: the agent had the real credentials, and the only guardrail was text in a prompt.
This is already happening in public. Replit's agent deleted a company's production database in July 2025, and a Cursor agent wiped a startup database in April 2026.
Safe, until the agent needs to fix what it just diagnosed, and you're pasting SQL by hand.
Suggestions. The model ignores them the moment a cleanup looks obvious.
Last night's dump, a restore you've never run, and every write since midnight gone.
How it works
A single Go binary or Docker image in your infra. Point the agent's DATABASE_URL at Tablebelt. Normal queries pass straight through. Your app keeps the real Postgres URL, so Tablebelt is never between your users and the database.
Credentials and row data stay on your box. On Pro and Team the proxy sends the held query and metadata out over HTTPS and polls for a decision. Free approves in the CLI, with no dashboard key.
# Point the agent at Tablebelt, not Postgres
DATABASE_URL=postgres://agent@127.0.0.1:5439/app
# App keeps the real URL, off the agent host
# postgres://app@db.internal:5432/app
One Go binary or Docker image you run. The agent talks to Tablebelt over the Postgres wire. Safe queries pass through. The proxy, not us, holds the real database URL on your side.
DROP, TRUNCATE, ALTER ... DROP, and UPDATE/DELETE without a WHERE are held. Tablebelt snapshots the affected tables first. Unparsed SQL does not run.
Free: tablebelt approve in the terminal. Pro and Team: hosted approvals in a web dashboard, Slack or email, plus audit history. Deny and the agent is told no.
tablebelt restore <snapshot> puts those tables back as they were at snapshot time. Not whole-database PITR. Writes after the snapshot are lost.
The snapshotted tables, on your side. Later writes to those tables are gone. It does not undo a cascade it did not snapshot. DROP DATABASE needs a whole-database snapshot.
$ tablebelt restore snap_0001
restoring public.users from snap_0001
ok public.users
note writes after snapshot are gone
What it catches
Parser-based, not a denylist of string prefixes. If Tablebelt can't read it, it doesn't run it.
DROP TABLE / SCHEMA / DATABASE
Gone, and no migration file brings the rows back.
TRUNCATE
Every row in one statement, with no WHERE to scope it.
DELETE / UPDATE
Held when there's no WHERE. Scoped writes go through.
ALTER ... DROP
Columns and tables you can't get back from a migration file the agent also rewrote.
DISABLE ROW LEVEL SECURITY
Nothing is deleted, but every row is suddenly readable by whoever has a key.
unparsed SQL
If it can't be parsed it doesn't run, because production isn't the place for a best-effort guess.
Works with
It works over the Postgres wire protocol, so it doesn't care who hosts the database.
Support
Agents
Postgres hosts
Why self-hosted
Snapshots stay in your own Postgres or storage. We never host them, and we never see database credentials. On Pro and Team we see the held statement and metadata, not rows.
It sits only in the agent's path. The app keeps the direct connection. Failure blocks the agent, not your users.
A Go binary or Docker image you can systemd, or just run.
Pricing
Start free. We'll email your install command. An API key is only for hosted approvals on Pro or Team.
£0 1 database
tablebelt approve£15 per database / month
£59 per month
FAQ
No. Database credentials and row data never leave your infra. Tablebelt the company never sees or stores database credentials. Snapshots stay in your own Postgres or storage. On Pro and Team the proxy makes outbound HTTPS calls to the dashboard with the held statement and metadata (table names, estimated rows, agent or client name), then polls for the decision. It does not open an inbound port for us. The API key only links a proxy to a dashboard account and can be revoked. You can redact statement text and send only a fingerprint and table names. Free has no dashboard key: you approve in the CLI.
Your machine. Snapshots and restore points stay there. I never host your Postgres. On Pro and Team the held statement and metadata can leave over outbound HTTPS. Credentials and rows do not.
A Postgres wire-protocol proxy you run. MCP, psql, or an ORM talking Postgres all connect to it. Point the agent at Tablebelt. Your app keeps the real URL.
DROP, TRUNCATE, ALTER ... DROP, and UPDATE / DELETE without a WHERE. Unparsed SQL does not run. DISABLE ROW LEVEL SECURITY is also held. Team gets shared approval rules.
It parses. Unparsed SQL doesn't run.
The snapshotted tables, as they were at snapshot time. Later writes to those tables are lost. Not whole-database PITR, and it doesn't undo a cascade it didn't snapshot. DROP DATABASE needs a whole-database snapshot.
In your own Postgres or storage, on your side of the proxy. We do not host them.
Yes, if it can read the raw database URL. Give the agent only the Tablebelt string, keep the real URL off that machine, and use a Postgres role it can only reach through Tablebelt. Pair that with hooks that block .env reads if the agent supports them.
It speaks the Postgres wire protocol, so it works with hosts that give you a normal connection string. Poolers, IAM auth and forced TLS can break a wire proxy; use a direct connection if yours does.
Normal queries stay on your network. A held statement waits for an approve: locally on Free, or via the dashboard on Pro and Team.
If the proxy is down, the agent is blocked. Your app is not, because it never goes through Tablebelt. If the dashboard is unreachable, Free still approves in the CLI. Pro and Team held queries wait until the proxy can poll again.
Read-only means the agent can't fix anything. PITR rolls the whole database back. Tablebelt holds one statement, snapshots what it touches, and lets everything else carry on.
Postgres only. If that's a deal-breaker, pick host: other on the form.
Undo, hosted approvals and audit history are the product. I have not published a licence for those.
Enter your email. We email your install command. Free is the self-hosted proxy, CLI approvals and local snapshots. An API key is only for hosted approvals on Pro or Team.
Founder
I'm Kyle Redelinghuys. I write Go, Vue and Postgres, run it all on DigitalOcean, and have Claude Code, Cursor or Codex open most days. My most-read post is on when --dangerously-skip-permissions is fine, and I built Vouch because an agent saying "done" isn't proof. Tablebelt is the same view: a CLAUDE.md rule is a suggestion, and the control that holds is in the call path. I run it on my own databases. If your stack looks different, tell me on the form.
Get Tablebelt
Email is enough. We'll send your install command.
Check your inbox for your install command. An API key is only for hosted approvals on Pro or Team.
Share on X