{"slug": "show-hn-cc-session-migrate-cross-node-migration-for-claude-code-sessions", "title": "Show HN: Cc-session-migrate: Cross-node migration for Claude Code sessions", "summary": "A new open-source tool, cc-session-migrate (csm), enables cross-node migration and backup of Claude Code sessions between machines using a Consul-style cluster model. Developed by GitHub user bigwhite, the tool uses a leader server with WebSocket relay to transfer session data between agents without requiring inbound ports, solving NAT traversal issues. The project supports S3-compatible storage backup and is available for Linux, macOS, and Windows.", "body_md": "Cross-node migration and backup tool for Claude Code sessions. Migrate session data between development machines and back up to any S3-compatible storage.\n\nClaude Code stores session data on local disk (`~/.claude/`\n\n). 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.\n\n`csm`\n\nsolves this with a Consul-style cluster model, making session data portable across nodes.\n\n```\n                          ┌──────────────────────────┐\n                          │    Server (Leader)        │\n                          │                          │\n                          │  · cluster topology       │\n                          │  · WebSocket hub          │\n                          │  · session relay          │\n                          │  · S3 backup              │\n                          │  HTTP + WS :9827          │\n                          └─────┬──────────┬─────────┘\n                         WS     │          │     WS\n                    ┌───────────┘          └───────────┐\n                    ▼                                  ▼\n            ┌───────────────┐                  ┌───────────────┐\n            │  Agent A      │                  │  Agent B      │\n            │  (MacBook)    │                  │  (SVR1)       │\n            │               │                  │               │\n            │  session ops  │                  │  session ops  │\n            │  S3 backup    │                  │  S3 backup    │\n            │  (no listen)  │                  │  (no listen)  │\n            └───────────────┘                  └───────────────┘\n\n   Cluster mgmt:       agents → server (WebSocket)\n   Session migration:  any node ↔ any node (relayed via server WebSocket)\n   S3 backup:          per-node, independent storage\n```\n\nThe 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.\n\n**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.\n\n**Linux (recommended for server node):**\n\n```\nmake build\nsudo ./scripts/install.sh --local ./bin/cc-session-migrate\n```\n\nThis installs the binary to `/usr/local/bin`\n\n, sets up the `csm`\n\nalias, creates the systemd service, and generates a default config at `/etc/cc-session-migrate/env`\n\n.\n\n**macOS / Windows:**\n\n```\ngo install github.com/bigwhite/cc-session-migrate@latest\n```\n\nThen create a `csm`\n\nalias so the examples below work:\n\n```\n# macOS / Linux (add to ~/.zshrc or ~/.bashrc)\nalias csm='cc-session-migrate'\n\n# Windows PowerShell (add to $PROFILE)\nSet-Alias csm cc-session-migrate\n```\n\nTip: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.\n\n**Step 1** — Start the server node:\n\n```\n# Linux\nsudo sed -i 's/CSM_AGENT_ROLE=agent/CSM_AGENT_ROLE=server/' /etc/cc-session-migrate/env\nsudo systemctl enable --now cc-session-migrate\ncat ~/.csm/config.yaml    # view the generated cluster-id and auth-token\n# macOS / Windows (run in tmux or a dedicated terminal)\ncsm agent --server --name server-01\n```\n\n**Step 2** — On each agent machine, join the cluster:\n\n```\n# Linux\nmake build && sudo ./scripts/install.sh --local ./bin/cc-session-migrate\nsudo sed -i 's/# CSM_CLUSTER_SERVER_ADDR=/CSM_CLUSTER_SERVER_ADDR=<server-ip>:9827/' /etc/cc-session-migrate/env\nsudo sed -i 's/# CSM_CLUSTER_AUTH_TOKEN=/CSM_CLUSTER_AUTH_TOKEN=<token>/' /etc/cc-session-migrate/env\nsudo systemctl enable --now cc-session-migrate\n# macOS / Windows (run in tmux or a dedicated terminal)\ncsm agent --server-addr <server-ip>:9827 --auth-token <token> --name my-macbook\n```\n\n**Step 3** — Verify cluster status:\n\n```\ncsm cluster list\n# List sessions on a remote node\ncsm session list --node macbook-pro\n\n# Pull a session (supports ID prefix matching, minimum 8 characters)\ncsm session pull cebea1f8 --from macbook-pro --project /home/user/my-project\n\n# Push a session\ncsm session push cebea1f8 --to server-01\n\n# Batch migrate all sessions\ncsm session pull --from macbook-pro --all\n\n# Resume development after migration\n# NOTE: claude --resume requires the FULL session ID (not a prefix).\n# Use `csm session list` to find the full ID from the SESSION ID column.\nclaude --resume 47f57b56-48b3-4405-b01d-3b8591874fe2\n# Configure S3 storage\ncsm backup config \\\n  --endpoint https://xxx.r2.cloudflarestorage.com \\\n  --bucket csm-backups \\\n  --access-key $ACCESS_KEY \\\n  --secret-key $SECRET_KEY\n\n# Back up all sessions\ncsm backup create\n\n# List backups\ncsm backup list\n\n# Restore a specific session\ncsm backup restore --node server-01 --session <session-id> --project /home/user/project\n\n# Restore the latest backup\ncsm backup restore --node server-01 --session <session-id>\n```\n\nIn 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).\n\n| Flag | Default | Description |\n|---|---|---|\n`--config` |\n`~/.csm/config.yaml` |\nConfig file path |\n`--verbose` / `-v` |\n`false` |\nVerbose output |\n\n| Flag | Default | Description |\n|---|---|---|\n`--server` |\n`false` |\nRun in server (leader) mode |\n`--server-addr` |\nLeader address for agent mode (host:port) | |\n`--auth-token` |\nCluster auth token (agent mode) | |\n`--bind` |\n`0.0.0.0:9827` |\nHTTP listen address (server mode only) |\n`--name` |\nhostname | Node name |\n`--data-dir` |\n`~/.claude` |\nClaude Code data directory |\n\n| Subcommand | Description |\n|---|---|\n`leave` |\nLeave the cluster (`--force` for forced leave) |\n`list` |\nList cluster nodes (`--format table|json` ) |\n\n| Subcommand | Description |\n|---|---|\n`list` |\nList sessions (`--node` for remote query, `--format table|json` ) |\n`pull` |\nPull a session (`--from` source node, `--project` path mapping, `--all` batch) |\n`push` |\nPush a session (`--to` target node, `--project` path mapping, `--all` batch) |\n\n| Subcommand | Description |\n|---|---|\n`config` |\nConfigure S3 storage (`--endpoint` + `--bucket` required) |\n`create` |\nCreate backups (`--session` for single, all by default) |\n`list` |\nList backups (`--node` / `--session` filter, `--format table|json` ) |\n`restore` |\nRestore a backup (`--node` + `--session` required, `--timestamp` optional) |\n\nPrints version, build time, Go version, and OS/Arch.\n\nConfig file at `~/.csm/config.yaml`\n\n, auto-generated on first run:\n\n```\nnode:\n  name: \"server-01\"\n  data_dir: \"~/.claude\"\n\nagent:\n  role: \"server\"\n  bind: \"0.0.0.0:9827\"\n\ncluster:\n  id: \"a1b2c3d4-...\"\n  auth_token: \"e5f6a7b8...\"\n  server_addr: \"\"\n\ns3:\n  endpoint: \"\"\n  bucket: \"\"\n  region: \"auto\"\n  access_key: \"\"\n  secret_key: \"\"\n\nbackup:\n  auto_enabled: true\n  interval: \"0 3 * * *\"\n  retention_days: 30\n```\n\nAll config values can be overridden via `CSM_`\n\n-prefixed environment variables (e.g., `CSM_AGENT_ROLE=server`\n\n). Config file permissions are automatically set to `0600`\n\n.\n\n| Dependency | Purpose |\n|---|---|\n`spf13/cobra` |\nCLI framework |\n`spf13/viper` |\nConfiguration (YAML + env vars) |\n`gorilla/websocket` |\nWebSocket connections (hub-and-spoke) |\n`aws/aws-sdk-go-v2` |\nS3 client (R2/MinIO compatible) |\n`robfig/cron/v3` |\nScheduled backup |\n`schollz/progressbar/v3` |\nTransfer progress bar |\n\n```\n# Build (with version info injection)\nmake build\n\n# Run all tests\nmake test\n\n# Clean build artifacts\nmake clean\ncc-session-migrate/\n├── cmd/                # CLI commands (cobra)\n├── internal/\n│   ├── agent/          # Daemon core (server / agent modes)\n│   ├── cluster/        # Cluster topology management\n│   ├── session/        # Session scanning, packing, path mapping, ID matching\n│   ├── ws/             # WebSocket protocol, hub (server), agent client\n│   ├── api/            # HTTP API types, server, and client\n│   ├── store/          # S3 client wrapper\n│   ├── backup/         # Backup create, restore, list, scheduler\n│   ├── config/         # Configuration (viper)\n│   └── log/            # Logging (slog)\n├── scripts/            # Install script, systemd unit\n└── doc/                # PRD, Feature Specs, Plan, Tasks\n```\n\n**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\n\n| Platform | Architecture |\n|---|---|\n| Linux | amd64, arm64 |\n| macOS | amd64, arm64 |\n| Windows | amd64, arm64 |\n\nIf you find `csm`\n\nuseful, consider buying me a coffee!\n\n**WeChat Pay / Alipay**:\n\nMIT", "url": "https://wpnews.pro/news/show-hn-cc-session-migrate-cross-node-migration-for-claude-code-sessions", "canonical_source": "https://github.com/bigwhite/cc-session-migrate", "published_at": "2026-07-24 12:13:20+00:00", "updated_at": "2026-07-24 12:22:12.914987+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["cc-session-migrate", "Claude Code", "bigwhite", "S3"], "alternates": {"html": "https://wpnews.pro/news/show-hn-cc-session-migrate-cross-node-migration-for-claude-code-sessions", "markdown": "https://wpnews.pro/news/show-hn-cc-session-migrate-cross-node-migration-for-claude-code-sessions.md", "text": "https://wpnews.pro/news/show-hn-cc-session-migrate-cross-node-migration-for-claude-code-sessions.txt", "jsonld": "https://wpnews.pro/news/show-hn-cc-session-migrate-cross-node-migration-for-claude-code-sessions.jsonld"}}