Skip to main content

SSH Server Manager

A local-first SSH host and credential manager for humans and AI agents. One CLI (serverctl) and a loopback-only web UI to add, import, test, and connect to your servers — with every password and passphrase stored in your operating system's native credential vault, never in a plaintext file.

test PyPI release license

简体中文说明 · Documentation · Security model · Website

🤖 Using an AI agent? The skill deploys to every agent on your machine in one line — dependencies, links, and health check included. See the agent deployment guide.


Why this exists

Most SSH managers make you choose between convenience and custody:

  • Cloud-synced clients (subscription GUIs) keep your credentials on someone else's infrastructure.
  • Plain ~/.ssh/config keeps you in control but handles no passwords, no vault, and gives AI coding agents an easy way to leak secrets.
  • sshpass-style wrappers put passwords in files, env vars, or shell history.

SSH Server Manager is different by construction:

Property How
Secrets never touch disk in plaintext macOS Keychain / Windows Credential Locker / Linux Secret Service via keyring; unsafe backends are rejected as a hard error
Your ~/.ssh/config is never modified A separate managed config is rendered and included alongside it
The web UI is unreachable from the network Loopback-only bind, one-time launch token, CSRF + Origin checks, strict CSP
Revealing a stored secret requires re-auth WebAuthn passkey (Touch ID / Windows Hello) or an Argon2id master password; grants are single-use and expire in 30 s
AI agents can drive it without seeing secrets Every command has --json; SSH authentication happens through AskPass so secrets never appear in argv, env, logs, or model context
Environment guidance stays with the right hosts Local Agent Skills have explicit many-to-many host bindings; resolution partitions multi-host tasks without installing skills or returning their bodies
Host keys are always verified StrictHostKeyChecking is never weakened, by policy and by code

Quick start

git clone https://github.com/xiayh0107/servers-connect.git
cd servers-connect/ssh-server-manager
./scripts/bootstrap          # Windows: scripts\bootstrap.cmd
./scripts/serverctl doctor   # verify ssh, vault backend, and dependencies

Add a server and connect:

./scripts/serverctl credential add-password work-password   # prompts locally, stores in OS vault
./scripts/serverctl server add web1 --hostname web1.example.com --username deploy --credential work-password
./scripts/serverctl server test web1
./scripts/serverctl connect web1

Or import everything you already have:

./scripts/serverctl server import          # preview only
./scripts/serverctl server import --apply

Prefer a GUI? ./scripts/serverctl ui opens the local web interface in your browser with a one-time tokenized URL.

Features

  • Connection profiles — alias, host, port, user, project/scenario tags, notes, ordered ProxyJump chains (with cycle detection).
  • Host-bound Agent Skills — discover and register local skills, bind one skill to several related nodes or several skills to one host, and resolve exact applies_to partitions before an agent acts. Bindings are routing metadata, not remote authorization. Manage a host's assignments directly from Hosts details; use the Skills page for discovery and registration.
  • Three credential kinds — vault-backed passwords, private keys with optional vault-backed passphrases, and ssh-agent/OpenSSH defaults. Credentials are reusable across servers. Default deletion rejects references; the Web UI can preview references and explicitly detach before deleting. Inspect and validate private keys locally, or test a selected credential independently without changing host bindings or health records.
  • OpenSSH import — parses your ~/.ssh/config (following Include), resolves each literal alias with ssh -G, previews before applying.
  • Managed config rendering — atomic, user-only-permission writes to ~/.ssh/ssh-server-manager.conf; your original config always loads last so unrelated defaults keep working.
  • Connection testing — server test reports latency and a classified error code (authentication-failed, host-key-untrusted, timeout, dns-failed, …) and records history.
  • Remote execution — serverctl exec alias -- cmd args, with --shell for pipelines, --stdin/--stdin-binary for streaming files, --reuse N for ControlMaster connection sharing (macOS/Linux), and --json for machine-readable results.
  • Saved working directories — serverctl path add web1 /srv/app --label app records where you work on a host; serverctl path resolve answers "where does this fleet keep its application" in one read, with no connection, grouping hosts that share a layout.
  • File transfer — serverctl get web1:/srv/app/config.yml . and serverctl put ./config.yml web1:/srv/app/ move files over the same SFTP path and vault credentials, and --recursive copies a whole tree, so no password prompt appears where scp and rsync would ask for one they cannot supply.
  • Local mounting — serverctl mount web1:/srv/app exposes a remote directory to Finder, Explorer, and your editor through sshfs. Needs a FUSE layer that serverctl doctor checks for; see docs/mounting.md.
  • Local web UI — manage servers and credentials, test connections, create/rename/delete tags and bulk-assign searchable hosts, choose system/light/dark/contrast themes and selectable accents, import config, and browse remote directories with saved paths, tabs, server-side name filtering, and explicit download/upload actions. Conflicts require an explicit overwrite. Hosts distinguish connection checks from system diagnosis and show the last successful observation. Reveal a stored secret for 15 seconds after passkey or master-password re-authentication. The session shows its actual expiry. Inspect or shut down a background instance with serverctl ui --status / --stop — no pid bookkeeping.
  • Port forwarding — save a forward per host (serverctl tunnel add db1-local --server db1 --local 15432:localhost:5432) and open it as a detached ssh -N (tunnel open), with status and close. Binds to 127.0.0.1 unless you say otherwise, and status proves a forward is live against the real process.
  • Audit log — a local, append-only, mode-600 record of remote commands and secret reveals (serverctl audit list --json). It rotates itself at 5 MiB, masks credential-shaped arguments, and never stores a secret value.
  • Portable inventory — serverctl export writes a deterministic JSON document of hosts, saved paths, and tunnels for git or another machine; serverctl import previews, then merges. Never secrets or credential ids.
  • Agent integration — a host-bound Agent Skill, plus an optional MCP server (serverctl mcp serve) that is read-only unless started with --allow-remote or --allow-exec --allow-command PATTERN, and never reveals a secret.
  • Mosh and session transcripts — serverctl connect ALIAS --mosh for roaming links, and connect --log for an opt-in, redacted transcript.
  • Local GeoIP — serverctl geo resolve --all --apply fills host locations from a local range file; no web service, and never a lookup when reading the inventory.
  • Diagnostics — serverctl doctor checks ssh availability and version, SFTP availability, mount backend availability, mosh and GeoIP support, vault backend safety, database and config paths, and Python dependencies.

Platform support

macOS Linux Windows
CLI + web UI ✅ ✅ ✅
Credential vault Keychain Secret Service (gnome-keyring / KWallet / KeePassXC) Credential Locker
Secret reveal re-auth Touch ID passkey or master password passkey or master password Windows Hello passkey or master password
Connection reuse (--reuse) ✅ ✅ — (OpenSSH ControlMaster needs Unix sockets; a warning is printed)
Background tunnels (serverctl tunnel) ✅ ✅ ✅
Mosh (connect --mosh) ✅ ✅ — (the Windows client is not offered; use connect)
Session transcripts (connect --log) ✅ ✅ — (needs a POSIX pty; the command says so)

Details and headless-server notes: docs/platforms.md. CI runs the full test suite on all three platforms.

For AI agents

This project ships as an Agent Skill (SKILL.md) so Claude Code, Codex, and other agents can manage servers safely: agents get structured JSON output and connection error classification, while the AskPass architecture keeps secrets out of the model's context by design.

The skill also encodes conversation UX, not just commands: agents answer inventory questions from a single --json call, hand interactive shells to your terminal and proxy follow-up commands through exec (connect refuses to run without a TTY instead of hanging), and clean up a background UI with serverctl ui --stop.

Environment-specific skills can follow only the hosts where they belong. The agent identifies the target first, runs serverctl skill resolve ALIAS [ALIAS ...] --json, then selects relevant ready skills by their normal trigger rules and applies them only to their returned applies_to aliases. Switching hosts discards the previous host-specific context; no cluster name or provider is hard-coded.

serverctl skill discover --json
serverctl skill add ~/.agents/skills/gpu-ops \
  --server gpu-lab-01 --server gpu-lab-02 --json
serverctl skill resolve gpu-lab-01 gpu-lab-02 --json

Discovery is local and read-only. Registration does not install or execute a skill, and resolution returns metadata and paths rather than instruction bodies. See the agent deployment guide.

Deploy the skill with one line:

curl -fsSL https://raw.githubusercontent.com/xiayh0107/servers-connect/main/install.sh | sh

It links the skill into every detected agent (~/.claude/skills, ~/.codex/skills, …), installs dependencies, and runs doctor. Windows uses install.ps1. See docs/ai-agents.md.

Documentation

Doc Contents
docs/installation.md Per-platform install, requirements, bootstrap
docs/quickstart.md First 10 minutes, common workflows
docs/cli.md Complete serverctl reference
docs/web-ui.md Web UI walkthrough and its security gates
docs/security.md Threat model and security invariants
docs/platforms.md Platform-specific behavior, headless Linux
docs/ai-agents.md Using with Claude Code / Codex / MCP
docs/mounting.md Mounting a host locally with sshfs
docs/faq.md Troubleshooting and common questions

License

MIT

Metadata

Release files for ssh-server-manager 0.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ssh-server-manager 0.10.1
File Size Uploaded Provenance
ssh_server_manager-0.10.1.tar.gz 731.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ssh-server-manager 0.10.1
File Interpreter ABI Platform
ssh_server_manager-0.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / ssh_server_manager-0.10.1.tar.gz

Download URL ssh_server_manager-0.10.1.tar.gz
Size 731.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8cf9a9a9d4c03571202966f165755cc6119f2c1cac17a5025072da605a9889eb
BLAKE2b-256 checksum
How to use checksums
20d5c5d4d32ef1a7f1a71297c79477f72d8646c3c9aa26e039241e75b39db823
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / ssh_server_manager-0.10.1-py3-none-any.whl

Download URL ssh_server_manager-0.10.1-py3-none-any.whl
Size 333.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
435a6bb23a953b7ad539dcda6753124e7cf806b279353f09e2516d57565cb902
BLAKE2b-256 checksum
How to use checksums
b131d6976bee845b3dfea858e449dc52ab74841859ff94286d5dee9acc0c1682
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for ssh-server-manager 0.10.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ssh_server_manager-0.10.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page