Documentation

The app

Everything TailMux does from the macOS menu bar app — profiles, tunnels, diagnostics, and browser routing in one window, with the scriptable CLI underneath.

View as Markdown

Overview#

Everything TailMux does is available from the macOS menu bar app — adding tailnets, routing the browser, exposing services on local ports, and diagnosing routes. The CLI remains the scriptable core underneath; the app is the first-class way to drive it.

The app has two surfaces:

  • The menu bar item — live status and quick actions: your profiles and their connection state, your tunnels with start/stop switches, and shortcut buttons.
  • The window — opened with the menu bar's Open button. A sidebar on the left switches between Profiles, Tunnels, Diagnostics, Logs, Settings, and License.

On launch, the app starts the TailMux routing service and (by default) points the active macOS network service at TailMux's PAC, so Safari and other system-proxy-aware browsers reach your tailnet hostnames with zero setup. Both behaviors are toggles under Settings.

Click the TailMux icon to see, at a glance:

  • Profiles — each configured tailnet with its color, icon, and connection state.
  • Tunnels — every service tunnel with its state, live connection count, a one-click copy endpoint button, and an on/off switch.
  • Quick actionsOpen (the window), Diagnose (jump straight to a route check), Copy PAC (the PAC URL for manual proxy setup), Web GUI, and Quit.

The window#

Open brings up the main window. The sidebar sections:

SectionWhat you do there
ProfilesAdd and edit tailnets: suffixes, routes, appearance, login.
TunnelsExpose services on fixed 127.0.0.1 ports — see tunnels.
DiagnosticsCheck which profile owns a hostname and whether it's reachable.
LogsThe live activity log of the routing service.
SettingsRouter listeners, profile defaults, launch behavior, PAC, the CLI.
LicenseActivate, inspect, or move your license.

Profiles#

A profile is one tailnet: an isolated embedded Tailscale node with its own identity and state. In Profiles you can:

  • Add a profile and give it a name, a display name, and — most importantly — its Tailnet Suffixes: the domains that belong to that tailnet (e.g. .home-lab.ts.net). The suffix is the routing key; every suffix belongs to exactly one profile, and TailMux rejects overlaps. That rule is what guarantees a hostname can never silently route through the wrong tailnet.
  • Log the profile in to its tailnet — the standard Tailscale approval page opens; your official Tailscale app account is never touched.
  • Set Subnet Routes (IP) and accept-routes for hosts behind a tailnet subnet router.
  • Pick an icon and color, which follow the profile everywhere — menu bar, tunnel rows, diagnostics.

Profile and suffix changes are routing changes — they apply on router restart (the app prompts you; see below).

Tunnels#

Tunnels gives any raw-TCP client — a database GUI, RDP, SMB, an SFTP tool — a fixed 127.0.0.1:<port> that relays through exactly one profile, kept alive whenever that profile is up. Add one with Add Tunnel, set the target host:port, and copy the assigned endpoint into your client. Tunnels can also forward through an SSH bastion for targets only reachable from inside a remote network. Tunnel edits apply live — no restart. Full guide: tunnels; worked examples: database clients.

Diagnostics#

Diagnostics (also reachable via the menu bar's Diagnose button) answers “why can't I reach this host?” in one shot. Enter a hostname and it reports:

  • which profile owns it — or that no suffix matches;
  • whether it's reachable through that profile — DNS resolution, ping, and an HTTP probe.

If a hostname classifies to the wrong profile, fix the suffixes in Profiles (and restart the router). If it classifies but doesn't respond, the probe results separate DNS problems from network path problems from a service that's simply down. For CLI-based deep dives (direct vs. DERP path, timing samples), see diagnostics.

Logs#

Logs streams the routing service's activity — connections routed, denials (raw IPs, unowned .ts.net names), profile state changes. Useful context to attach when reporting an issue.

Settings#

  • AppLaunch at login, Start TailMux service on app launch, and Configure system PAC automatically (points the current macOS network service at TailMux's proxy.pac while the app runs, and clears it on quit — this is what makes Safari work with zero setup).
  • Command LineInstall command-line tool links the bundled tailmux CLI into /usr/local/bin, so everything on this site's CLI pages works from any terminal.
  • Local listeners — the loopback addresses for the HTTP proxy, SOCKS5 proxy, and PAC server. All listeners are loopback-only by design.
  • Profile defaults — the port bases used to derive per-profile runtime ports, the generated hostname prefix, and the tunnel base port (first auto-assigned local port for service tunnels, default 43300).

Listener and port-base changes are routing changes and apply on router restart.

License#

Activate a license key, see the devices used against your limit, and deactivate this machine to free its slot. Same operations as tailmux license on the CLI.

When a restart is needed#

TailMux deliberately applies routing configuration on router restart, not live: profiles, suffixes, IP routes, listeners, and port bases. Rebuilding the routing stack in place would drop active connections, so instead the app marks the change as saved and shows a restart prompt — one click applies everything. Until then, live routing keeps using the previous configuration.

Two things do apply live: tunnels (create, edit, start, stop) and profile login/logout.

App vs CLI#

Both drive the same core, so nothing is app-only or CLI-only in substance:

TaskAppCLI
Add a tailnetProfiles → addedit config.yaml
Log inlogin buttontailmux profile login <name>
Browser routingautomatic PACset the PAC URL manually
Service on a local portTunnels → Add Tunneltailmux tunnel
Interactive SSH— (use the terminal)tailmux ssh <host>
Route checksDiagnosticstailmux test, tailmux diag path

Use the app for day-to-day management; use the CLI for scripts, dotfiles, CI — and on Linux, where the CLI is the whole product. The commands reference lists every verb.