Skip to content

v3.8.0 — Server groups from your config, Windows ssh_sync, and a crash fix

Latest

Choose a tag to compare

@bvisible bvisible released this 14 Aug 14:47

Highlights

👥 Optional group field per server (#56 — contributed by @ice616, requested in #55)

Tag a server with group = "production" and it is in that group: ssh_execute_group and ssh_group_manage list resolve members straight from your .env/TOML, so there is no .server-groups.json to maintain and the grouping travels with the config when you export it to another tool.

SSH_SERVER_WEB1_GROUP=production
SSH_SERVER_WEB2_GROUP=production

Membership is the union of both sources — the list stored by ssh_group_manage (which keeps carrying strategy, delay and stop-on-error) plus every server tagged with that name — so groups you already store keep working untouched. Group names are case-insensitive, and config-derived members are resolved at read time, never written to .server-groups.json.

🪟 ssh_sync works from a Windows host (#59 — contributed by @2836603852)

A local path such as C:\project reached MSYS2 rsync unchanged, which read C: as a remote host and tried to SSH into a machine named c. Drive-letter, UNC and extended-length paths are now converted for the rsync argument only, while Node keeps the native path for its filesystem checks. A path already written as /c/project is passed through untouched rather than mounted twice.

💥 A tunnel on a busy port no longer kills the MCP server

ssh_tunnel_create on an already-bound port hit an unhandled 'error' event — net.Server#listen reports bind failures through that event, never through its callback — and Node rethrew it, taking the whole process down along with every pooled SSH connection and open session, while the awaited promise never settled. It now returns a normal error.

Security

  • @modelcontextprotocol/sdk floor raised to ^1.30.0: the previous range still allowed versions carrying three published advisories, one of them high (cross-client data leak through shared server/transport reuse, DNS rebinding protection off by default, ReDoS).
  • The uuid dependency is gone in favour of Node's built-in crypto.randomUUID(). npm audit --omit=dev is clean.

Also in this release

  • JSDoc type-checking in CI (npm run typecheck) — TypeScript runs as a static checker over the plain JavaScript. No build step, no dist/, nothing changes for users; it found two of the bugs above on the day it landed.
  • The MCP server reported its version as 1.2.0 to clients — now derived from package.json.
  • ssh_sync and ssh_known_hosts compared the port number against a string, so the default-port guard never applied.
  • The dynamic all group ignored TOML-defined servers, and vanished entirely once .server-groups.json existed.

Full details in the changelog.