Skip to content

danielcregg/claude-sync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

claude-sync

Sync your Claude Code settings, skills, and config across machines

License: MIT Version 2.1.0 Claude Code Node.js Dependencies: git + gh Cross-platform

One command to sync your Claude Code skills, settings, agents, commands, and hooks to a private GitHub repo. One command to pull them on a new machine. Zero config. No encryption keys to manage. No cloud accounts to set up.


The Problem

You use Claude Code on multiple machines. Every time you set up a new one, you have to:

  • Reinstall all your custom skills
  • Reconfigure settings.json (plugins, permissions, model preferences)
  • Re-add all your MCP server definitions
  • Copy over agents, commands, hooks, and keybindings
  • Remember what you had and what you didn't

Or worse — you make a great skill on your laptop and forget to copy it to your desktop.

The Solution

# On every machine — just run init
claude-sync init

# That's it. init detects whether to push or pull automatically.

Quick Start

Install

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/danielcregg/claude-sync/main/install.sh | bash

Windows (PowerShell):

irm https://raw.githubusercontent.com/danielcregg/claude-sync/main/install.ps1 | iex

Manual (any platform — recommended if you prefer to audit the code first):

git clone https://github.com/danielcregg/claude-sync.git
node claude-sync/claude-sync.mjs version   # verify it works

Security note: The one-liner installers download and execute code from GitHub. If you prefer to review the code before running it, use the manual install method above. The SHA256SUM file in the repo can be used for manual verification.

Every Machine — Just Run Init

claude-sync init

That's it. init is smart — it detects your situation automatically:

Scenario What init Does
First machine (no sync repo exists) Creates a private GitHub repo, pushes your config
New machine (fresh Claude Code install) Detects the remote repo, pulls your config
Existing machine (has settings & skills) Backs up your config, shows what's different, pulls remote config, tells you how to merge

You never need to figure out whether to run clone, diff, or backupinit handles it all.

Keep in Sync

claude-sync push              # After making changes
claude-sync pull              # Before starting work on another machine
claude-sync status            # Check what's changed

Settings auto-sync on session end via a Stop hook (installed by init).


What Gets Synced

SyncedNot Synced (excluded by default)
File/Dir What
settings.json Plugins, permissions, model prefs
skills/ All custom skills
agents/ Custom agents
commands/ Custom slash commands
hooks/ Hook definitions
rules/ Custom rules
CLAUDE.md Global instructions
keybindings.json Key bindings
statusline-command.sh Status line
plugins/installed_plugins.json Plugin list
plugins/known_marketplaces.json Marketplace config
plugins/blocklist.json Blocked plugins
mcp-servers-sync.json MCP server definitions
File/Dir Why
.credentials.json Contains secrets
projects/ 85MB+, machine-specific
local/ 176MB, node dependencies
telemetry/ Machine-specific
debug/ Machine-specific logs
cache/ Regenerated automatically
shell-snapshots/ Environment-specific
history.jsonl Personal conversations
paste-cache/ May contain secrets
statsig/ Session analytics
sessions/, ide/ Process-specific
backups/ May contain secrets

The .gitignore is carefully tuned to sync everything useful while excluding everything sensitive or machine-specific. Credentials never leave your machine.

MCP Server Sync (v2.1.0)

MCP server definitions from ~/.claude.json are automatically extracted, synced, and merged across machines:

claude-sync list    # See your synced MCP servers

On push: MCP servers are collected from all projects in ~/.claude.json, deduplicated, and saved to mcp-servers-sync.json.

On pull/clone: MCP servers from the sync file are merged into your local ~/.claude.json — existing servers are never overwritten, only missing ones are added.

Note: MCP servers that use npx commands (like @playwright/mcp) work everywhere. Servers with local paths (like Python venvs) may need manual adjustment on each machine.

Cross-Platform Path Handling (v2.1.0)

Paths in synced files are automatically normalized using git smudge/clean filters:

  • In the repo: paths use {{CLAUDE_SYNC_HOME}} placeholder
  • On your machine: paths use your real home directory (/home/you, C:\Users\you, etc.)
  • git status: shows clean — the translation is transparent

This means settings.json, marketplace config, and MCP server paths all work correctly when synced between Linux, macOS, and Windows.


Commands

Command What It Does
claude-sync init First-time setup — creates repo, pushes, installs auto-sync hook
claude-sync init --no-hook Setup without auto-sync hook
claude-sync push Commit and push changes
claude-sync push -m "msg" Push with custom message
claude-sync pull Pull latest from GitHub
claude-sync status Show changes and sync state
claude-sync clone [user] Set up new machine from existing repo (auto-detects GitHub user)
claude-sync diff / preview Preview what would change before cloning (safe, read-only)
claude-sync backup Back up current config before syncing
claude-sync list / ls Show local config (skills, commands, MCP servers, plugins)
claude-sync list --remote Show what's on GitHub
claude-sync devices Show all machines syncing with this config
claude-sync doctor Check sync health, detect issues
claude-sync reset Force-align local with remote (backs up first)
claude-sync hook Install the auto-sync hook
claude-sync version Show version

Flags

Flag Works With What It Does
-m, --message push Custom commit message
-q, --quiet push, pull Minimal output
-n, --dry-run push, pull Preview without changes
--no-hook init Skip auto-sync hook

Auto-Sync (Enabled by Default)

claude-sync init automatically installs a Stop hook that pushes your config to GitHub whenever a Claude Code session ends. Your settings stay in sync without you having to remember to run push.

To skip this during setup: claude-sync init --no-hook

To install it later: claude-sync hook

The hook adds this to your settings.json (with the absolute path to your install):

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "node /home/you/.local/bin/claude-sync.mjs push -q -m auto-sync",
        "timeout": 30
      }]
    }]
  }
}

The path is detected automatically at install time — no manual editing needed.


Syncing to an Existing Machine

Already have Claude Code set up on another machine with settings you want to keep? Don't blindly clone — preview first:

# 1. See what would change
claude-sync diff

# 2. Back up your current config
claude-sync backup

# 3. Clone the remote config
claude-sync clone

# 4. If you lost something, restore from backup
cp ~/.claude-backup-2026-03-24T23-30-00/skills/my-local-skill ~/.claude/skills/
claude-sync push -m "merged local skill"

diff is completely read-only — it clones the remote repo to a temp directory, compares, and cleans up. Your local config is never touched.


Security

  • Private repo: claude-sync init creates a private GitHub repo. Only you can see it.
  • Credentials excluded: .credentials.json and all secret files are in .gitignore and never committed.
  • No encryption needed: Since the repo is private and credentials are excluded, there's nothing sensitive to encrypt.
  • Doctor check: claude-sync doctor verifies that no secrets are accidentally tracked.
  • No third-party services: Uses only git and gh (GitHub CLI) — tools you already have.

What about API keys?

If you have API keys in settings.json or in MCP server env blocks (e.g., Twitter API keys, RapidAPI keys), they will be synced to your private repo. Options:

  1. The repo is private — only you can access it
  2. Move secrets to environment variables on each machine instead
  3. Use settings.local.json for machine-specific secrets (excluded from sync)
  4. Use your OS keychain for sensitive values

How It Works

┌──────────────────────────────────────────────────────────┐
│  Machine A                        Machine B              │
│  ~/.claude/                       ~/.claude/             │
│  ├── settings.json                ├── settings.json      │
│  ├── skills/                      ├── skills/            │
│  ├── agents/                      ├── agents/            │
│  └── ...                          └── ...                │
│       │                                │                 │
│       │ claude-sync push               │ claude-sync pull│
│       ▼                                ▼                 │
│  ┌─────────────────────────────────────────┐             │
│  │  GitHub (private repo)                  │             │
│  │  yourname/claude-sync-config            │             │
│  └─────────────────────────────────────────┘             │
└──────────────────────────────────────────────────────────┘

Under the hood, claude-sync is a single Node.js script that initializes a git repo inside ~/.claude/, adds a comprehensive .gitignore, and pushes to a private GitHub repo. It uses git smudge/clean filters for cross-platform path normalization and extracts MCP server definitions from ~/.claude.json. No magic. No daemons. No cloud services. Just Node.js and git.


Requirements

  • Node.js — you already have this (Claude Code requires it)
  • git — you almost certainly have this
  • gh (GitHub CLI) — install here if you don't have it
  • A GitHub account — free tier works fine (unlimited private repos)

Compared to Alternatives

Feature claude-sync dotfiles (manual) tawanorg/claude-sync FelixIsaac/claude-code-sync
One-command setup Yes No Yes Yes
PowerShell support Yes No No No
No compiled binary Yes Yes No (Go) No (Go)
No cloud account Yes Yes No (R2/S3/GCS) Yes
No encryption keys Yes Yes No (passphrase) No (age keypair)
Auto-sync hook Yes No Yes No
Smart .gitignore Yes Manual Hardcoded Hardcoded
Doctor/health check Yes No No Yes
Dependencies Node.js, git, gh git npm + Go binary Go binary

Compatibility

Platform Status
macOS (bash/zsh) Fully supported
Linux (bash/zsh) Fully supported
Windows (PowerShell) Fully supported
Windows (cmd) Fully supported
Windows (Git Bash / WSL) Fully supported

FAQ

Can I use this with an existing dotfiles repo?

Yes. If you already have a dotfiles repo with a .claude/ directory, you can either:

  1. Continue using your dotfiles repo and skip claude-sync
  2. Switch to claude-sync which creates a dedicated repo just for Claude config

They solve the same problem differently. claude-sync is purpose-built for Claude Code and has a smarter .gitignore.

What happens if I change settings on two machines without syncing?

claude-sync pull uses git rebase by default. If there's a conflict, it will stash your local changes, pull, and try to re-apply them. If there's a merge conflict, it tells you and you resolve it like any git conflict.

Can multiple people share a sync repo?

This is designed for personal use (one person, multiple machines). For team config, use a project-level .claude/settings.json in your team's repo instead.

How do I stop syncing?
rm -rf ~/.claude/.git ~/.claude/.gitignore

This removes the git repo from .claude/ without affecting your config.

Is my conversation history synced?

No. history.jsonl and projects/ are excluded by default. Conversations stay on the machine where they happened.


Contributing

Contributions welcome. This is a single-file Node.js script — keep it simple, no npm dependencies.

  1. Fork this repository
  2. Create a feature branch
  3. Test on macOS, Linux, and Windows (PowerShell + Git Bash)
  4. Open a Pull Request

License

MIT

About

Sync Claude Code settings, skills, and config across machines. One command to setup, one command to clone. Private GitHub repo, smart .gitignore, no encryption needed. Just git.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors