# restore_storage_backup

Source: https://modulify.ai/docs/mcp/backups/restore-storage-backup

Puts files back into a site's storage from one of its backups, after a first call that only answers the plan.

- Title: Restore a storage backup
- Scope: `data:write`
- Access: Destructive

This is a two call tool, and the first call never restores anything. `mode` `full` makes the storage match the backup exactly and deletes every file added since, uploads from the CMS included. `mode` `selected` writes back only the `paths` you name, up to 200 of them, where a path ending in a slash is a folder and anything else is one file, both taken from `browse_storage_backup`. The only thing a selected restore deletes is the other copy of a restored file that has since been made public or private.

## The plan, then the restore

Call it first with `backupId`, `mode` and, for `selected`, `paths`, and without `confirm`. It answers `Nothing was restored, this is the plan.` with `started` false, a `plan` and a `confirm` value, and changes nothing at all. The plan counts the files that come back, as `filesAdded` for those not in the storage now, `filesReplaced` for those already there at a different size or visibility and `filesUnchanged` for those already there that are written over anyway, the files deleted in `filesRemoved` and the bytes that move in `bytesWritten` and `bytesRemoved`. `safetyBackup` says whether a **Before restore** backup of the current storage is taken first, and `filesSkipped` counts files whose path storage no longer accepts, which are left as they are.

The tool tells the client to show you that plan, say plainly what is overwritten and what is deleted, and wait for you to agree in your own words. Only then does it call again with the same `backupId`, `mode` and `paths` plus `confirm` set to the exact value the plan returned, and that call starts the restore. The client is told never to make up a `confirm` value, never to send one in the same breath as the plan it just read, and never to restore because it seems to follow from the request.

The `confirm` value is worked out from the plan, so it is pinned to it. If the storage changed in between, the second call is refused with a `409` and `The storage changed since this plan was made, so this confirmation no longer matches. Check the new plan and confirm again!`, carrying the new plan and a new `confirm`, so the new numbers have to be shown to you and agreed again. A file rewritten to the same size and visibility leaves the plan as it was, so that change is not caught.

## Once it starts

The confirmed call answers `started` true with the `restore` row, whose `_id` is the `restoreId` for `get_storage_restore_status`. The restore runs in the background and is not done when this answers, so the tool tells the client to say it has started, never that the files are back, and to poll `get_storage_restore_status` until it reads `completed`. Whenever the restore would overwrite or delete anything, a **Before restore** backup of the whole current storage is taken first, so a restore can itself be undone by restoring that row. The restored files are what the live site serves straight away, with nothing to publish.

Both calls need a paid plan and the **Delete projects** permission in the workspace, so even the plan is refused without them. Only one restore runs per site at a time, and a second one is refused with `A restore of this storage is already running!`, carrying the running restore as `activeRestore`. While a restore runs, the storage tools that change files, `create_storage_backup`, `clear_storage_backups` and deleting the backups the restore uses are refused with a `409`, and a restore cannot start while a backup of the same storage is still being archived.

A backup still being archived, one that failed and one taken in an older format cannot be restored. When you only want to see an old version of a file, `read_storage_backup_file` is the lighter answer. See [Restore a storage backup](https://modulify.ai/docs/editor/backups#restore-a-storage-backup).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site whose storage should be restored. |
| `backupId` | string | Yes | The backup to restore from, from `list_storage_backups`. |
| `mode` | string | Yes | `full` makes the whole storage match the backup and deletes every file added since. `selected` puts back only the `paths` you name. |
| `paths` | array of strings | No | For `selected` only: the files and folders to put back, from `browse_storage_backup`, at most 200. A path ending in a slash is a folder. Ignored for `full`. |
| `confirm` | string | No | The exact value the plan call returned. Leave it out on the first call to get the plan, since only a call carrying it starts the restore. |