Self-hosted. Fail closed.

The agent can have Postgres.
You keep the undo.

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 X

The problem

You gave the agent a database URL so it could actually fix things.

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.

Read-only MCP

Safe, until the agent needs to fix what it just diagnosed, and you're pasting SQL by hand.

CLAUDE.md rules

Suggestions. The model ignores them the moment a cleanup looks obvious.

Nightly pg_dump

Last night's dump, a restore you've never run, and every write since midnight gone.

How it works

Proxy, hold, approve, restore.

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.

How it connects agent path
# 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
Agent DATABASE_URL
Tablebelt proxy your infra
Postgres your database
Dashboard / Slack held query only
Outbound HTTPS on Pro and Team. No inbound port from us. Free stays on the box.
Your infra Fail closed

Self-hosted proxy

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.

Guard

DROP, TRUNCATE, ALTER ... DROP, and UPDATE/DELETE without a WHERE are held. Tablebelt snapshots the affected tables first. Unparsed SQL does not run.

Approve

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.

Undo

tablebelt restore <snapshot> puts those tables back as they were at snapshot time. Not whole-database PITR. Writes after the snapshot are lost.

What restore restores

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 your box
$ tablebelt restore snap_0001
restoring  public.users from snap_0001
ok         public.users
note       writes after snapshot are gone

What it catches

What it holds

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

Built for the agents and hosts you already use.

It works over the Postgres wire protocol, so it doesn't care who hosts the database.

Support

Agents

Claude Code Codex Cursor Any MCP client

Postgres hosts

DigitalOcean RDS Neon Railway Supabase Render Self-hosted

Why self-hosted

Your rows never visit my servers.

Data stays on the box

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.

If Tablebelt dies, production doesn't

It sits only in the agent's path. The app keeps the direct connection. Failure blocks the agent, not your users.

One binary, no extra fleet

A Go binary or Docker image you can systemd, or just run.

Pricing

Three plans. Same product.

Start free. We'll email your install command. An API key is only for hosted approvals on Pro or Team.

Free

£0 1 database

  • Self-hosted proxy, binary or Docker
  • CLI approvals with tablebelt approve
  • Local snapshots and restore
  • Destructive SQL held, fail closed
Start free

Pro

£15 per database / month

  • Everything in Free
  • Hosted approvals: dashboard, Slack or email
  • Audit history
Start free

Team

£59 per month

  • Everything in Pro
  • Up to 10 databases, so less per database than Pro
  • Multiple approver seats
  • Shared approval rules
  • Audit export
Start free

FAQ

The questions I'd ask.

Do you see my credentials or rows?

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.

Where does my data go?

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.

How does it sit in the path?

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.

What counts as destructive?

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.

Does it actually parse SQL, or regex?

It parses. Unparsed SQL doesn't run.

What does restore restore?

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.

Where do snapshots live?

In your own Postgres or storage, on your side of the proxy. We do not host them.

Can the agent just bypass it?

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.

What about managed Postgres?

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.

What's the latency?

Normal queries stay on your network. A held statement waits for an approve: locally on Free, or via the dashboard on Pro and Team.

What if Tablebelt goes down?

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.

How is this different from a read-only role, or my host's PITR?

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.

MySQL, or anything else?

Postgres only. If that's a deal-breaker, pick host: other on the form.

Is it open source?

Undo, hosted approvals and audit history are the product. I have not published a licence for those.

How do I get Tablebelt?

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

Why I built it

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.

ksred.com · @ksredelinghuys

Get Tablebelt

Start free before the next DROP.

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