Daily backup of ~/.claude (Claude Code config, memory, sessions, transcripts)
to a versioned local git repo plus a private off-site remote via
rclone.
~/.claude contains:
- Full conversation transcripts (everything you ever pasted into Claude Code, including code, secrets, error messages, internal docs)
- MCP server configurations in
~/.claude.jsonbackups, which often hold OAuth tokens and API keys - Shell snapshots that may contain environment variables, including secrets exported in your shell
- Recently-opened project paths, filenames, and todos
Treat the data/ directory and your local .git history as highly
sensitive. Push them only to a private destination (private Google Drive,
Backblaze B2, S3 with private ACL, a private GitHub repo, etc.). This
repository contains only the scripts — never commit data/ to any public
location.
rsyncmirrors~/.claude/into./data/(with an exclude list for caches and telemetry).git add -A+ commit of any diff, with aDaily sync YYYY-MM-DD HH:MM:SSmessage.- Weekly
git gc --autoon Sundays. rclone syncof the entire repo directory (working tree and.git) to your configured private remote.
A macOS LaunchAgent runs the script daily at a time you configure.
- macOS (for the LaunchAgent; the scripts themselves work anywhere with bash)
rsync,git,bashrcloneconfigured with a private remote (rclone config— Google Drive, B2, S3, …). Skip this if you only want local git versioning.
# 1. Clone next to your other repos
git clone https://github.com/stepanic/dotclaude-sync.git ~/git/dotclaude-sync
cd ~/git/dotclaude-sync
# 2. Configure
cp config.sh.example config.sh
$EDITOR config.sh
# Set DOTCLAUDE_REPO_DIR, DOTCLAUDE_RCLONE_REMOTE, your git identity,
# and the launchd label/time.
# 3. Install the daily job
chmod +x sync.sh restore.sh install-launchd.sh uninstall-launchd.sh
bash install-launchd.shVerify:
launchctl list | grep dotclaude-sync
launchctl start "$(grep '^LAUNCHD_LABEL' config.sh | cut -d'"' -f2)" # run once now
tail -f sync.logEverything under ~/.claude/ except the patterns in exclude.txt:
cache/,paste-cache/— local cachetelemetry/,statsig/,usage-data/— telemetrystats-cache.json,mcp-needs-auth-cache.jsonide/,debug/— empty / debug.DS_Store,.last-cleanup
Edit exclude.txt to adjust.
Pull the repo from your private remote, then run restore.sh:
mkdir -p ~/git && cd ~/git
rclone copy mydrive:dotclaude-sync ./dotclaude-sync --transfers=8 --fast-list
cd dotclaude-sync
cp config.sh.example config.sh && $EDITOR config.sh
bash restore.shrestore.sh uses rsync without --delete, so existing files on the target
machine that are not in the backup (caches, telemetry) are preserved.
dotclaude-sync/
├── README.md
├── LICENSE # MIT
├── .gitignore # ignores config.sh, data/, logs
├── config.sh.example # template — copy to config.sh
├── exclude.txt # rsync exclude list
├── sync.sh # mirror + commit + rclone push
├── restore.sh # recovery
├── install-launchd.sh # render plist + launchctl load
├── uninstall-launchd.sh
└── com.user.dotclaude-sync.plist.template
config.sh, data/, and the log files are gitignored.
bash uninstall-launchd.shThe script unloads and removes ~/Library/LaunchAgents/<label>.plist. Your
local mirror in data/ and the git history are kept; remove the directory
manually if you want them gone.
MIT — see LICENSE.