Skip to content
Rowsafe

A rewind button for your AI agent.

Coding agents now run migrations and change data, often while nobody is watching. With Rowsafe, your agent saves a restore point before every risky change, so a bad migration is a rewind, not a disaster.

How it works

  1. It checks your database is protected

    Before a risky change, the agent asks Rowsafe whether the database can be restored right now.

  2. It saves a restore point

    It marks the moment by name and waits until Rowsafe confirms the mark is safely stored.

  3. It makes the change

    The migration runs as usual. Rowsafe doesn't get in the way.

  4. You can rewind

    If something breaks, the agent stops and tells you the restore point's name. You restore to it when you're ready.

Restore pointsapp-prod
  • before-migration-0042Recoverableclaude-code3h ago
  • pre-deploy-2026-09-22Recoverablejordan@acme.dev2d ago
  • before-orders-backfillRecoverableclaude-code6d ago
  • Read-only until you allow more

    By default an agent can only look. Saving restore points is a separate, explicit switch.

  • No commands, no data access

    Agents can't run commands or queries through Rowsafe, restart your database or restore anything.

  • Every action on record

    Everything an agent does through Rowsafe lands in your audit log, under its own key.

Set it up

You need a database that Rowsafe already protects, and the rowsafe CLI logged in: rowsafe login opens the dashboard in your browser, you approve, and that's it. On CI and headless machines use rowsafe login --key rsk_... or ROWSAFE_API_KEY. The remote server takes an API key.

  1. Connect the MCP server

    Locally, rowsafe mcp serves the tools over stdio with your saved login (or ROWSAFE_API_KEY). It is read-only unless you add a flag. --allow-restore-points adds only create_restore_point, which is what an agent needs.

    Claude Code: read-only plus restore points
    $ claude mcp add rowsafe -- rowsafe mcp --allow-restore-points
    Claude Code: read-only
    $ claude mcp add rowsafe -- rowsafe mcp

    Remotely, connect to https://api.rowsafe.sh/mcp with an API key in the Authorization header. Write tools are listed, but the API refuses them for a key created with --read-only.

    Claude Code: remote
    $ claude mcp add --transport http rowsafe https://api.rowsafe.sh/mcp --header "Authorization: Bearer rsk_..."

    Claude Desktop runs rowsafe mcp locally. Its remote connectors can't send an API-key header, so use stdio there, with the absolute path from which rowsafe. It uses the login saved by rowsafe login.

    claude_desktop_config.json
    {
      "mcpServers": {
        "rowsafe": {
          "command": "/usr/local/bin/rowsafe",
          "args": ["mcp", "--allow-restore-points"]
        }
      }
    }
  2. Tell the agent the rules

    Paste this into AGENTS.md or CLAUDE.md at the root of your project and set the database name. Agents read it before they work.

    AGENTS.md
    ## Database safety (Rowsafe)
    
    This project's PostgreSQL is protected by Rowsafe (database: `app`). Before any destructive
    or risky database operation (migrations, schema changes, DROP/TRUNCATE, DELETE or UPDATE
    without a narrow WHERE, backfills, resets, restoring a dump):
    
    1. Run `safety_check` for `app` (or `rowsafe status app`). If it is not protected,
       tell me the reasons and wait for my OK.
    2. Create a restore point with a descriptive name: `create_restore_point` (or
       `rowsafe mark app before-<what>`), wait until it is confirmed, and tell
       me its name.
    3. Then proceed.
    
    If something goes wrong: stop, don't try to repair the data, and never restore anything
    yourself. Tell me what happened and the restore point's name; I'll decide whether to restore.

    The same steps work from a shell, for agents without MCP:

    CLI
    rowsafe init app                     # writes .rowsafe.json; later commands can omit the name
    rowsafe status app                   # protected? exit 0 if yes, 3 if not
    rowsafe mark app before-drop-legacy-orders
    rowsafe marks app                    # restore points, with the backup to restore from
  3. Let a hook enforce it (Claude Code)

    The Claude Code plugin bundles the MCP server (with restore points), a skill that teaches the workflow, and a PreToolUse hook, rowsafe guard. The hook recognizes destructive database commands and creates a restore point named agent-<UTC timestamp> right before they run, whether or not the model remembered to.

    Install the plugin
    claude plugin marketplace add rowsafe/rowsafe
    claude plugin install rowsafe@rowsafe

    Tell the hook which database the project uses in .rowsafe.json, which rowsafe init app writes (or set ROWSAFE_DATABASE). By default it only warns if something fails. With require_protection (or ROWSAFE_REQUIRE_PROTECTION=1) it also runs safety_check and blocks the command when the database isn't protected or the restore point can't be confirmed.

    .rowsafe.json
    { "database": "app", "require_protection": true }

    What it matches:

    • Migration tools: Prisma, Rails, Alembic, Django, Knex, Sequelize, TypeORM, Drizzle, goose, migrate, dbmate, Atlas, sqlx, Diesel, Flyway, Liquibase, Ecto, Laravel, Supabase, and db:migrate-style npm scripts.
    • SQL sent to psql: DROP, TRUNCATE, ALTER TABLE ... DROP/RENAME/TYPE, DELETE or UPDATE without WHERE.
    • PostgreSQL tools: dropdb, pg_restore --clean.

    It ignores status, dry-run and help invocations, and commands that only mention a tool. Test a command with:

    Check the matcher
    $ rowsafe guard --check "npx prisma migrate deploy"
    Read the full guide

Reference

Every MCP tool

ToolWhat it doesAccess
safety_checkCould this database be restored right now? protected plus every reason it isn't.Read
list_restore_pointsNamed restore points, their status, and the backup a restore must start from.Read
fleet_healthEvery problem across the organization, worst first, each with the exact next step.Read
list_databases / get_databaseStatus, schedules, WAL archiving, recent backups, drills and tasks.Read
list_backups / list_drillsFinished backups, and restore drill results with failures and warnings.Read
list_tasks / get_taskWhat ran, who queued it, its typed result and the end of its log.Read
list_hosts / get_orgEnrolled hosts and agents; plan, limits and usage.Read
create_restore_pointMark this moment by name and wait until it is confirmed in the backup repository.Restore points
run_backup / run_drillQueue a backup or a restore drill now, in addition to the schedule.Write
plan_adoption / apply_adoptionPlan adopting a database (read-only on the host); apply only with your explicit approval.Write
verify_databaseProve WAL reaches the bucket after a restart.Write
update_scheduleChange backup and drill schedules or retention.Write

There is also an incident_triage prompt: it checks the fleet, reads the evidence for each problem and proposes next steps without changing anything.

What an agent can and can't do

Read-only by default
rowsafe mcp registers only read tools. --allow-restore-points adds create_restore_point and nothing else. --allow-writes adds every write tool.
Read-only keys
On the remote endpoint, a key created with rowsafe api-keys create NAME --read-only gets the same guarantee from the API itself: write tools answer 403.
Fixed tasks, no SQL
Tools queue the same fixed tasks as the CLI. None runs arbitrary SQL or commands, restarts PostgreSQL, restores a backup or reads backup contents.
Approval for real changes
apply_adoption refuses to run unless confirm is the database's exact name and a read-only plan succeeded; its description tells the model to ask you first.
Everything is audited
Every call goes through the public API with its key: organization scoping, plan limits and the audit log apply, attributed to that key.
  • Rowsafe doesn't stop an agent from running a bad statement. It makes the moment before it recoverable.
  • Restoring is a pgBackRest restore to a new host or scratch cluster, following the restore runbook. Nothing rewinds production in place.
  • The guard hook is a safety net, not a sandbox: a destructive statement hidden in application code or an unusual wrapper won't match. The rules and the MCP tools cover what the hook can't see.
Read the AI agents guide

Give your agent a rewind button.

Free for one server and three databases. Upgrade when you add more.

Start free