Peer-to-peer file synchronization across Mac Studio, MacBook, and Proxmox โ hub-and-spoke topology with Proxmox as the always-on relay. Installed March 27, 2026.
Syncthing provides real-time, encrypted, peer-to-peer file synchronization without relying on cloud services. It replaces iCloud Drive sync for app configuration files (Typinator, BetterTouchTool, etc.) which proved unreliable โ iCloud aggressively evicts files, struggles with frequently-updated small configs, and silently creates conflict copies instead of merging.
Topology: Hub-and-spoke
| Node | Role | IP | Syncthing Port | Web UI |
|---|---|---|---|---|
| Proxmox (pve) | Hub โ always-on relay | 192.168.8.221 | 22000 | http://192.168.8.221:8384 |
| Mac Studio | Spoke | 192.168.8.180 | 22000 | http://127.0.0.1:8384 |
| MacBook | Spoke | 192.168.8.160 | 22000 | http://127.0.0.1:8384 |
Both Macs sync exclusively to Proxmox. They do not connect to each other directly. This means changes sync even when one Mac is asleep or powered off โ Proxmox holds the canonical copy and relays changes when the other Mac comes online.
Data flow:
Mac Studio โโ Proxmox (always-on hub) โโ MacBook
โ
/nvmepool/sync/SyncConfigs
(canonical copy on ZFS)
Device IDs:
| Device | ID | Addresses |
|---|---|---|
| Proxmox (pve) | FXMOTJR-XYM6RAO-NIY7KE6-4RPX2M4-NCMYYSG-KZX577Y-6QYSLHH-WL3HVAD |
tcp://192.168.8.221:22000 |
| Mac Studio | UXJMRP2-N2ZX2B7-KWI6OO2-IT7W5LC-GESRIJC-JV2DGTD-FEND4MO-F46LPAS |
tcp://192.168.8.180:22000 |
| MacBook | VLIWDBL-5VD3VSC-XQTOXYS-EGU3NSB-BCHQOML-ACRYBI3-VFT2SPR-WDNBEAF |
tcp://192.168.8.160:22000 |
All devices have autoAcceptFolders: true to simplify adding new shared folders.
| Folder ID | Label | Purpose | Shared With |
|---|---|---|---|
app-configs |
App Configs | Typinator, BetterTouchTool, and other app configuration sync | All three devices |
claude-config |
Claude Config | Claude Code settings, CLAUDE.md, MCP config (~/.claude/) |
Mac Studio โ MacBook |
claude-ed |
Claude ED | All of ~/Sync/ED/ โ context bundle, TASKS.md, SECRETS.md, skills, memory, homelab docs, scripts |
Mac Studio โ MacBook |
mcp-servers |
MCP Servers | Custom MCP server source code (~/.mcp-servers/), excludes .venv/ |
Mac Studio โ MacBook |
farm-data-sync |
Farm Data | Emlid exports, voice memos, farm scripts (~/Sync/farm/) |
Mac Studio โ MacBook |
Folder paths per device:
| Device | app-configs | claude-config | claude-ed | mcp-servers |
|---|---|---|---|---|
| Proxmox | /nvmepool/sync/SyncConfigs |
โ | โ | โ |
| Mac Studio | ~/Sync/SyncConfigs |
~/.claude/ |
~/Sync/ED/ |
~/.mcp-servers/ |
| MacBook | ~/Sync/SyncConfigs |
~/.claude/ |
~/Sync/ED/ |
~/.mcp-servers/ |
app-configs syncs through all three devices via Proxmox hub. The Claude folders sync directly between the two Macs (bidirectional, no Proxmox relay) โ Mac Studio is the source of truth.
All folders use Send & Receive mode.
.stignore for mcp-servers:
.venv
__pycache__
node_modules
.DS_Store
*.pyc
Venvs are excluded because they contain platform-specific compiled binaries. A launchd agent on the MacBook (com.bee.rebuild-mcp-venvs) watches ~/.mcp-servers/ and automatically rebuilds venvs when new code arrives via Syncthing.
History: The original setup (2026-05-12) used three separate subfolder syncs (claude-memory, claude-skills, claude-memory) under ~/Sync/ED/. This was replaced on 2026-05-19 with a single parent claude-ed sync covering all of ~/Sync/ED/ to ensure critical files like .claude-context.md, TASKS.md, and SECRETS.md also sync. The mcp-servers folder was added at the same time.
.stignore for claude-ed (~/Sync/ED/.stignore, auto-managed) โ ~/Sync/ED/ lives inside several huge dirs that would otherwise dominate the sync footprint. The ignore patterns:
**/.venv
**/.venv-*
**/.venv_*
**/__pycache__
**/*.pyc
**/node_modules
**/.DS_Store
homelab/paperless-ngx # entire app dir, ~126 GB
homelab/antigravity # research data, ~12 GB
life_archive/data # LanceDB + everything under it, ~345 GB
life_archive/embeddings # ~62 GB
life_archive/EmailAttachments # ~3.2 GB
beedifferent/plant_database # ~40 GB
beedifferent/farm # ~2.5 GB
Without these exclusions the folder is ~603 GB; with them it’s ~50 GB of context files, skills, scripts, memory, dictation, and Bee Hub source. Studio Syncthing rescans automatically when .stignore changes; MacBook follows on reconnect. The exclusions were expanded from a smaller surgical list on 2026-05-25 after the folder kept failing to converge.
Proxmox (Debian):
| Setting | Value |
|---|---|
| Version | 1.29.5 |
| Install method | apt install syncthing |
| Service | syncthing@root.service (systemd) |
| Config location | /root/.local/state/syncthing/config.xml |
| API key | RzHyGwQhmkvb9A4burcfWGHThGcoThqM |
| Web UI | http://0.0.0.0:8384 (LAN-accessible) |
Start/stop/restart:
systemctl start syncthing@root
systemctl stop syncthing@root
systemctl restart syncthing@root
systemctl status syncthing@root
Mac Studio (macOS):
| Setting | Value |
|---|---|
| Version | 2.0.15 |
| Install method | brew install syncthing |
| Service | Homebrew launchd (homebrew.mxcl.syncthing) |
| Config location | ~/Library/Application Support/Syncthing/config.xml |
| API key | CCuJcwA9wTsfDecNXtymtZwfpQvYWAU7 |
| Web UI | http://127.0.0.1:8384 (localhost only) |
Start/stop/restart:
brew services start syncthing
brew services stop syncthing
brew services restart syncthing
brew services list | grep syncthing
MacBook (macOS):
| Setting | Value |
|---|---|
| Install method | brew install syncthing |
| Service | Homebrew launchd (homebrew.mxcl.syncthing) |
| Web UI | http://127.0.0.1:8384 (localhost only) |
Same brew services commands as Mac Studio.
Syncthing uses three ports. All were opened on Proxmox via UFW:
| Port | Protocol | Purpose | UFW Rule |
|---|---|---|---|
| 8384 | TCP | Web UI | ufw allow 8384/tcp comment 'Syncthing Web UI' |
| 22000 | TCP | Sync protocol (file transfer) | ufw allow 22000/tcp comment 'Syncthing sync' |
| 21027 | UDP | Local discovery (LAN device detection) | ufw allow 21027/udp comment 'Syncthing discovery' |
On the Macs, no firewall changes are needed โ macOS will prompt on first run and Syncthing only listens on localhost for the web UI.
Global discovery and relaying are enabled by default but not needed on the LAN. All devices are configured with explicit tcp://IP:22000 addresses for direct LAN connections. Global discovery and relaying serve as fallback if a device connects from outside the home network.
The primary use case is syncing app configs between both Macs, replacing unreliable iCloud sync.
Typinator:
- Quit Typinator on both Macs
- Open Typinator Preferences โ Advanced โ Data Folder
- Point it at
~/Sync/SyncConfigs/Typinator/ - Do the same on the other Mac
- Relaunch โ configs now sync via Syncthing
BetterTouchTool:
- Open BTT Preferences โ Sync
- Set the sync folder to
~/Sync/SyncConfigs/BTT/ - Repeat on the other Mac
Adding new apps:
For apps with a built-in “data folder” or “sync folder” setting, point it at a subfolder inside ~/Sync/SyncConfigs/. For apps without a custom path setting, use a symbolic link:
# Quit the app first, then:
mv ~/Library/Application\ Support/AppName ~/Sync/SyncConfigs/AppName
ln -s ~/Sync/SyncConfigs/AppName ~/Library/Application\ Support/AppName
Note: Sandboxed App Store apps may not follow symlinks. Check that the app works after symlinking before relying on it.
Added 2026-05-12, overhauled 2026-05-19. Syncthing keeps the full Claude environment in sync between both Macs: Claude Code config, the entire ~/Sync/ED/ working directory (context bundle, tasks, secrets, skills, memory, docs), and MCP server source code. See the dedicated Claude Multi-Machine Setup page for the complete architecture.
Why not route through Proxmox? These folders contain machine-specific paths and configs that only make sense on macOS. Proxmox has no use for them, so the two Macs sync directly.
What syncs automatically vs. what needs manual steps:
| Component | Sync Method | Automatic? |
|---|---|---|
~/.claude/ (settings, plugins) |
Syncthing claude-config |
Yes |
~/Sync/ED/ (context, tasks, skills, memory, docs) |
Syncthing claude-ed |
Yes |
~/.mcp-servers/ (MCP source code) |
Syncthing mcp-servers |
Yes |
| MCP Python venvs | launchd agent com.bee.rebuild-mcp-venvs |
Yes (auto-rebuild on change) |
claude_desktop_config.json |
Symlinked into ~/Sync/ED/config/ |
Yes |
| Cowork skills snapshot | sync-cowork-snapshot.sh (includes MacBook push) |
Manual (run after skill edits) |
.stignore for claude-config
The ~/.claude/ directory contains a mix of persistent config and ephemeral/large session data. The .stignore file excludes 19 patterns to keep sync fast and avoid conflicts:
sessions
session-env
todos
statsig
telemetry
debug
downloads
backups
file-history
cache
ide
.config.json
policy-limits.json
stats-cache.json
mcp-needs-auth-cache.json
history.jsonl
*.bak
.DS_Store
plugins/data
The claude-skills and claude-memory folders sync without any .stignore โ their entire contents are relevant on both machines.
Syncthing launchd agent
A dedicated launchd agent runs Syncthing on the Mac Studio (separate from the Homebrew-managed service used for app-configs):
| Setting | Value |
|---|---|
| Plist | ~/Library/LaunchAgents/com.beedifferent.syncthing.plist |
| Program | /Applications/Syncthing.app/Contents/MacOS/Syncthing |
| KeepAlive | Yes |
| RunAtLoad | Yes |
# Check status
launchctl list | grep beedifferent
# Restart
launchctl kickstart -k gui/$(id -u)/com.beedifferent.syncthing
Syncthing is included in the Proxmox health monitoring system. The system-health-check.sh script (runs every 15 minutes, pushes to Gotify) monitors:
- ZFS pool health for
nvmepool(where SyncConfigs lives) - Disk space on all pools
- Proxmox service availability
The Syncthing web UIs on each device also show connection status, sync progress, and any file conflicts.
Gotify alert configuration:
| Setting | Value |
|---|---|
| Gotify URL | http://192.168.8.100:8070 |
| App name | System Alerts |
| Token | ARCkVc0wf001L.e |
Device shows “Disconnected”:
- Check if Syncthing is running on the remote device (
brew services list | grep syncthingorsystemctl status syncthing@root) - Verify the device address is set to
tcp://IP:22000(not justdynamic) - Check UFW on Proxmox:
ufw status | grep -E '22000|21027' - Restart Syncthing:
brew services restart syncthingorsystemctl restart syncthing@root
Files not syncing:
- Check the Syncthing web UI for errors or conflicts
- Verify the folder path exists on both devices
- Check folder type is “Send & Receive” on all devices
- Look for
.stignorefiles that might be filtering content
Conflict files:
Syncthing creates .sync-conflict-YYYYMMDD-HHMMSS files when the same file is modified on multiple devices simultaneously. Resolve by keeping the correct version and deleting the conflict copy.
Reset a device’s Syncthing config:
# Mac (will regenerate on next start)
brew services stop syncthing
rm -rf ~/Library/Application\ Support/Syncthing/
brew services start syncthing
# Proxmox
systemctl stop syncthing@root
rm -rf /root/.local/state/syncthing/
systemctl start syncthing@root
After resetting, you’ll need to re-add devices and shared folders.
Problem: Typinator and BetterTouchTool configuration files were not syncing reliably between Mac Studio and MacBook despite using their built-in iCloud sync. iCloud Drive was identified as the root cause โ it aggressively evicts files to free local storage, handles frequently-updated small files poorly, and creates silent conflict copies.
Solution: Syncthing was deployed with Proxmox as the always-on hub. This provides: real-time LAN sync without cloud dependency, no file eviction, proper conflict detection with visible conflict files, and ZFS-backed storage on the hub with automatic snapshots every 15 minutes.
Why not direct Mac-to-Mac sync: Both Macs would need to be powered on simultaneously for sync to occur. With Proxmox as the hub, one Mac can be off โ changes queue on Proxmox and sync when the other Mac comes online.
Installed: March 27, 2026.