Pre-alpha. Postgres, HTTP, Stripe and email work today.
Let your agents write in pencil.
Retract sits between your AI agent and your database, files and APIs. Every change is held, shown as one diff, and committed or discarded by you.
git clone https://github.com/retracthq/retract
$ retract session start | node agent.js database: added customer 1073741824 (Ann Lee) stripe: created customer cus_rtxAxjVjA8BaGaGbKkp stripe: charged $19.00 as pi_rtxL2bOLEMjqF7Z2wnv (status processing) database: customer 1073741824 is now on the pro plan mail: 250 2.0.0 Held by Retract as msg_fa835a60f5a4 $ retract diff public.customers: 1 added + id=1073741824 {"email":"[masked]","name":"Ann Lee","plan":"pro"} (values masked in: email) Held calls and email, sent in this order after the commit: 1 stripe create customer cus_rtxAxjVjA8BaGaGbKkp (email=[masked], name=Ann Lee) 2 stripe create payment_intent pi_rtxL2bOLEMjqF7Z2wnv (amount=1900, currency=usd, …) 3 mail email "Welcome to Pro" to [masked]@example.com $ retract commit Committed ses_d06ba880058d (14 journal entries). rows: 1 inserted, 0 updated, 0 deleted new id: public.customers.id 1073741824 -> 1 outbox: Sent 3 held messages. new id: stripe cus_rtxAxjVjA8BaGaGbKkp -> cus_1001 new id: stripe pi_rtxL2bOLEMjqF7Z2wnv -> pi_1002 $ retract discard Discarded ses_d06ba880058d (14 journal entries).
Nothing has left yet. Your call.
Output from the quickstart, lightly trimmed. The agent added a row, charged a card and sent an email. None of it left until the commit.
- Holds today
- Postgres 16 and laterHTTP APIsStripeEmail over SMTP
- Next
- FilesMCP serverPython and TypeScript SDKsReview UI
Hold, review, then commit or discard.
Point your agent at Retract instead of production. It is a connection string and a base URL, not a rewrite.
-
Hold
The agent connects to Retract as if it were the real thing. Reads pass through. Writes land in a private scratch copy, and outgoing calls and email wait in an outbox.
-
Review
When the session ends, Retract shows one diff: every row added, changed or removed, and every message waiting to be sent, in the order it will go.
-
Commit or discard
Commit replays the changes in order with conflict checks, then sends the held messages. Discard leaves no trace.
Your agent
- Any Postgres client, HTTP SDK or mail library
- Holds stand-in credentials only
Retract
- Writes land in a scratch copy
- Calls and email wait in an outbox
- Reads pass straight through
- Real keys stay here, encrypted
Production
- Your Postgres database
- Stripe and other HTTP APIs
- Your mail server
Built to sit in front of production.
Nothing lands until you commit.
Writes, API calls and email are held. Your database, Stripe and your mail server see nothing until you say so.
One diff for everything.
Every row and outgoing message in one place, as plain values, with sensitive columns masked. Files join the same diff next.
Commit is ordered and checked.
Changes replay in the order they happened. If the data changed underneath, Retract stops and shows the conflict instead of guessing.
The agent never sees your keys.
It logs in with stand-in credentials that only work through Retract, so Retract is its only door to production.
No model inside.
Risk is decided by fixed rules on parsed SQL and a catalog of known destructive API calls. Built for AI agents, not with them.
Read every line in your data path.
The proxy, journal, diff, replay and outbox are written from scratch on Node.js built-ins, with no third-party dependencies.
Try it in ten minutes.
An example agent adds a customer, charges them $19 on Stripe and sends a welcome email. You review one diff, then commit or discard. A fake Stripe and a fake mail server are included, so you need no accounts.
- Node.js 24
- PostgreSQL 16 or later, with its contrib modules
# after registering your database, a scratch server and the fakes $ node cli/bin/retract.js up --target app --target stripe \ --target mail --scratch local $ node cli/bin/retract.js session start | node examples/quickstart/agent.js $ node cli/bin/retract.js diff $ node cli/bin/retract.js commit
Why Retract exists
Undo should be a property of the connection, not a hope about backups.
In April 2026 a coding agent on a routine staging task hit a credential mismatch, tried to fix it, and deleted a production database and its backups with one API call. It was not malicious. It was helpful, fast and wrong, which is how agents fail, and it could only do that because a real key was within reach.
I spent three years building bioinformatics pipelines where one bad write could quietly corrupt months of research, and I work shifts as an ER tech, where every action is checked before it touches a patient. Retract brings that habit to software: verify, then act.
Ryan, founder
Putting an agent on production data? Build with us.
We are working closely with the first ten teams. You get direct help wiring Retract in, and what your agent touches decides what Retract holds next.