sshmng

Gestor de sesiones SSH basado en MCP para equipos de backend de Linux

Documentación

English | 简体中文

sshmng

sshmng es un gestor SSH unificado que cubre todas las formas de conexión — directa, saltos transparentes ssh -J, bastiones interactivos, proxies de transporte — en un único binario sin dependencias que admite auto-actualización. Funciona como servidor MCP para agentes de IA (Claude Code / Hermes / etc.) y como CLI sshmng ssh para humanos, ambos respaldados por la misma configuración. Cuando algo falla, el Agente lee el rastro del fallo, corrige la configuración y reintenta — auto-reparación en bucle cerrado, sin intervención humana.

Características

  • Bastiones interactivos que realmente funcionan: la mayoría de las herramientas SSH se rinden ante bastiones basados en menús. El árbol de decisión LoginFlow de sshmng (enviar + esperar, glob o regex re:) maneja el menú para iniciar sesión en el objetivo — y cuando el texto del menú cambia, el rastro del fallo vuelve al Agente para que pueda corregir el patrón y reintentar
  • Bucle de configuración auto-reparable: el Agente lee error / login_trace, llama a update_* para corregir el patrón LoginFlow dañado, reintenta login — cierra el bucle de diagnóstico sin supervisión humana
  • Asistente de configuración con un solo comando: sshmng install crea el directorio de configuración + plantilla, detecta automáticamente los Agentes de IA instalados (Claude Code / Hermes / OpenCode) y se inyecta en sus configuraciones con copias de seguridad con marca de tiempo; sshmng doctor verifica que todo esté conectado
  • Una configuración, dos interfaces: servidor MCP para agentes de IA (Claude Code / Hermes / OpenCode / Claude Desktop / Cursor), CLI sshmng ssh para humanos. Mismo config.json, mismos patrones directo / Patrón A (ssh -J) / Patrón B (bastión) — configura un servidor una vez, úsalo desde cualquier lado
  • Gestión explícita de sesiones: trío login → run_in_session → close_session; los comandos consecutivos comparten cwd / env / trabajos en segundo plano, a diferencia de ssh host cmd de un solo uso
  • Transferencia de archivos sftp: upload / download archivos individuales a través de un canal sftp dedicado, separado del canal de comandos PTY; degradación elegante cuando no está disponible. upload_dir / download_dir transfieren árboles de directorios recursivamente, concurrente (predeterminado 4), política de conflictos sobrescribir / omitir / renombrar. relay_transfer transmite un archivo de una sesión a N otras vía sshmng (sin disco local, fanout 1:N, fuente leída una vez)
  • Diagnóstico de comandos: run_in_session tiempo de espera auto Ctrl-C + drenaje, devuelve timed_out / ctrl_c_sent; get_trace recupera el historial de comandos (incluyendo raw_output, ctrl_c_sent)
  • Clave de host TOFU: la primera conexión registra la clave pública en known_hosts; los cambios se rechazan ("host key changed, possible MITM")
  • CRUD de configuración: familias de herramientas list_* / get_* / update_* gestionan SSHServer / Jumphost / Proxy, con semántica RFC 7396 JSON Merge Patch

Instalación y compilación

sshmng es un único binario sin dependencias de ejecución. Elige una opción:

# Option 0: one-click install — downloads release, places on PATH
#   macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/jim58246/sshmng/main/install.sh | bash
#   Windows (PowerShell):
irm https://raw.githubusercontent.com/jim58246/sshmng/main/install.ps1 | iex

# Option 1: download release binary (recommended, no Go required)
#   From https://github.com/jim58246/sshmng/releases, pick the binary for your OS/Arch
chmod +x sshmng

# Option 2: go install (requires Go 1.25+)
go install github.com/jim58246/sshmng/cmd/sshmng@latest

# Option 3: clone and build locally
git clone https://github.com/jim58246/sshmng.git
cd sshmng && go build -o sshmng ./cmd/sshmng

O deja que tu Agente de IA lo instale por ti: copia el prompt en docs/agent-install-prompt.md y pégalo en Claude Code / Cursor / Hermes / OpenCode — el Agente descargará el binario, lo colocará en PATH y ejecutará sshmng install por ti.

macOS: los binarios descargados desde el navegador llevan un atributo de cuarentena de Gatekeeper — ejecuta xattr -d com.apple.quarantine sshmng antes del primer uso. Los binarios go install / go build no lo necesitan (compilación local). Los binarios auto-actualizados tampoco lo necesitan (ver docs/auto-update.md).

Después de obtener el binario, ejecuta sshmng install para crear ~/.sshmng/ e inyectarlo en los Agentes de IA instalados (Claude Code / Hermes / OpenCode, etc.). Ver Quick Start.

Recomendado: antes de ejecutar install, mueve el binario a una ubicación estable en tu PATH (p. ej. mv sshmng /usr/local/bin/, o confía en ~/go/bin/ si usaste go install). sshmng install registra la ruta absoluta del binario en las configuraciones del Agente, y sshmng doctor verifica que coincida con el ejecutable en ejecución — elegir una ubicación estable de antemano evita re-ejecutar la instalación después de un movimiento posterior.

Compilar desde el código fuente

# Plain build (version.Version is "dev", self-update is disabled)
go build -o sshmng ./cmd/sshmng

# Inject version via ldflags (self-update needs a real version number)
go build -ldflags="-X github.com/jim58246/sshmng/internal/version.Version=v1.2.3" -o sshmng ./cmd/sshmng

Sin ldflags, version.Version por defecto es "dev", en cuyo caso tanto sshmng update como la gorutina de auto-actualización al inicio de mcp se omiten.

Ejecuta:

./sshmng                                  # Print help
./sshmng mcp                              # Start MCP server (what Agent configs use)
./sshmng install                          # First-time setup wizard
./sshmng doctor                           # Verify setup
./sshmng version                          # Print version / commit / date
./sshmng version --check                  # Check latest version against source
./sshmng update                           # Self-update to latest release
./sshmng mcp --config /path/to/config.json  # MCP server with custom config
SSHMNG_HOME=/custom/dir ./sshmng mcp         # MCP server with custom home
./sshmng server list [keywords...]        # List SSH servers (AND match on name/addr/tags)
./sshmng server get <name>                # Show SSH server details (full auth)
./sshmng jumphost list|get ...            # Same for jumphosts
./sshmng proxy list|get ...               # Same for proxies
./sshmng ssh <name> [command]             # Interactive login; <name> also resolves to a jumphost (bastion). Non-interactive command needs a shell — bastions (ssh_j=false) and raw devices (raw=true) reject it
./sshmng file upload <name> <local> <remote>   # File transfer via sftp (also: download, upload-dir, download-dir, relay)
./sshmng file relay <src-name> <src-path> <dst-path> --to <dst1,dst2>  # 1:N fanout to multiple servers

Inicio rápido

# 1. Build
go build -o sshmng ./cmd/sshmng

# 2. First-time install (creates ~/.sshmng/ + injects into installed AI Agents)
./sshmng install

# 3. Verify config
./sshmng doctor

# 4. Restart your Agent, have it call sshmng:
#    "list_ssh_servers"          → should return an empty array
#    "add an SSH server named prod-web-01 at 10.0.0.1:22 with password ..."
#    "login to prod-web-01 and run df -h"

No interactivo:

./sshmng install --yes --agents claude-code,hermes

Para configuración manual de respaldo y pasos de integración por Agente, ver docs/agents.md.

Resumen de herramientas MCP

21 herramientas en total:

CategoríaHerramientaDescripción
Consulta de configuraciónlist_ssh_servers / list_jumphosts / list_proxiesCoincidencia AND multi-palabra clave en nombre/dirección/etiquetas (separadas por espacios, sin distinción de mayúsculas, autenticación redactada)
Consulta de configuraciónget_ssh_server / get_jumphost / get_proxyRegistro único por nombre (autenticación completa)
Actualización de configuraciónupdate_ssh_server / update_jumphost / update_proxyRFC 7396 JSON Merge Patch; null elimina, objeto fusiona/crea
Sesiónlogin(name) → {sid, sftp_available, mode, tags}Dial + LoginFlow + inyección RC + configuración del canal sftp. mode: shell = shell unix (usa run_in_session); raw = sin shell unix, p. ej. switch de red (usa send_in_session/read_in_session). tags reflejan las etiquetas configuradas del servidor (pistas humano→IA)
Sesiónrun_in_session(sid, cmd, timeout_ms?, max_output_bytes?)Ejecuta comando, devuelve output/exit_code/timed_out/truncated/total_bytes. Rechazado en sesiones raw
Sesiónsend_in_session(sid, input)Primitiva de terminal: escribe en el PTY. El servidor interpreta escapes estilo C (\r=Enter, \n, \t, \e=ESC, \uXXXX=Ctrl-C etc., \\=barra invertida literal), el resto verbatim. Solo sesiones inactivas; funciona en todas las sesiones
Sesiónread_in_session(sid, wait_ms?, max_bytes?)Primitiva de terminal: lee la nueva salida del PTY desde la última lectura (absorción silenciosa, la salida no leída permanece en cola). Devuelve output/more/idle_ms
Sesiónclose_session(sid)Forzar cierre, rastro conservado durante 10 minutos
Sesiónstat()Lista todos los resúmenes de sesiones activas (incluyendo sftp_available, mode, tags)
Diagnósticoget_trace(sid, last_n?, trunc_output?)Recupera el historial de comandos (incluyendo ctrl_c_sent, salida raw)
Transferencia de archivosupload(sid, src, dst, timeout_ms?)Local → remoto, vía sftp
Transferencia de archivosdownload(sid, src, dst, timeout_ms?)Remoto → local, vía sftp
Transferencia de archivosupload_dir(sid, src, dst, conflict?, concurrency?, timeout_ms?)Árbol de directorios local → remoto, sftp recursivo, concurrente predeterminado 4, política de conflictos sobrescribir/omitir/renombrar
Transferencia de archivosdownload_dir(sid, src, dst, conflict?, concurrency?, timeout_ms?)Árbol de directorios remoto → local, sftp recursivo, concurrente predeterminado 4, política de conflictos sobrescribir/omitir/renombrar
Transferencia de archivosrelay_transfer(src_sid, src_path, dst_sids[], dst_path, timeout_ms?)Transmite un archivo remoto de una sesión a N otras vía sshmng (sin disco local, fanout 1:N, fuente leída una vez); requiere sftp en la fuente + todos los destinos; fallos parciales devuelven ok:false (verifica el campo ok, no IsError)

Los dispositivos raw (switches etc., raw: true) no tienen shell unix: el inicio de sesión omite la detección de shell / inyección RC, y run_in_session se rechaza. Manéjalos con las primitivas de terminal send_in_session + read_in_session: envía un comando (añade \r — el servidor interpreta escapes estilo C, así que Enter funciona ya sea que el cliente transmita un CR real o los dos caracteres \r), lee la salida, juzga la finalización por el contenido + idle_ms, maneja los prompts de paginador (---- More ----) según la convención del dispositivo — el servidor no incluye recetas de proveedor. Las mismas primitivas funcionan en sesiones unix para programas persistentes (tail -f, top, vim). Los clientes MCP serializan las llamadas a herramientas, así que las primitivas solo son utilizables mientras la sesión está inactiva (nunca durante un run_in_session en ejecución).

Notas de seguridad

  • Almacenamiento en texto plano: v1 almacena contraseña / frase de contraseña en texto plano en config.json, documentado explícitamente; si es inaceptable, cifra todo config.json con age / gpg tú mismo, descifra antes de usar
  • Clave de host TOFU: habilitada por defecto; la primera conexión registra la clave pública en ~/.sshmng/known_hosts, los cambios se rechazan ("host key changed, possible MITM"). Se puede deshabilitar por entidad vía host_key_verify: false (omite completamente la lectura/escritura de known_hosts, pierde la protección MITM — solo para bastiones de intranet de confianza, etc.); eliminar una clave registrada aún requiere editar manualmente ~/.sshmng/known_hosts, sin soporte de herramientas
  • El rastro contiene datos sensibles: Send (etapa LoginFlow), Output (flujo raw PTY) pueden contener contraseñas; el rastro es solo en memoria, retenido durante 10 minutos después de close_session y luego auto-limpiado, nunca persistido en disco
  • stdout nunca debe registrar: JSON-RPC está dedicado a stdout; los registros de operación van al archivo rotativo especificado por config.log_path (10MB / 5 archivos, permisos 0600), o sin registro si no está configurado; los errores de arranque van a stderr
  • Alcance de autenticación (v1): solo se admiten Password + PrivateKey; sin keyboard-interactive / agente SSH / certificado SSH / 2FA (si tu entorno lo requiere, extensión v2 o interacción codificada en LoginFlow)

Auto-actualización

sshmng verifica silenciosamente actualizaciones en una gorutina en segundo plano al inicio de mcp (escribe solo el registro log_path, nunca stdout). Deshabilita vía {"auto_update_enabled": false}. Actualización manual: sshmng update. ¿Limitado por GitHub? Descarga el recurso con tu navegador y ejecuta sshmng update --file <path> (omite la cuota de API; acepta .tar.gz, .tar o un directorio extraído). Verificación de versión: sshmng version --check. Fuente personalizada: establece update_url (ver docs/auto-update.md para el diseño de fuente auto-alojada, notas de macOS, modo --file y flujo de lanzamiento).

Pruebas y desarrollo

# Run all tests (with race detector)
go test -race ./...

Para cobertura de pruebas y detalles de desarrollo, ver docs/development.md (solo chino — traducciones bienvenidas).

Documentación

  • Referencia de configuración — referencia completa de campos de config.json, restricciones de forma Patrón A/B, ejemplos
  • Guía de integración de agentes — configuración detallada de Claude Code / Hermes Agent / OpenCode / Claude Desktop, depuración con MCP Inspector, flujo de configuración inicial, flujo de llamadas típico
  • Prompt de instalación de agentes — prompt de copiar y pegar para que tu Agente de IA instale sshmng de principio a fin
  • Auto-actualización — diseño de fuente HTTP auto-alojada, notas de macOS, flujo de lanzamiento
  • Arquitectura y desarrollo — estructura de paquetes, diseños clave, despacho de subcomandos, cobertura de pruebas (solo chino — traducciones bienvenidas)
  • Documento de diseño — especificación de diseño completa (centinela PTY, LoginFlow, máquina de estados de sesión, etc.) (solo chino — traducciones bienvenidas)
  • Plan de implementación — progreso de implementación v1 (solo chino — traducciones bienvenidas)

Estado

Etapa v1: el cliente se ejecuta de forma independiente, stdio de un solo proceso, configuración almacenada localmente. Documento de diseño: docs/ssh-session-manager-design.md (solo chino — traducciones bienvenidas).

Contribuciones

Siéntete libre de abrir issues para errores y solicitudes de funciones.

Licencia

MIT — Copyright (c) 2026 jim58246