ssh-tunnel

Manage SSH tunnels declaratively. Use when the user wants to create, start, stop, enable, disable, or check the status of SSH port-forwarding tunnels. Also use when the user mentions SSH tunnels, port forwarding, bastion hosts, or connecting to remote databases/services through SSH.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ssh-tunnel" with this command: npx skills add statechangelabs/ssh-tunnel-manager/statechangelabs-ssh-tunnel-manager-ssh-tunnel

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

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

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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ssh-tunnel-debug

No summary provided by upstream source.

Repository SourceNeeds Review
General

neo

Browse websites, read web pages, interact with web apps, call website APIs, and automate web tasks. Use Neo when: user asks to check a website, read a web page, post on social media (Twitter/X), interact with any web app, look up information on a specific site, scrape data from websites, automate browser tasks, or when you need to call any website's API. Keywords: website, web page, browse, URL, http, API, twitter, tweet, post, scrape, web app, open site, check site, read page, social media, online service.

Archived SourceRecently Updated
General

image-gen

Generate AI images from text prompts. Triggers on: "生成图片", "画一张", "AI图", "generate image", "配图", "create picture", "draw", "visualize", "generate an image".

Archived SourceRecently Updated
General

explainer

Create explainer videos with narration and AI-generated visuals. Triggers on: "解说视频", "explainer video", "explain this as a video", "tutorial video", "introduce X (video)", "解释一下XX(视频形式)".

Archived SourceRecently Updated