Ganoid solves this by treating each coordination server as a named profile and saving/restoring the full Tailscale state directory per profile. The private node key is part of that state, so when you switch back to a server you've used before, Tailscale picks up where it left off with no login prompt.
It runs as a Windows service (ganoidd) with an embedded web UI and REST API. A system tray app (ganoid) sits in the notification area, shows the current connection status, and lets you switch profiles with one click.
The tricky part was figuring out the state file format. server-state.conf is a JSON file where every value is base64-encoded. The ControlURL is embedded in the profile entries, so before backing up or restoring, Ganoid verifies the state actually belongs to the profile being switched. This prevents corrupting a backup by writing the wrong server's state into it.
Only tested on Windows. Linux/macOS stubs compile but do nothing useful. The platform layer is abstracted so it should be straightforward to implement for other OSes.
This was vibe coded, but I have been running it myself and it does what I need it to do. Putting it out there in case someone else finds it useful. Ideas for improvement or PRs are always welcome.
The name comes from ganoid scales, the hard interlocking scales found on primitive fish like gars and sturgeons. Tailscale has scale in the name, so it felt fitting.
GitHub: https://github.com/yashau/ganoid