Cross-node migration and backup tool for Claude Code sessions. Migrate session data between development machines and back up to any S3-compatible storage.
Claude Code stores session data on local disk (~/.claude/
). When you start a session on your MacBook and switch to an Ubuntu server to continue, the context is lost β the session is locked to the original machine.
csm
solves this with a Consul-style cluster model, making session data portable across nodes.
ββββββββββββββββββββββββββββ
β Server (Leader) β
β β
β Β· cluster topology β
β Β· WebSocket hub β
β Β· session relay β
β Β· S3 backup β
β HTTP + WS :9827 β
βββββββ¬βββββββββββ¬ββββββββββ
WS β β WS
βββββββββββββ βββββββββββββ
βΌ βΌ
βββββββββββββββββ βββββββββββββββββ
β Agent A β β Agent B β
β (MacBook) β β (SVR1) β
β β β β
β session ops β β session ops β
β S3 backup β β S3 backup β
β (no listen) β β (no listen) β
βββββββββββββββββ βββββββββββββββββ
Cluster mgmt: agents β server (WebSocket)
Session migration: any node β any node (relayed via server WebSocket)
S3 backup: per-node, independent storage
The server (Leader) runs an HTTP server with a WebSocket endpoint. All agents maintain persistent outbound WebSocket connections to the server β no inbound ports required on agent machines, solving NAT traversal issues.
Server modeβ Cluster leader. Manages topology, accepts agent WebSocket connections, relays session operations between nodes.** Agent mode**β Connects to the server via outbound WebSocket. Handles session commands relayed by the server. No port listening needed.S3 backupβ Optional. Each node independently configures R2/MinIO/any S3-compatible storage.
Linux (recommended for server node):
make build
sudo ./scripts/install.sh --local ./bin/cc-session-migrate
This installs the binary to /usr/local/bin
, sets up the csm
alias, creates the systemd service, and generates a default config at /etc/cc-session-migrate/env
.
macOS / Windows:
go install github.com/bigwhite/cc-session-migrate@latest
Then create a csm
alias so the examples below work:
alias csm='cc-session-migrate'
Set-Alias csm cc-session-migrate
Tip:Run the server (leader) node on a Linux server that is always online. Agent nodes on your laptop or other machines can join and leave freely.
Step 1 β Start the server node:
sudo sed -i 's/CSM_AGENT_ROLE=agent/CSM_AGENT_ROLE=server/' /etc/cc-session-migrate/env
sudo systemctl enable --now cc-session-migrate
cat ~/.csm/config.yaml # view the generated cluster-id and auth-token
csm agent --server --name server-01
Step 2 β On each agent machine, join the cluster:
make build && sudo ./scripts/install.sh --local ./bin/cc-session-migrate
sudo sed -i 's/# CSM_CLUSTER_SERVER_ADDR=/CSM_CLUSTER_SERVER_ADDR=<server-ip>:9827/' /etc/cc-session-migrate/env
sudo sed -i 's/# CSM_CLUSTER_AUTH_TOKEN=/CSM_CLUSTER_AUTH_TOKEN=<token>/' /etc/cc-session-migrate/env
sudo systemctl enable --now cc-session-migrate
csm agent --server-addr <server-ip>:9827 --auth-token <token> --name my-macbook
Step 3 β Verify cluster status:
csm cluster list
csm session list --node macbook-pro
csm session pull cebea1f8 --from macbook-pro --project /home/user/my-project
csm session push cebea1f8 --to server-01
csm session pull --from macbook-pro --all
claude --resume 47f57b56-48b3-4405-b01d-3b8591874fe2
csm backup config \
--endpoint https://xxx.r2.cloudflarestorage.com \
--bucket csm-backups \
--access-key $ACCESS_KEY \
--secret-key $SECRET_KEY
csm backup create
csm backup list
csm backup restore --node server-01 --session <session-id> --project /home/user/project
csm backup restore --node server-01 --session <session-id>
In daemon mode, automatic scheduled backups are available (incremental, based on file mtime). Expired backups are cleaned up automatically (30-day retention by default, minimum 3 copies retained per session).
| Flag | Default | Description |
|---|---|---|
--config |
||
~/.csm/config.yaml |
||
| Config file path | ||
--verbose / -v |
||
false |
||
| Verbose output |
| Flag | Default | Description |
|---|---|---|
--server |
||
false |
||
| Run in server (leader) mode | ||
--server-addr |
||
| Leader address for agent mode (host:port) | ||
--auth-token |
||
| Cluster auth token (agent mode) | ||
--bind |
||
0.0.0.0:9827 |
||
| HTTP listen address (server mode only) | ||
--name |
||
| hostname | Node name | |
--data-dir |
||
~/.claude |
||
| Claude Code data directory |
| Subcommand | Description |
|---|---|
leave |
|
Leave the cluster (--force for forced leave) |
|
list |
|
| List cluster nodes (`--format table | json` ) |
| Subcommand | Description |
|---|---|
list |
|
List sessions (--node for remote query, `--format table |
json` ) |
pull |
|
Pull a session (--from source node, --project path mapping, --all batch) |
|
push |
|
Push a session (--to target node, --project path mapping, --all batch) |
| Subcommand | Description |
|---|---|
config |
|
Configure S3 storage (--endpoint + --bucket required) |
|
create |
|
Create backups (--session for single, all by default) |
|
list |
|
List backups (--node / --session filter, `--format table |
json` ) |
restore |
|
Restore a backup (--node + --session required, --timestamp optional) |
Prints version, build time, Go version, and OS/Arch.
Config file at ~/.csm/config.yaml
, auto-generated on first run:
node:
name: "server-01"
data_dir: "~/.claude"
agent:
role: "server"
bind: "0.0.0.0:9827"
cluster:
id: "a1b2c3d4-..."
auth_token: "e5f6a7b8..."
server_addr: ""
s3:
endpoint: ""
bucket: ""
region: "auto"
access_key: ""
secret_key: ""
backup:
auto_enabled: true
interval: "0 3 * * *"
retention_days: 30
All config values can be overridden via CSM_
-prefixed environment variables (e.g., CSM_AGENT_ROLE=server
). Config file permissions are automatically set to 0600
.
| Dependency | Purpose |
|---|---|
spf13/cobra |
|
| CLI framework | |
spf13/viper |
|
| Configuration (YAML + env vars) | |
gorilla/websocket |
|
| WebSocket connections (hub-and-spoke) | |
aws/aws-sdk-go-v2 |
|
| S3 client (R2/MinIO compatible) | |
robfig/cron/v3 |
|
| Scheduled backup | |
schollz/progressbar/v3 |
|
| Transfer progress bar |
make build
make test
make clean
cc-session-migrate/
βββ cmd/ # CLI commands (cobra)
βββ internal/
β βββ agent/ # Daemon core (server / agent modes)
β βββ cluster/ # Cluster topology management
β βββ session/ # Session scanning, packing, path mapping, ID matching
β βββ ws/ # WebSocket protocol, hub (server), agent client
β βββ api/ # HTTP API types, server, and client
β βββ store/ # S3 client wrapper
β βββ backup/ # Backup create, restore, list, scheduler
β βββ config/ # Configuration (viper)
β βββ log/ # Logging (slog)
βββ scripts/ # Install script, systemd unit
βββ doc/ # PRD, Feature Specs, Plan, Tasks
Session ID prefix matchingβ Git-style, minimum 8 characters, errors on ambiguity** Atomic migration**β Writes to staging directory first, atomic move after SHA256 verification** Streaming transfer**β 64KB chunked streaming, bounded memory usage** Path mapping**β Text replacement in JSONL content for cross-machine project path differences** WebSocket keepalive**β Persistent WebSocket connections with ping/pong, automatic reconnection with exponential backoff** Hub-and-spoke relay**β Session data relayed through the server, no direct node-to-node connections needed (NAT-friendly)** Incremental backup**β Based on file mtime, only backs up changed sessions** Expiration cleanup**β 30-day retention by default, minimum 3 copies per session
| Platform | Architecture |
|---|---|
| Linux | amd64, arm64 |
| macOS | amd64, arm64 |
| Windows | amd64, arm64 |
If you find csm
useful, consider buying me a coffee!
WeChat Pay / Alipay:
MIT