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-migrateThis 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@latestThen create a csm alias so the examples below work:
# macOS / Linux (add to ~/.zshrc or ~/.bashrc)
alias csm='cc-session-migrate'
# Windows PowerShell (add to $PROFILE)
Set-Alias csm cc-session-migrateTip: 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:
# Linux
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# macOS / Windows (run in tmux or a dedicated terminal)
csm agent --server --name server-01Step 2 — On each agent machine, join the cluster:
# Linux
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# macOS / Windows (run in tmux or a dedicated terminal)
csm agent --server-addr <server-ip>:9827 --auth-token <token> --name my-macbookStep 3 — Verify cluster status:
csm cluster list# List sessions on a remote node
csm session list --node macbook-pro
# Pull a session (supports ID prefix matching, minimum 8 characters)
csm session pull cebea1f8 --from macbook-pro --project /home/user/my-project
# Push a session
csm session push cebea1f8 --to server-01
# Batch migrate all sessions
csm session pull --from macbook-pro --all
# Resume development after migration
# NOTE: claude --resume requires the FULL session ID (not a prefix).
# Use `csm session list` to find the full ID from the SESSION ID column.
claude --resume 47f57b56-48b3-4405-b01d-3b8591874fe2# Configure S3 storage
csm backup config \
--endpoint https://xxx.r2.cloudflarestorage.com \
--bucket csm-backups \
--access-key $ACCESS_KEY \
--secret-key $SECRET_KEY
# Back up all sessions
csm backup create
# List backups
csm backup list
# Restore a specific session
csm backup restore --node server-01 --session <session-id> --project /home/user/project
# Restore the latest backup
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: 30All 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 |
# Build (with version info injection)
make build
# Run all tests
make test
# Clean build artifacts
make cleancc-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

