Write history and undo
Every change sent through SZ-MCP is recorded twice: a one-year log you can read on the dashboard, and a 30-day history Claude can undo from. The log says who sent what and how it was approved. The history also keeps the target’s state from just before the write, which is what makes an undo possible.
Write history page (/writes) | Undoable history (history.*) | |
|---|---|---|
| Kept | 365 days | 30 days, at most 5,000 writes |
| Holds | Time, person, method and path, result, approval, a hash of the body | The body sent, the target’s state just before, a create’s response, the undo plan, the post-change verification |
| Read by | Anyone in the organisation, on the dashboard | Claude, for any role |
| Undo | No | history.undo (engineer and above to send it) |
Where do I see what Claude changed?
Section titled “Where do I see what Claude changed?”Go to Change › Write history (/writes). It lists every change sent to the
controller through SZ-MCP, by anyone in the organisation, newest first. Reads
are not listed.
| Column | What it shows |
|---|---|
| When | The time it was sent |
| Change | Method and path (switches before a SwitchM path), with a DANGEROUS chip for a dangerous write |
| By | The person whose chat sent it |
| Result | The HTTP status, or FAILED |
| Approval | guard off, confirmed in chat, authenticator code or approved here |
The page shows the newest 200 writes. Download CSV exports up to 5,000. The filter box (Filter by path or person) searches the rows on the page.
How does Claude look up a write?
Section titled “How does Claude look up a write?”Claude reads the undoable history with two functions:
| Function | Default | What it returns |
|---|---|---|
history.writes({ sinceMinutes, path, surface, limit }) | Last 24 hours, 50 writes (at most 30 days, 500 writes) | Each write’s id, time, person, method, path and status, whether it can be undone (and why not), and its post-change verification |
history.get_write({ writeId }) | — | One write in full: the body, the state before (before), a create’s response, the undo plan and its verification. Secret-looking fields are masked |
Every write call sends returns its writeId.
What can history.undo reverse?
Section titled “What can history.undo reverse?”An update, a create or a delete. Not an action.
| The write was | The undo sends | Caveat |
|---|---|---|
PATCH or PUT | The same method and path, with the fields the write set put back to their earlier values | Fields that were not in the earlier state are left as the write set them |
POST that created something (the response carried an id) | A DELETE of what it created | Only if the API has that DELETE |
DELETE | A POST that recreates it from its earlier state | Approximate: it gets a new id, and anything that referred to the old one (WLAN groups, AP groups, profiles) is not relinked |
| Anything else, such as a reboot or a restore | Nothing | ”<METHOD> writes are not undoable” or the reason below |
history.undo returns not_undoable with one of these reasons:
- “the write failed (HTTP status), so there is nothing to undo”
- “this write was itself an undo of write N; undo that one’s original instead, or make the change again”
- “the write or its before-state was too large to keep” (a body over 64 KB or a before-state over 256 KB is not stored)
- “no before-state: … has no GET … to read it with”
- “the response carried no id, so this POST was an action or a query, not a create”
the spec has no DELETE …/{id}
How do I undo a change?
Section titled “How do I undo a change?”Ask Claude to undo it. history.undo({ writeId }) is a dry run by default:
it reads the target and shows the plan, sending nothing. With apply: true the
reversing request goes through the write guard like any other write, so you get
the usual preview and confirm, and a code or dashboard approval for a dangerous
one. Sending it needs the engineer role or above.
| Situation | What Claude gets back |
|---|---|
| Someone changed the target after the write | changed_since: “The target changed after this write; undoing would overwrite that change. Show the user, and repeat with force: true only if they agree.” |
| The write was already undone | already_undone: “Write N was undone by write M.” |
| The write is older than 30 days, or pushed out by newer ones | not_found: “No write N (writes are kept 30 days).” |
A write can be undone once. The undo is a write of its own, with its own id, and it cannot itself be undone: make the change again instead.