harper-ssh. SSH y nmap desde Claude Code sin salir del chat

Índice
harper-ssh. SSH y nmap desde Claude Code sin salir del chat

SSH ya lo tienes configurado. Sabes dónde viven tus claves y tienes tus hosts en ~/.ssh/config. harper-ssh conecta ese conocimiento con Claude Code para que puedas pedir “reinicia el servicio en servidor01” y que ocurra — sin abrir un terminal.

Todo el contenido publicado aquí —artículos, scripts, herramientas y configuraciones— tiene fines exclusivamente educativos y refleja mi experiencia personal trabajando sobre infraestructura propia o en entornos de laboratorio controlados.

Las técnicas, metodologías y herramientas descritas están pensadas para su uso en sistemas propios o con autorización explícita de sus propietarios. El conocimiento de técnicas ofensivas forma parte del aprendizaje defensivo; publicar algo no implica que sea adecuado para cualquier contexto.

Si reutilizas o adaptas lo que encuentres aquí, eres responsable de hacerlo dentro del marco legal de tu país, especialmente en materia de protección de datos (RGPD), acceso no autorizado a sistemas (art. 197 bis CP) y privacidad. El autor no asume responsabilidad por usos que contravengan la legislación aplicable.

Este es el tercer artículo de la serie MCP en el homelab.


🔧 Instalación

Sin dependencias Python adicionales. El servidor usa el ssh y el nmap del sistema.

# ssh ya lo tienes. Solo falta nmap para las herramientas de red:
sudo apt install nmap    # Debian/Ubuntu
brew install nmap        # macOS

⚙️ Configuración

El servidor lee directamente de ~/.ssh/config. Si ya tienes tus hosts definidos ahí, no hay nada más que configurar.

Ejemplo ~/.ssh/config

Host servidor01
    HostName 192.168.1.10
    User admin
    IdentityFile ~/.ssh/id_ed25519

Host nas
    HostName 192.168.1.20
    User gonzo
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Host remoto
    HostName 10.0.0.5
    User sistemas
    ProxyJump bastion.ejemplo.com

Añadir a Claude Code

{
  "mcpServers": {
    "harper-ssh": {
      "type": "stdio",
      "command": "python3",
      "args": ["/ruta/a/harper-mcps/mcp_ssh_server.py"],
      "env": {}
    }
  }
}

🛡️ Backup automático

Cuando el servidor detecta que un comando va a sobreescribir un fichero remoto, hace backup antes de ejecutarlo. El backup se crea en la misma ruta con el sufijo .harper.YYYY-MM-DD. Sin configuración — ocurre solo.


🛠️ Herramientas disponibles

ssh_run

Ejecuta un comando en un host remoto y devuelve stdout + stderr + código de retorno.

Muéstrame el uso de disco en servidor01
→ ssh_run("servidor01", "df -h")

ssh_read_file

Lee un fichero remoto y devuelve su contenido.

Lee /etc/nginx/nginx.conf de servidor01
→ ssh_read_file("servidor01", "/etc/nginx/nginx.conf")

ssh_write_file

Escribe contenido en un fichero remoto. Hace backup automático si el fichero existe.

Actualiza /etc/hosts en servidor01 con este contenido: ...
→ ssh_write_file("servidor01", "/etc/hosts", contenido)

ssh_check

Verifica que un host es accesible vía SSH. Útil para diagnosticar problemas de conectividad.

ssh_check_all

Comprueba todos los hosts definidos en ~/.ssh/config de una vez. Devuelve cuáles responden y cuáles no.

ssh_list_hosts

Lista todos los hosts disponibles en ~/.ssh/config con su IP y usuario.

nmap_discover

Descubre hosts activos en un rango de red. Equivale a nmap -sn.

¿Qué hosts hay activos en 192.168.1.0/24?
→ nmap_discover("192.168.1.0/24")

nmap_scan

Escaneo de puertos sobre un host o rango. Configurable: puertos, tipo de escaneo, detección de versiones.

Escanea los puertos abiertos en servidor01
→ nmap_scan("servidor01", ports="1-1024")

nmap_audit

Escaneo de seguridad con scripts NSE. Detecta servicios, versiones y vulnerabilidades conocidas.

Audita servidor01 en busca de vulnerabilidades
→ nmap_audit("servidor01")

💬 Ejemplo de sesión real

Tú: Comprueba qué hosts tengo disponibles y dime cuáles no responden.

Claude: [ssh_check_all()] → servidor01 ✓, nas ✓, remoto ✗ (timeout)

Claude: remoto no responde. ¿Quieres que intente hacer ping
        o que revise si hay alguna regla de firewall bloqueando?

Tú: Escanea la red 192.168.1.0/24 y dime qué servicios hay.

Claude: [nmap_discover("192.168.1.0/24")] → 12 hosts activos
Claude: [nmap_scan("192.168.1.0/24", ports="22,80,443,8080,8443")]
        → resultado del escaneo con puertos abiertos por host

📚 La serie

Repo: github.com/jaimealberto/harper-mcps