ssh-tunnel

📁 statechangelabs/ssh-tunnel-manager 📅 6 days ago
4
总安装量
3
周安装量
#54228
全站排名
安装命令
npx skills add https://github.com/statechangelabs/ssh-tunnel-manager --skill ssh-tunnel

Agent 安装分布

opencode 3
antigravity 3
claude-code 3
github-copilot 3
goose 3
codex 3

Skill 文档

SSH Tunnel Manager

You are managing SSH tunnels using the ssh-tunnels CLI tool backed by a declarative JSON config at ~/.ssh-tunnels/config.json.

Step 1: Ensure the tool is installed

Before doing anything, check if the CLI is available:

which ssh-tunnels 2>/dev/null && echo "installed"

If NOT installed, run:

npm install -g @statechange/ssh-tunnel-manager

This single command installs the CLI, creates ~/.ssh-tunnels/ directories, sets up a macOS LaunchAgent for the menu bar app, and starts it automatically.

After installation, verify:

ssh-tunnels status

Step 2: Manage tunnels

Check current tunnels

ssh-tunnels status

Add a new tunnel

ssh-tunnels add \
  --name "Descriptive Name" \
  --host <ssh-host> \
  --user <ssh-user> \
  --localPort <local-port> \
  --remoteHost <remote-host> \
  --remotePort <remote-port> \
  --enabled

Enable / disable / remove

ssh-tunnels enable <tunnel-id>
ssh-tunnels disable <tunnel-id>
ssh-tunnels remove <tunnel-id>

Sync all tunnels to match config

ssh-tunnels sync

Use –json for programmatic output

ssh-tunnels status --json
ssh-tunnels enable <id> --json

Critical knowledge

The –user flag is the #1 source of errors

The SSH username defaults to the local OS user. Most servers require root or a specific service account. If you see “Permission denied (publickey)” in the logs, change the user first.

The –remoteHost is relative to the SSH server

When the service runs directly on the SSH host, use --remoteHost localhost. When the service is on a different machine accessible from the SSH host, use that machine’s internal hostname or IP.

Common ports

Port Service
5432 PostgreSQL
3306 MySQL
6379 Redis
27017 MongoDB
80 HTTP
443 HTTPS
8080 Dev server / admin UI
8089 Splunk / custom
18789 OpenClaw admin
3000 Node.js dev server
9200 Elasticsearch

Tunnel IDs

The ID is auto-generated from the name by slugifying it (lowercase, hyphens). For example, “Production Postgres” becomes production-postgres. Always use the ID (not the name) for enable/disable/remove/logs commands.

After adding an enabled tunnel, verify it started

Always check status or logs after enabling a tunnel. The enable and add --enabled commands will automatically verify and report issues, but with --json output you should check the healthy field:

ssh-tunnels enable my-tunnel --json
# Look for: "healthy": true

If unhealthy, check logs:

ssh-tunnels logs my-tunnel

Menu bar app

The Electron menu bar app provides a GUI for the same functionality:

  • Tray icon: green (all OK), yellow (partially running), red (failures)
  • Click to see tunnel list with toggle switches
  • “Add Tunnel…” opens a form
  • “Sync Now” forces immediate reconciliation
  • Auto-syncs every 30 seconds for crash recovery

The app reads/writes the same ~/.ssh-tunnels/config.json as the CLI. Changes from either the CLI or the app are reflected in both.

The menu bar app is automatically set up as a macOS LaunchAgent during installation. To manually start it:

cd $(npm root -g)/@statechange/ssh-tunnel-manager && npx electron dist/app.mjs