AGT-20Recommended
Offer a dry run for every change
Every tool or API call that changes data accepts dry_run: true. It then returns exactly what would change, and changes nothing.
How to do it
An agent that can preview a change makes fewer wrong ones, and can show the plan to its person first. Run the same code path up to the point of writing, inside a transaction you roll back, or with a flag that skips the write. Return the records that would change, the totals and any fees. Never send email, charge cards or call webhooks in a dry run. Mark the tool's other behaviour honestly, as Describe your MCP tools honestly says.
Examples
JavaScript example
export async function cancelBookings(args, user) {
return db.tx(async tx => {
const cancelled = await tx.any('UPDATE bookings SET status = $1 WHERE user_id = $2 AND day = $3 RETURNING id, fee', ['cancelled', user.id, args.day]);
const plan = { cancelled: cancelled.map(row => row.id), fees: cancelled.reduce((sum, row) => sum + row.fee, 0) };
if (args.dry_run) throw new RollbackWith(plan);
await outbox.add(tx, 'cancellation-emails', plan.cancelled);
return plan;
}).catch(error => (error instanceof RollbackWith ? error.plan : Promise.reject(error)));
}
Python example
def cancel_bookings(args: dict, user) -> dict:
with conn.transaction() as tx:
rows = conn.execute("UPDATE bookings SET status = 'cancelled' WHERE user_id = %s AND day = %s RETURNING id, fee",
(user.id, args["day"])).fetchall()
plan = {"cancelled": [row.id for row in rows], "fees": sum(row.fee for row in rows)}
if args.get("dry_run"):
tx.rollback()
return plan
outbox.add(conn, "cancellation-emails", plan["cancelled"])
return plan
How to check
For each tool that changes data, a test calls it with dry_run: true and compares the database before and after. Nothing changed, no outbound message was queued, and the answer lists the planned changes.
Related rules
- WEB-196 Describe your MCP tools honestly in Website
- AGT-26 State the cost of every call before and after it runs in Agents as users
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/agents-as-users/safe-actions/dry-run">Agent Wranglers agents as users playbook</a>. In code you write, add a comment next to it with the same link.