agentsclimarketplace

Sshc

Skill fivif/sshc

让本地 AI Agent 在线管理你的远程服务器。Zero-overhead SSH multiplexing CLI for AI agents — manage remote servers like local commands.

Install
npx -y skills add fivif/sshc

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Universal SSH multiplexing CLI for AI agents. Zero-overhead C daemon with ControlMaster connection reuse eliminates repeated authentication latency. Trigger: remote server management, batch ops, SSH connection acceleration, executing commands on remote servers, VPS administration, server health checks, multi-server orchestration. Use whenever the user asks to run commands on a remote server, check server status, manage VPS instances, or perform DevOps tasks.

SKILL.md

15.2 KB, as published. Nobody here has run it

sshc — Agent-Native SSH Multiplexing

Pure C daemon architecture (cross-platform: Unix + Windows). System deps only (python3 + nc + ssh). Single-file distributable. SSH ControlMaster persistent multiplexing eliminates repeated auth delay.

Execution Rules

  1. Ensure daemon is alive before any exec: ./sshc health > /dev/null 2>&1 || ./sshc daemon &
  2. All remote commands go through: ./sshc exec <profile> "<command>"
  3. Independent commands can run in parallel
  4. Config contains secrets — ensure chmod 600 ~/.sshc/profiles.json
  5. Config changes are picked up automatically (hot reload via mtime detection — no daemon restart needed)

Quick Start

# 1. Compile daemon
cc -O2 -o sshc-daemon sshc-daemon.c       # Unix
# x86_64-w64-mingw32-gcc -O2 -o sshc-daemon.exe sshc-daemon.c -lws2_32  # Windows cross-compile

# 2. Ensure executable
chmod +x sshc sshc-daemon sshc-web

# 3. Create config
mkdir -p ~/.sshc
cat > ~/.sshc/profiles.json << 'EOF'
{
  "default": "my-server",
  "servers": {
    "my-server": {
      "host": "1.2.3.4",
      "user": "root",
      "key": "~/.ssh/id_ed25519",
      "port": 22
    }
  }
}
EOF

# 4. Start daemon
./sshc daemon

# 5. Health check
./sshc health

# 6. Execute remote command
./sshc exec my-server "uptime"

# 7. (Optional) Launch web UI for visual management
./sshc web
# Open http://127.0.0.1:17375

Commands

sshc daemon                              # Start daemon
sshc health [profile]                    # Health check (omit for all, "*" = all)
sshc exec <profile> <cmd> [timeout]      # Execute command (default timeout: 30s)
sshc profiles                            # List all servers and status
sshc add <name> <user@host> -i <key> [-p port] [--proxy <cmd>] [--allow <re>] [--deny <re>]  # Add server
sshc remove <name>                       # Remove server
sshc default <name>                      # Set default server
sshc reconnect <profile>                 # Force reconnect (kill + re-establish ControlMaster)
sshc upload <profile> <local> <remote>   # Upload file via SFTP (dirs auto tar-pipe)
sshc download <profile> <remote> <local> # Download file via SFTP (dirs auto tar-pipe)
sshc web [port]                          # Start web UI (default :17375)

Add server examples

# Key auth
./sshc add prod [email protected] -i ~/.ssh/id_rsa

# Key auth with custom port + proxy + command safety
./sshc add prod [email protected] -i ~/.ssh/id_rsa -p 2222 \
  --proxy "nc -X 5 -x 127.0.0.1:1080 %h %p" \
  --allow "^(ls|df|uptime|systemctl|apt|docker).*" \
  --deny ".*rm -rf.*|.*mkfs.*"

# Password auth (server must be added via Web UI or direct JSON edit for password)

Web UI & REST API

./sshc web starts a management dashboard at http://127.0.0.1:17375. Features:

  • Drag-and-drop key upload — drag private key file onto drop zone, auto base64-encodes and stores to ~/.sshc/keys/<profile>/<filename>
  • Proxy modal — per-server proxy config with type dropdown (HTTP / SOCKS5 / SOCKS4 / custom ProxyCommand), accessible via "代理" button in server list
  • Async health checks — table renders instantly, health status streams in via parallel background checks (pulsing gray dot = checking)
  • Live status — click "测试" to re-check individual server, status dot updates in real-time

API Endpoints

# ── List all servers (instant, no health check — alive: null) ──────────
curl http://127.0.0.1:17375/api/profiles
# Response: {"default":"prod","profiles":{"prod":{"host":"1.2.3.4","user":"root","port":22,"alive":null,"has_key":true,"has_password":false,"proxy":"nc -X 5 -x ..."}}}

# ── Add server (key path) ──────────────────────────────────────────────
curl -X POST http://127.0.0.1:17375/api/profiles \
  -H 'Content-Type: application/json' \
  -d '{"name":"prod","host":"1.2.3.4","user":"root","key":"~/.ssh/id_rsa"}'

# ── Add server (key content — base64, from file upload) ─────────────────
curl -X POST http://127.0.0.1:17375/api/profiles \
  -H 'Content-Type: application/json' \
  -d '{"name":"prod","host":"1.2.3.4","user":"root","key_content":"<base64>","key_filename":"id_rsa"}'

# ── Add server (password auth) ─────────────────────────────────────────
curl -X POST http://127.0.0.1:17375/api/profiles \
  -H 'Content-Type: application/json' \
  -d '{"name":"staging","host":"5.6.7.8","user":"admin","password":"mypass","port":2222}'

# ── Add server (with proxy) ────────────────────────────────────────────
curl -X POST http://127.0.0.1:17375/api/profiles \
  -H 'Content-Type: application/json' \
  -d '{"name":"hidden","host":"10.0.0.5","user":"root","key":"~/.ssh/id_rsa","proxy":"nc -X 5 -x 127.0.0.1:1080 %h %p"}'

# ── Update proxy ───────────────────────────────────────────────────────
curl -X PUT http://127.0.0.1:17375/api/profiles/hidden \
  -H 'Content-Type: application/json' \
  -d '{"proxy":"nc -X connect -x proxy.internal:3128 %h %p"}'

# ── Clear proxy ────────────────────────────────────────────────────────
curl -X PUT http://127.0.0.1:17375/api/profiles/hidden \
  -H 'Content-Type: application/json' \
  -d '{"proxy":null}'

# ── Set default server ─────────────────────────────────────────────────
curl -X PUT http://127.0.0.1:17375/api/profiles/prod -d '{"default":true}'

# ── Test connection (blocking — calls daemon health check) ─────────────
curl -X POST http://127.0.0.1:17375/api/test/prod
# Response: {"ok":true,"name":"prod","alive":true}

# ── Delete server ──────────────────────────────────────────────────────
curl -X DELETE http://127.0.0.1:17375/api/profiles/staging

Proxy Types (Web UI modal generates these automatically)

TypeGenerated ProxyCommand
HTTPnc -X connect -x {host}:{port} %h %p
SOCKS5nc -X 5 -x {host}:{port} %h %p
SOCKS4nc -X 4 -x {host}:{port} %h %p
Customuser-provided raw ProxyCommand string

For agents adding servers programmatically, use the proxy field directly with any valid OpenSSH ProxyCommand string.

Configuration

~/.sshc/profiles.json:

{
  "default": "prod",
  "servers": {
    "prod": {
      "host": "10.0.0.1",
      "user": "root",
      "key": "~/.ssh/prod.key",
      "port": 22
    },
    "staging": {
      "host": "10.0.0.2",
      "user": "admin",
      "password": "secret",
      "port": 2222
    },
    "hidden": {
      "host": "10.0.0.5",
      "user": "root",
      "key": "~/.ssh/id_rsa",
      "port": 22,
      "proxy": "nc -X 5 -x 127.0.0.1:1080 %h %p"
    },
    "safe-prod": {
      "host": "10.0.0.1",
      "user": "root",
      "key": "~/.ssh/id_rsa",
      "port": 22,
      "allow": "^(ls|df|uptime|systemctl|apt|docker).*",
      "deny": ".*rm -rf.*|.*mkfs.*|.*dd if=.*"
    }
  }
}
  • default — default server name (used when profile omitted in exec)
  • servers.<name>.host — IP or domain (required)
  • servers.<name>.user — SSH user (default: root)
  • servers.<name>.key — SSH private key path on disk (mutually exclusive with password)
  • servers.<name>.password — plaintext password (mutually exclusive with key)
  • servers.<name>.port — SSH port (default: 22)
  • servers.<name>.proxy — OpenSSH ProxyCommand string (optional, default: none / direct connect)
  • servers.<name>.allow — POSIX regex for allowed commands (optional, default: allow all)
  • servers.<name>.deny — POSIX regex for denied commands (optional, default: deny none)

Command Safety

Per-server command validation via POSIX extended regex (Unix) / glob matching (Windows). Rules are evaluated as: deny takes priority. If deny matches → rejected. If allow is set but doesn't match → rejected.

# Add with command restrictions
./sshc add safe-prod [email protected] -i ~/.ssh/id_rsa \
  --allow "^(ls|df|uptime|systemctl).*" \
  --deny ".*rm -rf.*"

# Update via API
curl -X PUT http://127.0.0.1:17375/api/profiles/safe-prod \
  -H 'Content-Type: application/json' \
  -d '{"allow":"^(ls|df|uptime|systemctl|apt).*"}'

Validation happens in the C daemon before any command reaches SSH — no way to bypass at the CLI or Web UI level.

SFTP File Transfer

File upload/download via OpenSSH sftp reusing the existing ControlMaster connection (no extra auth). Directories are auto-detected and transferred via tar pipe for efficiency.

# CLI upload (single file)
./sshc upload prod ./app.tar.gz /opt/app.tar.gz

# CLI upload (directory → auto tar pipe)
./sshc upload prod ./my-project/ /opt/my-project/

# CLI download
./sshc download prod /var/log/syslog ./syslog
./sshc download prod /opt/data/ ./data-backup/

# Web UI: click "上传" / "下载" buttons in server list

Web UI upload API:

# Upload file (base64 content in JSON)
curl -X POST http://127.0.0.1:17375/api/upload/prod \
  -H 'Content-Type: application/json' \
  -d '{"content":"<base64>","remote_path":"/opt/app.tar.gz","filename":"app.tar.gz"}'
# Response: {"ok":true,"name":"prod","size":12345,"remote":"/opt/app.tar.gz"}

Web UI download API:

# Download file (streaming binary response)
curl -o app.tar.gz 'http://127.0.0.1:17375/api/download/prod?path=/opt/app.tar.gz'

Config Hot Reload

The C daemon automatically detects config file changes via mtime (last-modified timestamp). No daemon restart needed — any changes to ~/.sshc/profiles.json take effect on the next request. This includes adding/removing servers, changing proxies, and updating allow/deny rules.

Architecture

sshc (bash) ──nc──> daemon.sock (Unix) / 127.0.0.1:{port} (Windows TCP)
                           │
                      sshc-daemon (C, fork/thread-per-request)
                           │
                      posix_spawnp/vfork+execvp("ssh") / CreateProcess + pipes
                           │
                      ControlMaster ──> Remote Server
                      (~/.sshc/mux/ssh-<name>, persist 300s)

Web UI (python3) ──socket──> daemon IPC ──> health/exec requests
         │
         └── profiles.json (read/write directly, atomic replace + chmod 600)
  • Daemon overhead ~15ms, end-to-end latency ≈ raw SSH
  • ControlMaster auto-warmup on first health check or exec
  • Master socket persists 300s idle, auto-reconnect on failure
  • Health checks: ensure_master + ssh exec "echo ok" — also serves as connection warmup
  • Unix: AF_UNIX socket at ~/.sshc/daemon.sock, fork() per request, posix_spawnp for master, vfork for exec
  • Windows: TCP localhost (port written to ~/.sshc/daemon.port), CreateThread per request, CreateProcess for all SSH calls
  • Command validation: POSIX regex (Unix) / glob matching (Windows) evaluated in daemon before SSH execution
  • SFTP: sftp -b - with ControlPath reuse for file transfer; tar pipe for directories
  • Config hot reload: stat()-based mtime detection at start of each request handler, no polling loop
  • Key upload: browser FileReader.readAsDataURL() → base64 → ~/.sshc/keys/<profile>/<filename> (chmod 600, basename-sanitized)
  • Proxy: stored as raw ProxyCommand string, injected via -o ProxyCommand="..." into all SSH invocations

Platform Notes

AspectUnix (macOS/Linux)Windows
IPCAF_UNIX socketTCP 127.0.0.1 (auto-assigned port)
Concurrencyfork() per requestCreateThread per request
Process spawnposix_spawnp / vfork+execvpCreateProcess
Socket path~/.sshc/daemon.sock~/.sshc/daemon.port (contains port number)
Compilecc -O2 -o sshc-daemon sshc-daemon.cAdd -lws2_32
Shellbash (native)Git Bash / MSYS2 / WSL

Dependencies

DependencyPurposeRequired
cc (clang/gcc)Compile C daemonYes (one-time)
python3JSON parsing + Web UI serverYes
ncSocket communication (IPC)Yes
sshOpenSSH client with ControlMasterYes
sshpassPassword authentication supportNo (only if using password auth)

Agent Workflow Guide

Adding a new server behind a proxy

# Via CLI
./sshc add hidden [email protected] -i ~/.ssh/id_rsa --proxy "nc -X 5 -x 127.0.0.1:1080 %h %p"

# Via REST API (when daemon+web are running)
curl -X POST http://127.0.0.1:17375/api/profiles \
  -H 'Content-Type: application/json' \
  -d '{"name":"hidden","host":"10.0.0.5","user":"root","key":"~/.ssh/id_rsa","proxy":"nc -X 5 -x 127.0.0.1:1080 %h %p"}'

Running commands on multiple servers in parallel

./sshc exec prod "uptime" &
./sshc exec staging "df -h" &
./sshc exec db "systemctl status postgresql" &
wait

Checking all server status

./sshc health          # all profiles
./sshc health prod     # single profile
./sshc profiles        # table format with status

Uploading and downloading files

# Upload
./sshc upload prod ./app.tar.gz /opt/app.tar.gz
./sshc upload prod ./my-project/ /opt/my-project/   # directory → tar pipe

# Download
./sshc download prod /var/log/syslog ./syslog
./sshc download prod /opt/data/ ./data-backup/

# Via Web UI: click "上传" / "下载" buttons in server list

Restricting commands with allow/deny patterns

# Add server with command safety
./sshc add safe-prod [email protected] -i ~/.ssh/id_rsa \
  --allow "^(ls|df|uptime|systemctl|apt|docker).*" \
  --deny ".*rm -rf.*|.*mkfs.*|.*dd if=.*"

# Update via REST API
curl -X PUT http://127.0.0.1:17375/api/profiles/safe-prod \
  -H 'Content-Type: application/json' \
  -d '{"allow":"^(ls|df|uptime|systemctl|apt|docker).*"}'

# Validation happens in daemon — bypassing impossible

Setting up via Web UI (when human needs visual management)

./sshc web
# Human opens http://127.0.0.1:17375
# - Drag key file onto drop zone
# - Fill host/user/port
# - Click "代理" in server list to configure proxy via modal
# - Click "测试" to verify connectivity

Troubleshooting

# Daemon not responding
./sshc daemon          # restart

# Master connection stale
./sshc reconnect prod  # force re-establish

# Check if daemon is alive
./sshc health > /dev/null 2>&1 && echo "alive" || echo "dead"

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.