Backup and restore ClawdBot configuration, skills, commands, and settings. Sync across devices, version control with git, automate backups, and migrate to new machines.
OpenClaw skills run inside an OpenClaw container. EasyClawd deploys and manages yours ā no server setup needed.
clawdbot-backup 1.0.0 ā Initial public release - Backs up and restores ClawdBot configuration, skills, commands, and settings. - Supports syncing across devices and version control integration with git. - Provides full-featured and quick backup scripts for skills, settings, and full backups. - Automates backup routines and cleanup of old backups. - Enables migration to new machines and restores from archive files.
---
name: clawdbot-backup
description: Backup and restore ClawdBot configuration, skills, commands, and settings. Sync across devices, version control with git, automate backups, and migrate to new machines.
homepage: https://github.com/clawdbot/backup-skill
metadata: {"clawdbot":{"emoji":"š¾","requires":{"bins":["git","tar","rsync"],"env":[]}}}
---
# ClawdBot Backup Skill
Backup, restore, and sync your ClawdBot configuration across devices directly from Clawdbot.
## Overview
This skill helps you:
- Backup all ClawdBot data and settings
- Restore from backups
- Sync between multiple machines
- Version control your configuration
- Automate backup routines
- Migrate to new devices
## ClawdBot Directory Structure
### Key Locations
```
~/.claude/ # Main ClawdBot directory
āāā settings.json # Global settings
āāā settings.local.json # Local overrides (machine-specific)
āāā projects.json # Project configurations
āāā skills/ # Your custom skills
ā āāā skill-name/
ā ā āāā SKILL.md
ā ā āāā supporting-files/
ā āāā another-skill/
āāā commands/ # Custom slash commands (legacy)
ā āāā command-name.md
āāā contexts/ # Saved contexts
āāā templates/ # Response templates
āāā mcp/ # MCP server configurations
āāā servers.json
~/projects/ # Your projects (optional backup)
āāā project-1/
ā āāā .claude/ # Project-specific config
ā āāā settings.json
ā āāā skills/
āāā project-2/
```
### What to Backup
```
ESSENTIAL (Always backup):
ā ~/.claude/skills/ # Custom skills
ā ~/.claude/commands/ # Custom commands
ā ~/.claude/settings.json # Global settings
ā ~/.claude/mcp/ # MCP configurations
RECOMMENDED (Usually backup):
ā ~/.claude/contexts/ # Saved contexts
ā ~/.claude/templates/ # Templates
ā Project .claude/ folders # Project configs
OPTIONAL (Case by case):
ā ~/.claude/settings.local.json # Machine-specific
ā Cache directories # Can be rebuilt
ā Log files # Usually not needed
```
## Quick Backup Commands
### Full Backup
```bash
# Create timestamped backup
BACKUP_DIR="$HOME/clawdbot-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="clawdbot_backup_$TIMESTAMP"
mkdir -p "$BACKUP_DIR"
tar -czvf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" \
-C "$HOME" \
.claude/skills \
.claude/commands \
.claude/settings.json \
.claude/mcp \
.claude/contexts \
.claude/templates \
2>/dev/null
echo "Backup created: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
```
### Quick Skills-Only Backup
```bash
# Backup just skills
tar -czvf ~/clawdbot_skills_$(date +%Y%m%d).tar.gz \
-C "$HOME" .claude/skills .claude/commands
```
### Restore from Backup
```bash
# Restore full backup
BACKUP_FILE="$HOME/clawdbot-backups/clawdbot_backup_20260129.tar.gz"
# Preview contents first
tar -tzvf "$BACKUP_FILE"
# Restore (will overwrite existing)
tar -xzvf "$BACKUP_FILE" -C "$HOME"
echo "Restore complete!"
```
## Backup Script
### Full-Featured Backup Script
```bash
#!/bin/bash
# clawdbot-backup.sh - Comprehensive ClawdBot backup tool
set -e
# Configuration
BACKUP_ROOT="${CLAWDBOT_BACKUP_DIR:-$HOME/clawdbot-backups}"
CLAUDE_DIR="$HOME/.claude"
MAX_BACKUPS=10 # Keep last N backups
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Check if ClawdBot directory exists
check_claude_dir() {
if [ ! -d "$CLAUDE_DIR" ]; then
log_error "ClawdBot directory not found: $CLAUDE_DIR"
exit 1
fi
}
# Create backup
create_backup() {
local backup_type="${1:-full}"
local backup_name="clawdbot_${backup_type}_${TIMESTAMP}"
local backup_path="$BACKUP_ROOT/$backup_name.tar.gz"
mkdir -p "$BACKUP_ROOT"
log_info "Creating $backup_type backup..."
case $backup_type in
full)
tar -czvf "$backup_path" \
-C "$HOME" \
.claude/skills \
.claude/commands \
.claude/settings.json \
.claude/settings.local.json \
.claude/projects.json \
.claude/mcp \
.claude/contexts \
.claude/templates \
2>/dev/null || true
;;
skills)
tar -czvf "$backup_path" \
-C "$HOME" \
.claude/skills \
.claude/commands \
2>/dev/null || true
;;
settings)
tar -czvf "$backup_path" \
-C "$HOME" \
.claude/settings.json \
.claude/settings.local.json \
.claude/mcp \
2>/dev/null || true
;;
*)
log_error "Unknown backup type: $backup_type"
exit 1
;;
esac
if [ -f "$backup_path" ]; then
local size=$(du -h "$backup_path" | cut -f1)
log_info "Backup created: $backup_path ($size)"
else
log_error "Backup failed!"
exit 1
fi
}
# List backups
list_backups() {
log_info "Available backups in $BACKUP_ROOT:"
echo ""
if [ -d "$BACKUP_ROOT" ]; then
ls -lh "$BACKUP_ROOT"/*.tar.gz 2>/dev/null | \
awk '{print $9, $5, $6, $7, $8}' || \
echo "No backups found."
else
echo "Backup directory doesn't exist."
fi
}
# Restore backup
restore_backup() {
local backup_file="$1"
if [ -z "$backup_file" ]; then
log_error "Please specify backup file"
list_backups
exit 1
fi
if [ ! -f "$backup_file" ]; then
# Try relative path in backup dir
backup_file="$BACKUP_ROOT/$backup_file"
fi
if [ ! -f "$backup_file" ]; then
log_error "Backup file not found: $backup_file"
exit 1
fi
log_warn "This will overwrite existing configuration!"
read -p "Continue? (y/N) " confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
log_info "Restore cancelled."
exit 0
fi
log_info "Restoring from: $backup_file"
tar -xzvf "$backup_file" -C "$HOME"
log_info "Restore complete!"
}
# Clean old backups
cleanup_backups() {
log_info "Cleaning old backups (keeping last $MAX_BACKUPS)..."
cd "$BACKUP_ROOT" 2>/dev/null || return
local count=$(ls -1 *.tar.gz 2>/dev/null | wc -l)
if [ "$count" -gt "$MAX_BACKUPS" ]; then
local to_delete=$((count - MAX_BACKUPS))
ls -1t *.tar.gz | tail -n "$to_delete" | xargs rm -v
log_info "Removed $to_delete old backup(s)"
else
log_info "No cleanup needed ($count backups)"
fi
}
# Show backup stats
show_stats() {
log_info "ClawdBot Backup Statistics"
echo ""
echo "=== Directory Sizes ==="
du -sh "$CLAUDE_DIR"/skills 2>/dev/null || echo "Skills: N/A"
du -sh "$CLAUDE_DIR"/commands 2>/dev/null || echo "Commands: N/A"
du -sh "$CLAUDE_DIR"/mcp 2>/dev/null || echo "MCP: N/A"
du -sh "$CLAUDE_DIR" 2>/dev/null || echo "Total: N/A"
echo ""
echo "=== Skills Count ==="
find "$CLAUDE_DIR/skills" -name "SKILL.md" 2>/dev/null | wc -l | xargs echo "Skills:"
find "$CLAUDE_DIR/commands" -name "*.md" 2>/dev/null | wc -l | xargs echo "Commands:"
echo ""
echo "=== Backup Directory ==="
if [ -d "$BACKUP_ROOT" ]; then
du -sh "$BACKUP_ROOT"
ls -1 "$BACKUP_ROOT"/*.tar.gz 2>/dev/null | wc -l | xargs echo "Backup files:"
else
echo "No backups yet"
fi
}
# Usage
usage() {
cat << EOF
ClawdBot Backup Tool
Usage: $(basename $0) <command> [options]
Commands:
backup [type] Create backup (typesRead full documentation on ClawHub