Quickstart
Five minutes from an empty directory to a blocked DROP TABLE, an UPDATE that Postgres’s own change log confirms, and then the case Deedglass is for: the same UPDATE, the agent reports 1 row, and Postgres changed 301. It ends on the undo preview built from those rows.
Before you start
- Docker is running, with about 2 GiB of free disk.
- Node 22.12 or later (for
npx), or Go 1.27 to build the CLI yourself. - macOS or Linux. On Windows, use WSL 2.
1. Get the CLI
Section titled “1. Get the CLI”npx fetches the CLI for your platform. It has no install script.
$ npx -y deedglass versiondeedglass … · api 2026-10-01 · …Prefer a binary on your PATH? go install github.com/deedglass/deedglass/cmd/deedglass@latest, then use deedglass in place of npx -y deedglass below.
2. Set up a local stack
Section titled “2. Set up a local stack”In a new, empty directory:
$ mkdir acme-agents && cd acme-agents$ npx -y deedglass init --yesdeedglass init · setting up Deedglass in …✓ Docker …✓ Postgres …✓ Deedglass http://127.0.0.1:…✓ Agent quickstart-agent · key saved to .deedglass/quickstart.key …✓ Policies postgres-safe v1 · enforce …✓ Smoke · postgres.query Claimed · Matches · deed_…✕ Smoke · DROP TABLE Blocked by policy "block-destructive-sql": DROP and TRUNCATE are never allowed for agents.✓ Smoke · UPDATE 1 row Proven · Matches · Postgres committed the row in public.orders · deed_…✓ Sealed. Your first record is in the ledger.init starts Postgres 18.6 in Docker, runs deedglass serve on 127.0.0.1:8080, creates an org, an agent with a test key, the Acme demo database behind a Postgres connector, and the postgres-safe policy. Then it sends three actions through Deedglass:
- a read, which runs: Claimed ·Matches
- a
DROP TABLE, which the policy blocks before Postgres sees it - an
UPDATEof one row, which waits for a person (in dev,initcountersigns as you), runs, and is checked at Proven: Proven ·Matches
With the Postgres image already pulled this takes 6 to 8 seconds on an M-series Mac. Run it again and it prints Nothing to change.
3. Check everything
Section titled “3. Check everything”$ npx -y deedglass doctordeedglass doctor · 16 checks · ……16 okEach line is one check. A problem prints its fix; every check is explained in Doctor checks.
4. See the blocked action and the verified one
Section titled “4. See the blocked action and the verified one”The admin key init saved lets the CLI read the Ledger:
$ export DEEDGLASS_API_KEY="$(cat .deedglass/admin.key)"$ npx -y deedglass actions list --limit 3…postgres.execute…The DROP TABLE is sealed as denied: its record names the rule and says that nothing ran. The UPDATE waited for a person, ran once approved, and was checked at Proven: Postgres’s change log shows exactly one row of public.orders changed.
5. One reported row, 301 changed
Section titled “5. One reported row, 301 changed”The demo database has a legacy trigger written for it: when one order ships, it ships the next 300 open ones too. init --trigger turns it on, sends the same one-row UPDATE of order 42 as the quickstart agent (in dev, init countersigns as you again), and shows the Proven check:
$ npx -y deedglass init --triggerdeedglass init --trigger · one UPDATE, a legacy trigger, and what Postgres really committed…✕ UPDATE order 42 Proven · Doesn't match · Postgres changed 301 rows in public.orders. The agent reported 1. expected UPDATE 1 row in public.orders where id = 42 · sets status observed UPDATE 301 rows in public.orders · 300 outside id = 42…✓ Trigger off orders_ship_open_batch dropped✓ Undo preview Undo available · 301 rows in public.orders · 301 updates…The agent said 1 row. Postgres's change log says 301. Nothing was undone yet.…The agent’s tool answer said 1 row, and that is all an agent log would show. Deedglass read Postgres’s change log for the same transaction and found 300 more. The diff lists them (the first 20 here; all of them in the Console).
Then it turns the trigger off and previews the undo: 301 updates, planned from the rows Postgres recorded, each putting a status back. Nothing runs yet. Next prints the deedglass undo run line with the plan’s digest; the undo waits until a person countersigns it in the Console (Approvals), and Postgres’s change log checks the undo too.
Run init --trigger again any time: it puts the order statuses back to the seed’s first.
6. Connect your agent
Section titled “6. Connect your agent”Pick your client. Each page shows the exact config, generated from the CLI’s own snippets.
- Claude Code: one
claude mcp addline. - Claude Desktop, or Cursor, VS Code and Windsurf.
- Your own code: the Python SDK or the TypeScript SDK.
7. Look in the Console
Section titled “7. Look in the Console”Open http://127.0.0.1:8080/app and sign in as you@localhost.test. In dev, Deedglass writes mail to its log instead of sending it, so the sign-in link is in .deedglass/serve.log.
What just happened
Section titled “What just happened”- The agent asked Deedglass to run a tool, and Deedglass checked its key.
- Your rules (the enforced policy) decided: allow, deny, or require approval.
- The denied call was sealed as a record and never reached Postgres.
- The allowed call ran through the Postgres connector as the least-privilege role
deedglass_agent. - The check compared what the tool reported with Postgres’s change log (Proven).
- Each result was sealed into the org’s record chain, which anyone can check offline.
What it doesn’t do
Section titled “What it doesn’t do”- The local stack is for a laptop:
127.0.0.1only, dev mode, throwaway data. Run in production on one VM is the next step. initdoesn’t edit your MCP client’s config file. It prints what to paste.- It doesn’t use an existing database yet. Put Deedglass in front of Postgres covers your own database.
init --triggerchanges only the demo databaseinitmade; the trigger exists for the length of the step.deedglass init --stopstops the stack. It keeps.deedglass/and the Docker volumes, so a laterinitpicks up where you left off.
- Scan in 60 seconds: grade your own agent setup A to F.
- Your first policy: edit
postgres-safefor your tables. - What Matches (VERIFIED) means, and what it doesn’t.
- Glossary: the plain names and the API names they map to.