Backups and Recovery
Introduction
Section titled “Introduction”The MCP Filesystem Ultra backup system protects your code against accidental loss. Every destructive operation (edit, delete) automatically creates a persistent backup that you can easily recover.
Key Benefits
Section titled “Key Benefits”- Automatic backups - Created automatically, no action required
- Intelligent validation - Warns you before risky changes
- Quick recovery - One command to restore lost code
- Complete audit trail - History of all changes
Automatic Backups
Section titled “Automatic Backups”When Are Backups Created?
Section titled “When Are Backups Created?”Backups are created automatically before:
- File edits (
edit_file) - Deletions (
delete_file) - Batch operations (
batch_operationswithcreate_backup: true)
Backup Location
Section titled “Backup Location”By default, backups are stored in:
- Windows:
%TEMP%\mcp-batch-backups\(typicallyC:\Users\<you>\AppData\Local\Temp\mcp-batch-backups\) - Linux/macOS:
$TMPDIR/mcp-batch-backups/(typically/tmp/mcp-batch-backups)
The server resolves temp/mcp-batch-backups relative to the OS temp directory. To use a different location, pass --backup-dir <path> (and the path must be in --allowed-paths).
Each backup has its own directory with a unique ID:
20241203-153045-abc123\├── metadata.json # Backup information└── files\ # Backed up files └── your_file.goConfiguration
Section titled “Configuration”Customize backup behavior in claude_desktop_config.json:
{ "mcpServers": { "filesystem-ultra": { "args": [ "--backup-dir", "C:\\Backups\\MCP", "--backup-max-age", "14", "--backup-max-count", "200", "C:\\your\\project\\", "C:\\Backups\\MCP" ] } }}Important: The backup directory MUST be in allowed paths.
Risk Validation
Section titled “Risk Validation”What Is Risk Validation?
Section titled “What Is Risk Validation?”Before editing a file, the system analyzes the impact of the change:
- Percentage of the file that will change
- Number of occurrences to replace
- Specific risk factors
Risk Levels
Section titled “Risk Levels”| Level | Conditions | Behavior |
|---|---|---|
| LOW | < 20% change, < 50 occurrences | Proceeds silently |
| MEDIUM | ≥ 20% change, OR ≥ 50 occurrences | Auto-backup + proceed + risk notice |
| HIGH | ≥ 75% change, OR ≥ 100 occurrences | Auto-backup + proceed + prominent warning |
| CRITICAL | ≥ 90% change | Auto-backup + proceed + VERIFY instruction — never blocked by risk level alone |
Thresholds are defaults and can be changed with
--risk-threshold-mediumand--risk-threshold-high. Occurrence thresholds are--risk-occurrences-medium(default 50) and--risk-occurrences-high(default 100). CRITICAL is fixed at ≥ 90% file change.Since v4.5.10, two additional safety guards can still block an
edit_fileindependently of the risk level:
- Accidental-rewrite guard — fires when
new_textis > 2× the size ofold_textAND > 50% of the file is outside the matched block ANDnew_textis > 500 B / > 50% of file size. Override withallow_rewrite: true(notforce:true).--auto-occ=block(v4.5.17) — rejects the edit if the session’s storedcontent_hashbaseline differs from the on-disk hash (another process wrote the file between read and edit).
Example: MEDIUM/HIGH Risk (Auto-Proceeds)
Section titled “Example: MEDIUM/HIGH Risk (Auto-Proceeds)”When editing a significant portion of a file:
edit_file({ path: "main.go", old_text: "// old implementation block...", new_text: "// new implementation block..."})Response (edit succeeds immediately):
Replaced 1 occurrence(s). Characters changed: ~400Backup: 20260302-143022-abc123
Risk notice [medium] 40.0% of file changed (1 occurrence(s), ~400 chars) Auto-backup: 20260302-143022-abc123 Restore with: backup({ action:"restore", backup_id })Example: CRITICAL Risk (Auto-Proceeds with Warning)
Section titled “Example: CRITICAL Risk (Auto-Proceeds with Warning)”When attempting to rewrite nearly the entire file:
edit_file({ path: "main.go", old_text: "func", new_text: "function" // This replaces most of the file})Response:
Replaced 1 occurrence(s). Characters changed: ~200Backup: 20260302-143022-def456
⚠️ RISK LEVEL: CRITICAL Almost complete file rewrite (95.3%) Auto-backup created: 20260302-143022-def456 VERIFY: read_file(mode:"tail") to confirm file is complete.For CRITICAL changes, the response includes a VERIFY instruction. The server does not block the edit; the rewrite guard (allow_rewrite) and OCC guard (--auto-occ=block) are the only things that can still block it.
Recommended Workflow
Section titled “Recommended Workflow”For MEDIUM/HIGH/CRITICAL risk changes: no special workflow is needed. The edit proceeds automatically and creates a backup. If something looks wrong, use the backup ID from the response:
backup({ action: "undo_last", file_path: "main.go" })For changes that trip the accidental-rewrite guard (very large new_text replacing a small anchor): override with allow_rewrite: true after reviewing.
edit_file({ path: "main.go", old_text: "// old header", new_text: "// new header...\n...many lines...", allow_rewrite: true})For external-change protection, run the server with --auto-occ=block or chain edits using expected_hash from the previous response.
Backup Management
Section titled “Backup Management”1. List Available Backups
Section titled “1. List Available Backups”backup({ action: "list", limit: 20, // Maximum to show filter_operation: "edit", // edit, delete, batch, all filter_path: "main.go", // Filter by file newer_than_hours: 24 // Only last 24 hours})Response:
Available Backups (3)
20241203-153045-abc123 Time: 2024-12-03 15:30:45 (2 hours ago) Operation: edit_file Files: 1 (12.1KB) Context: Edit: 12 occurrences, 35.2% change
20241203-140230-def456 Time: 2024-12-03 14:02:30 (3 hours ago) Operation: batch_operations Files: 47 (2.3MB) Context: Batch rename: 47 files
Use backup({ action:"restore", backup_id }) to restore files2. Get Detailed Information
Section titled “2. Get Detailed Information”backup({ action: "info", backup_id: "20241203-153045-abc123"})Response:
Backup Details: 20241203-153045-abc123
Timestamp: 2024-12-03 15:30:45 (2 hours ago)Operation: edit_fileContext: Edit: 12 occurrences, 35.2% changeTotal Size: 12.1KBFiles: 1
Files in backup: - C:\project\main.go (12.1KB)
Backup Location: C:\Users\...\mcp-batch-backups\20241203-153045-abc1233. Compare with Current State
Section titled “3. Compare with Current State”Before restoring, see what changed:
backup({ action: "compare", backup_id: "20241203-153045-abc123", file_path: "C:\\project\\main.go"})Response:
=== Comparison for C:\project\main.go ===Backup lines: 245Current lines: 268Difference: +23 lines
First differences:Line 12: - BACKUP: func oldName() { + CURRENT: func newName() {
Line 45: - BACKUP: // TODO: implement + CURRENT: // DONE: implementedFile Recovery
Section titled “File Recovery”Preview Mode (Recommended)
Section titled “Preview Mode (Recommended)”First, use preview mode to see what will be restored:
backup({ action: "restore", backup_id: "20241203-153045-abc123", file_path: "C:\\project\\main.go", preview: true})Response:
Preview Mode - Changes to be restored:
=== Comparison for C:\project\main.go ===[shows the diff]Actual Restoration
Section titled “Actual Restoration”If the preview looks correct, proceed with restoration:
backup({ action: "restore", backup_id: "20241203-153045-abc123", file_path: "C:\\project\\main.go"})Response:
Restore completed successfully
Restored 1 file(s): - C:\project\main.go
A backup of the current state was created before restoringNote: A backup of the current state is created before restoring, giving you double protection.
Restore All Files
Section titled “Restore All Files”Omit file_path to restore everything:
backup({ action: "restore", backup_id: "20241203-140230-def456" // Backup with 47 files})Backup Cleanup
Section titled “Backup Cleanup”Why Clean Up?
Section titled “Why Clean Up?”Backups take disk space. Regularly clean up old ones.
Dry Run (Recommended)
Section titled “Dry Run (Recommended)”First, see what would be deleted:
backup({ action: "cleanup", older_than_days: 7, dry_run: true})Response:
Dry Run Mode - Preview of cleanup operation
Would delete: 45 backup(s)Would free: 120.5MB
Run with dry_run: false to actually delete backupsExecute Cleanup
Section titled “Execute Cleanup”If you agree, execute the cleanup:
backup({ action: "cleanup", older_than_days: 7, dry_run: false})Response:
Cleanup completed
Deleted: 45 backup(s)Freed: 120.5MBAutomatic Cleanup
Section titled “Automatic Cleanup”The system automatically cleans up when:
backup_max_countis exceeded (default: 100)- Oldest backups are deleted first
Step-Through Undo (v4.3.8+)
Section titled “Step-Through Undo (v4.3.8+)”Instead of restoring a file in one jump, walk the backup chain one step at a time. Every edit_file / multi_edit links its new backup to the previous one for the same file via PreviousBackupID. Use undo_last with a file_path to walk the chain backwards.
Preview the next undo step
Section titled “Preview the next undo step”backup({ action: "undo_last", file_path: "main.go", preview: true})Returns a diff of what would be undone (without executing).
Execute one undo step
Section titled “Execute one undo step”backup({ action: "undo_last", file_path: "main.go"})Each undo_last undoes exactly one backup in the chain. Repeat until you reach the version you want. Without file_path, it undoes the most recent backup globally.
Show the full undo chain
Section titled “Show the full undo chain”backup({ action: "undo_chain", file_path: "main.go"})Returns the complete ordered list of backups for the file (oldest first), so the agent can decide which step to roll back to.
Soft-Delete Trash / SD-ID Flow (v4.5.11+)
Section titled “Soft-Delete Trash / SD-ID Flow (v4.5.11+)”Soft-deletes (the default behaviour of delete_file without permanent:true) are now integrated with the backup system via the SD-ID flow. When --backup-dir is configured, the response of a soft-delete returns:
- The SD-ID (e.g.
sd-...) - The trash path (e.g.
<backup-dir>/filesdelete/<sd-id>/<basename>) - A one-line restore command
List soft-deleted files
Section titled “List soft-deleted files”backup({ action: "list_trash" })backup({ action: "list_trash", filter_path: "main.go" })backup({ action: "list_trash", older_than_days: 30, limit: 50 })Restore one
Section titled “Restore one”backup({ action: "restore_trash", sd_id: "sd-..." })// Moves the file back to its original path// Refuses if the original path is currently occupied (no silent overwrite)Purge (permanent delete from trash)
Section titled “Purge (permanent delete from trash)”// Dry-run firstbackup({ action: "purge_trash", older_than_days: 30, dry_run: true })
// Real purgebackup({ action: "purge_trash", older_than_days: 30 })backup({ action: "purge_trash", sd_id: "sd-..." })The Dashboard Trash tab (v4.5.12+) shows the same entries through a web UI with View / Download / Restore / Purge per-row actions.
Common Use Cases
Section titled “Common Use Cases”Case 1: Safe Massive Edit
Section titled “Case 1: Safe Massive Edit”Situation: You need to change “func” to “function” throughout the file.
// 1. Analyze the impactanalyze_operation({ operation: "edit", path: "main.go", old_text: "func", new_text: "function"})
// 2. If safe, proceededit_file({ path: "main.go", old_text: "func", new_text: "function", force: true // If risky})
// 3. If something went wrong, restorebackup({ action: "restore", backup_id: "20241203-153045-abc123", file_path: "main.go"})Case 2: Emergency Recovery
Section titled “Case 2: Emergency Recovery”Situation: You accidentally overwrote an important file.
// 1. List recent backupsbackup({ action: "list", newer_than_hours: 2, filter_path: "important.go"})
// 2. Find the correct backupbackup({ action: "info", backup_id: "20241203-140230-def456"})
// 3. Compare to be surebackup({ action: "compare", backup_id: "20241203-140230-def456", file_path: "important.go"})
// 4. Restorebackup({ action: "restore", backup_id: "20241203-140230-def456", file_path: "important.go"})Case 3: Safe Batch Operations
Section titled “Case 3: Safe Batch Operations”Situation: You need to rename 50 files.
// 1. Batch with automatic backupbatch_operations({ operations: [ {type: "edit", path: "file1.go", old_text: "old", new_text: "new"}, // ... 49 more ], atomic: true, create_backup: true, force: true // If analysis requires it})
// 2. If something fails, rollback is automatic// Or you can restore manually if neededCase 4: Change Audit
Section titled “Case 4: Change Audit”Situation: You want to see what changes were made today.
// List all backups from todaybackup({ action: "list", newer_than_hours: 24, limit: 100})
// Review each onebackup({ action: "info", backup_id: "20241203-XXXXXX-XXXXXX"})
// Compare with current statebackup({ action: "compare", backup_id: "20241203-XXXXXX-XXXXXX", file_path: "file.go"})Advanced Configuration
Section titled “Advanced Configuration”Custom Risk Thresholds
Section titled “Custom Risk Thresholds”Adjust risk validation sensitivity:
{ "args": [ "--risk-threshold-medium", "40.0", "--risk-threshold-high", "60.0", "--risk-occurrences-medium", "75", "--risk-occurrences-high", "150" ]}Defaults (v4.5.26, per CLAUDE.md):
- MEDIUM: ≥ 30% change or ≥ 50 occurrences
- HIGH: ≥ 50% change or > 100 occurrences
- CRITICAL: ≥ 90% change (no longer hard-blocked; auto-proceeds with backup)
Backup Retention
Section titled “Backup Retention”Control how many backups to keep:
{ "args": [ "--backup-max-age", "14", "--backup-max-count", "200" ]}Defaults:
- Max age: 7 days
- Max count: 100 backups
Security and Reliability
Section titled “Security and Reliability”Data Integrity
Section titled “Data Integrity”- SHA256 hash of each file
- Integrity verification on restore
- JSON metadata for audit
Error Handling
Section titled “Error Handling”- Rollback if backup creation fails
- Backup of current state before restoring
- Descriptive error messages
Performance
Section titled “Performance”- Minimal overhead: approximately 5-10ms per small file
- Intelligent cache: Metadata in memory (refresh every 5 min)
- Non-blocking: Operations do not block the system
Tips and Best Practices
Section titled “Tips and Best Practices”1. Always Use Preview
Section titled “1. Always Use Preview”Before restoring, use preview mode:
backup({ action:"restore", backup_id: "...", file_path: "...", preview: true })2. Clean Up Regularly
Section titled “2. Clean Up Regularly”Establish a weekly routine:
backup({ action:"cleanup", older_than_days: 7, dry_run: false })3. Validate Large Changes
Section titled “3. Validate Large Changes”For massive edits, always use analyze_operation first.
4. Keep Backup Directory Accessible
Section titled “4. Keep Backup Directory Accessible”Ensure it is in allowed paths for full access.
Are backups automatically deleted?
Section titled “Are backups automatically deleted?”Not after success, but yes when:
- You exceed
backup_max_count - You run
backup({ action:"cleanup" })
Can I access backups manually?
Section titled “Can I access backups manually?”Yes, they are in the normal filesystem. You can copy, move them, etc.
What happens if I edit a file without backup?
Section titled “What happens if I edit a file without backup?”The system always creates a backup before editing. It is automatic.
Can I disable backups?
Section titled “Can I disable backups?”Not directly, but you can use --backup-max-age=0 to delete them immediately.
Do backups include binary content?
Section titled “Do backups include binary content?”Yes, any file type is backed up.
What if I run out of disk space?
Section titled “What if I run out of disk space?”The system will warn you, but it is better to clean up regularly with backup({ action:"cleanup" }).
Last updated: 2026-07-11 Version: 4.5.29