A terminal UI and CLI for Syncthing — keeps a single ~/meshd folder in sync across all your machines, like a self-hosted Dropbox. Built on the same Go/Bubbletea stack as tuitube.
- Single folder —
~/meshdauto-created and registered with Syncthing on first run - Live monitoring — event-driven updates via Syncthing long-poll, no polling delay
- Device completion % — shows
↻ 73%per device when syncing, not just Online/Offline - Conflict resolution —
.sync-conflict-*files flagged with!badge; interactive resolve in TUI and CLI - File versioning — browse and restore
.stversionssnapshots from the TUI or CLI - Last seen — offline devices show "last seen 2h ago"
- Activity log — timestamped event feed: connects, syncs, errors
- Connect screen — accept/dismiss pending devices, rename devices inline
- Header spinner —
⠹ Syncing 73% · notes.mdshows exactly what's transferring - MCP server — scriptable headless control for automation and AI agents
- Any file, any size — block-level transfer, both machines always have identical copies
- Syncthing installed and running
Go install (all platforms):
go install github.com/gitcoder89431/meshd/cmd/meshd@latestIf you see a checksum DB error, prefix with
GONOSUMDB=github.com/gitcoder89431/meshd
Download binary — grab from Releases and put in your PATH.
From source:
git clone https://github.com/gitcoder89431/meshd
cd meshd
go install ./cmd/meshdLinux:
systemctl --user enable --now syncthing
meshdmacOS:
brew install syncthing
brew services start syncthing
meshdmeshd reads the Syncthing API key automatically — no manual setup. On first launch it creates ~/meshd and registers it with Syncthing.
Run meshd doctor to verify everything is working.
meshd launch the TUI
meshd id print this machine's Syncthing device ID
meshd status show devices + file sync state
meshd status --json machine-readable JSON output
meshd status --json --watch stream JSON on every state change
meshd devices list all paired devices with IDs
meshd add-device <id> [name] add a device and share ~/meshd
meshd scan trigger immediate rescan of ~/meshd
meshd pause pause syncing
meshd resume resume syncing
meshd errors show file-level sync errors
meshd watch stream sync events to stdout
meshd watch --json stream as JSON lines (for scripts / widgets)
meshd watch --until idle block until folder is fully synced
meshd conflicts list unresolved sync conflicts
meshd conflicts --fix interactively resolve conflicts
meshd versions list all saved file versions
meshd versions <file> list versions of a specific file
meshd versions <file> --restore N restore version N
meshd ignore list show active .stignore patterns
meshd ignore add <pattern> add a pattern to .stignore
meshd ignore preset <name> apply a preset (obsidian, dev, photos, keepass)
meshd doctor check Syncthing connection and folder health
meshd mcp start MCP stdio server (headless/agent control)
--url URL Syncthing API URL (default: http://127.0.0.1:8384)
--key KEY API key override (default: auto-read from Syncthing config)
--version print version
- Run
meshd idon each machine — copy both device IDs - On machine A:
meshd add-device <machine-B-id> <name> - On machine B:
meshd add-device <machine-A-id> <name> - Both machines share
~/meshdautomatically — no manual accept needed
| Key | Action |
|---|---|
j / ↓ |
Navigate down |
k / ↑ |
Navigate up |
enter |
Open selected file/folder in terminal |
r |
Rename device (Connect screen) / restore version (Versions screen) |
d |
Dismiss pending device / delete version |
D |
Delete conflict, keep original (Conflicts screen) |
K |
Keep conflict version, replace original (Conflicts screen) |
p |
Pair by device ID (Connect screen — paste full ID, press enter) |
a |
Accept pending device |
s |
Toggle sidebar |
ctrl+k |
Command palette |
? |
Help |
q / ctrl+c |
Quit |
meshd exposes a Model Context Protocol stdio server for scriptable control from automation tools or AI agents.
Add to your MCP client config (e.g. ~/.claude.json for Claude Code):
"mcpServers": {
"meshd": {
"command": "meshd",
"args": ["mcp"]
}
}| Tool | What it does |
|---|---|
get_status |
Devices + file list with sync state |
list_devices |
All paired devices with status |
get_device_id |
This machine's device ID |
list_files |
Files in ~/meshd with sync indicators |
add_device |
Accept/add a device by ID |
trigger_scan |
Force immediate rescan |
pause_sync |
Pause syncing |
resume_sync |
Resume syncing |
get_errors |
File-level sync errors |
get_activity |
Recent events log |
wait_for_sync |
Block until folder is idle (with timeout) |
list_ignore |
Show active ignore patterns |
add_ignore |
Add a pattern to .stignore |
graph LR
subgraph mini
ST1[Syncthing] <--> M1[meshd]
M1 <--> TUI[TUI / CLI]
M1 <--> MCP[MCP server]
end
subgraph macbook
ST2[Syncthing] <--> M2[meshd]
end
subgraph phone
ST3[Syncthing]
end
ST1 <-->|P2P sync| ST2
ST1 <-->|P2P sync| ST3
MCP -->|stdio| Agent[AI agent / script]
- Bubble Tea v2 — TUI framework
- Lip Gloss v2 — styling and layout
- Syncthing REST API — no extra dependencies, plain HTTP
go run ./cmd/meshd # run
go test ./... # test
meshd doctor # health checkGoReleaser via GitHub Actions on tag push.
Homebrew tap requires a
homebrew-meshdrepo atgithub.com/gitcoder89431/homebrew-meshdand aHOMEBREW_TAP_TOKENsecret. Until then usego installor download from Releases.
git tag v0.1.0 && git push origin v0.1.0