Prototipo · Versión preliminar: todos los servidores del registro oficial, sincronizados cada 30 minutos. Las reseñas y las cuentas llegarán en una etapa posterior.
PopNx MCPServidores MCP para quienes usan IA · explicados con palabras sencillas

SSH — policy-gated remote access

de tufantuncversión 2.23.1i★ –iSe ejecuta en tu computadora
Nombre en el registroio.github.tufantunc/ssh-mcp

Instalar

Resumen

Descripción del creador (original en inglés)

Policy-gated, audited SSH for Linux and Windows hosts: roles, approvals, and an audit log.

Los tres pilares de PopNx MCP

Estos tres nunca se combinan en una sola puntuación: las opiniones, las mediciones y la popularidad son cosas distintas.

Qué puedes hacer con él

Todavía no escribimos un resumen sencillo para este. Abajo están los datos que leímos del registro.

  • Conexión: Se ejecuta en tu computadora
  • Transporte: stdio
  • Categoría: Otros
  • Debes completar: SSH_MCP_PASSWORD, SSH_MCP_PASSPHRASE, SSH_MCP_SUDO_PASSWORD

Instalación

Elige la app de IA que usas y copia la configuración.

Antes de instalar

  • Revisiones básicas: 1 de 1 superadas
  • Se ejecuta en tu computadora con los permisos de tu usuario (archivos, red, apps).
  • Debes completar tú: SSH_MCP_PASSWORD, SSH_MCP_KEY, SSH_MCP_PASSPHRASE, SSH_MCP_SUDO_PASSWORD

Los valores marcados como secretos son llaves de tu cuenta. Nunca los compartas ni los pegues en un chat.

Necesitas

  • npmNode.js instalado (para el comando npx)

¿Qué app usas?

Elige tu app arriba. La recordamos, así que la próxima vez el botón dirá “Instalar en …”.

Abre Claude Desktop → Settings → Developer → Edit Config y pega esto en claude_desktop_config.json

{
  "mcpServers": {
    "ssh": {
      "command": "npx",
      "args": [
        "-y",
        "ssh-mcp"
      ],
      "env": {
        "SSH_MCP_PASSWORD": "your-value",
        "SSH_MCP_KEY": "your-value",
        "SSH_MCP_PASSPHRASE": "your-value",
        "SSH_MCP_SUDO_PASSWORD": "your-value"
      }
    }
  }
}

Ejecuta esto en tu terminal

claude mcp add ssh --env SSH_MCP_PASSWORD=your-value --env SSH_MCP_KEY=your-value --env SSH_MCP_PASSPHRASE=your-value --env SSH_MCP_SUDO_PASSWORD=your-value -- npx -y ssh-mcp

Completa los valores vacíos antes de ejecutarlo.

Abrir en Cursor

O copia la configuración tú

Pégalo en .cursor/mcp.json de tu proyecto, o en ~/.cursor/mcp.json

{
  "mcpServers": {
    "ssh": {
      "command": "npx",
      "args": [
        "-y",
        "ssh-mcp"
      ],
      "env": {
        "SSH_MCP_PASSWORD": "your-value",
        "SSH_MCP_KEY": "your-value",
        "SSH_MCP_PASSPHRASE": "your-value",
        "SSH_MCP_SUDO_PASSWORD": "your-value"
      }
    }
  }
}

Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.

Abrir en VS Code

O copia la configuración tú

Pégalo en .vscode/mcp.json de tu proyecto

{
  "servers": {
    "ssh": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "ssh-mcp"
      ],
      "env": {
        "SSH_MCP_PASSWORD": "your-value",
        "SSH_MCP_KEY": "your-value",
        "SSH_MCP_PASSPHRASE": "your-value",
        "SSH_MCP_SUDO_PASSWORD": "your-value"
      }
    }
  }
}

Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.

Este se ejecuta en tu computadora, y ChatGPT solo puede conectarse a servidores en internet. Elige otra app.

Tu elección se guarda en una cookie en este dispositivo; no necesitas cuenta.

Valores que debes completar

  • SSH_MCP_PASSWORD secreto env
    Password for the configured profile; a per-profile SSH_MCP_ _PASSWORD takes precedence. Credentials are never accepted as CLI arguments.
  • SSH_MCP_KEY env
    Path to the private key file to authenticate with — the path, not the key material. A per-profile SSH_MCP_ _KEY takes precedence.
  • SSH_MCP_PASSPHRASE secreto env
    Passphrase for an encrypted private key.
  • SSH_MCP_SUDO_PASSWORD secreto env
    Password the sudo tool escalates with, when the policy in force allows the privileged class.

Esta configuración se genera a partir de la ficha del creador en el registro. Si el README dice otra cosa, sigue el README.

Qué puede hacer

Se ejecuta en tu computadora; la lista de herramientas aparece en tu app de IA después de instalarlo.

Revisiones básicasi

Revisamos información que cualquiera puede ver; no hemos leído el código. Las revisiones que no aplican no se cuentan. · Revisado el 6 nov 2026

  • ✓ Superada

    El creador coincide con el repo

    El nombre en el registro se verificó con la cuenta de GitHub tufantunc, dueña del repo

  • … Aún sin revisar

    Sigue en mantenimiento

    Todavía no hemos leído este repo en GitHub

  • … Aún sin revisar

    Tiene licencia

    Todavía no hemos leído este repo en GitHub

  • – No aplica

    El endpoint responde

    Este se ejecuta en tu computadora; no hay endpoint en internet

  • – No aplica

    Inicio de sesión con OAuth

    Se ejecuta en tu computadora y usa ajustes locales en su lugar

  • … Aún sin revisar

    Sin instrucciones ocultas en las descripciones de herramientas

    Se ejecuta en tu computadora; solo podemos leer listas de herramientas de endpoints en internet

Comparado con otros en Otrosi

  • Más estrellas que el 0% de los otros 32505 servidores de esta categoría
  • Publicado en el registro más recientemente que el 100% de los otros 32505 servidores de esta categoría
  • Revisiones básicas iguales o mejores que el 100% de los otros 32505 servidores de esta categoría

Comparado con todos los servidores activos de esta categoría en el registro. Las estrellas solo cuentan cuando quien lo publica es dueño del repo.

Preguntas frecuentes

¿Es seguro SSH — policy-gated remote access?

Superó 1 de 1 revisiones básicas aplicables. No hemos leído el código. Antes de agregar una clave o un token, revisa qué acceso pide el servidor y usa una clave que tenga solo los permisos que necesitas.

¿Qué claves o códigos necesita?

Debes completar: SSH_MCP_PASSWORD, SSH_MCP_PASSPHRASE, SSH_MCP_SUDO_PASSWORD

¿Se ejecuta en mi computadora o en la nube?

Se ejecuta en tu computadora. Tu app de IA lo inicia cuando hace falta, y los datos no pasan por los servidores del creador (a menos que el propio servidor llame a un servicio en línea).

¿Sigue en mantenimiento?

El repo de GitHub cambió por última vez –, y la última versión (2.23.1) llegó al registro hoy.

¿Qué apps pueden usarlo?

Las apps compatibles con MCP, como Claude Desktop, Claude Code, Cursor y VS Code. También necesitas Node.js en tu computadora.

¿Qué puedo usar en su lugar?

En la misma categoría: Spec Driven Development, Remote Desktop Commander, topo^alpin

Alternativas

Servidores de la misma categoría hechos por otros creadores, ordenados por estrellas.

Cómo leer una tarjeta:★ Estrellas de GitHubiTres pilares: reseñas · revisiones · usoiActualizado = fecha en que se publicó la última versión en el registroi

Spec Driven Development

de formulahendry

MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.

Se ejecuta en tu computadora★ 440MITActualizado hace 14 meses
Instalar

Remote Desktop Commander

de desktop-commander

Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.

Se ejecuta en la nube★ 211Actualizado ayer
Instalar

topo^alpin

de topoalpin.app

Avalanche bulletins and mountain weather forecasts for any place in the Alps.

Se ejecuta en la nubeActualizado hoy
Instalar

README del creador

Abrir el README

Copiado tal cual del repo del creador. PopNx MCP no lo ha revisado ni lo respalda. Se quitaron HTML, imágenes y scripts. Los enlaces llevan fuera de este sitio.

SSH MCP Server v2

SSH MCP Server is a security-first Model Context Protocol server that gives LLM agents controlled SSH access to remote hosts — with command classification, policy-based authorization, human-in-the-loop approval, and full audit logging.

The risk this server exists to manage. Giving an LLM shell access on a remote host puts private data, untrusted input and network egress in one place — Simon Willison's "lethal trifecta". Prompt injection has no general fix, so ssh-mcp assumes any command may be attacker-influenced: it classifies before executing, authorizes against a role × host-group matrix, gates destructive work behind approval, and records the decision either way. That narrows the blast radius; it does not remove the risk. Two things stay yours: never point it at a root account, and never set `auto` approval on a production profile. SECURITY.md has the full threat model.


Quick Start

1. Install
npm install -g ssh-mcp
2. Configure

Without a config the server still starts, so a client or directory can complete the MCP handshake and read tools/list — but every tool call is refused until you configure it, with a message naming the path below. Nothing runs on a host until this step is done. The one exception is reload-config: write the file, then call it with action: "reload" (or restart the server) to configure a server that is already running — see Reloading.

Create the config file at the path for your platform:

PlatformPath
Linux~/.config/ssh-mcp/config.toml (or $XDG_CONFIG_HOME/ssh-mcp/config.toml)
macOS~/Library/Application Support/ssh-mcp/config.toml
Windows%APPDATA%\ssh-mcp\config.toml
[defaults]

defaultProfile = "dev" approvalMode = "ask-destructive"

[[profiles]] name = "dev" host = "192.168.1.100" port = 22 user = "deploy" # NOT root! auth = "key" keyRef = "~/.ssh/id_ed25519" role = "admin" approvalPolicy = "auto" # dev is permissive

chmod 700 ~/.config/ssh-mcp && chmod 600 ~/.config/ssh-mcp/config.toml

The config decides which hosts, roles and policy rules this server honours, so it checks that nobody but you can read it — and treats the two platforms differently, because the question has a much clearer answer on one of them.

Linux and macOS: enforced. The mode check above, on the file *and* the directory — which is why chmod 700 is in that command, since mkdir -p under the default umask leaves the directory 0755. The server refuses to start otherwise. "Only the owner" is unambiguous here and chmod is a one-line fix.

Windows: split by what the ACL actually allows. There are no mode bits, so the ACL is read instead — and read exposure and write exposure are not treated alike, because Windows is much clearer about one of them than the other.

The ACL lets another account…Default
only read the configreported, and the server starts
change the configrefused
nothing (no ACL at all)refused — that is full control for everyone
…and if the ACL could not be readrefused, except when icacls is absent or the check timed out

A config under %APPDATA% inherits access for you, SYSTEM and Administrators and needs nothing done to it. One created elsewhere does not: a file under C:\ inherits *read* for every local account and *modify* for every authenticated one. The message names the two icacls commands that fix it either way.

Read exposure is reported rather than refused because that is where Windows is genuinely muddier than POSIX, and refusing over it blocked a config at the documented location (#138). Write exposure is refused because it is not muddy at all: another account being able to rewrite the file that decides which hosts, roles and approval policy this server honours is an authorization bypass, not a disclosure.

Two flags move the whole thing: --strictConfigAcl refuses everything the check objects to, read-only grants included; --allowUncheckedConfigAcl reports everything and refuses nothing. Neither combination leaves you without an exit, which is the lesson of #138.

Exit statuses
StatusMeaning
0Clean shutdown
1A defect in the server — printed with a stack trace; please report it
2How it was invoked or configured — printed as a message, no stack

A supervisor that treats any non-zero status as a failure needs no change. One that matched on 1 to detect a startup problem should match on 2 as well.

Starting with nothing configured is not an exit-2 condition, as of the release that added introspection without a config: the server starts so it can be described, and refuses each tool call instead, except reload-config. A supervisor that used a non-zero exit to catch an unconfigured deployment should watch for starting unconfigured on stderr, or read configured from GET /health when running the HTTP transport.

3. Set credentials via environment variables
export SSH_MCP_PASSWORD="your-password"        # if using auth=password

OR use SSH agent (recommended):

export SSH_AUTH_SOCK="$SSH_AUTH_SOCK" # already set if agent running

4. Connect from your MCP client

Claude Code:

claude mcp add --transport stdio ssh-mcp -- ssh-mcp

Claude Desktop / Cursor / Windsurf:

{

"mcpServers": { "ssh-mcp": { "command": "ssh-mcp", "env": { "SSH_MCP_PASSWORD": "your-password" } } } }

Never pass passwords as CLI arguments — they're visible via ps aux. Use env vars, config files, SSH agent, or OS keychain.


Tools (15)

ToolPurposereadOnlydestructive
list-connectionsDiscover available hosts and connection status✅—
list-sessionsList active sessions per host✅—
open-sessionCreate a named interactive (stateful) or background session——
close-sessionClose a session. A background session's command is signalled (INT/TERM/KILL) before its channel is dropped—✅
read-session-outputRead output from background sessions (e.g., tail -f)✅—
read-commandExecute allowlisted read-only commands (ls, cat, grep, ...)✅—
run-commandExecute arbitrary commands (destructive/privileged need approval, unless approvalPolicy = "auto")——
privileged-commandExecute with sudo (needs approval, unless approvalPolicy = "auto")—✅
sftp-uploadUpload a file via SFTP (replaces the destination unconditionally)—✅
sftp-downloadDownload a file via SFTP✅—
sftp-listList a remote directory, bounded in entries and bytes✅—
sftp-upload-fileStream a local file to the remote host, never through model context—✅
sftp-download-fileStream a remote file to local disk, never through model context—✅
signal-processSend INT/TERM/KILL to a remote PID—✅
reload-configShow the config file's status, or re-read and apply it without a restart (see Reloading)—✅
Streaming file transfer

sftp-upload/sftp-download move file *contents* through the model's context: the text is an argument on the way out and a response on the way back. That is what you want for a config snippet and exactly what you do not want for a 200 MB tarball or anything binary.

The two also differ on what they do to an existing destination, and the approved string now says which is which. sftp-upload replaces unconditionally and spells --overwrite every time, because that is what it always does; sftp-upload-file refuses unless you pass overwrite: true, and only then carries the flag. Since sftp-upload takes its content as an argument rather than naming a local file, its string also carries --bytes= --sha256=<32 hex> — without that, two uploads to the same path are the same string, which means one approval covers both and an auditor cannot tell which set of bytes landed. The digest is 128 bits rather than a short prefix because that claim has to hold against a caller who picks both payloads, not only against an accidental repeat.

[policy].denylist patterns are tested against that whole string and, for every SFTP tool, against the remote path on its own — as given, lexically normalized, and read the way Windows reads it (see "Policy Engine"). A rule written for the path, such as authorized_keys$, therefore does not depend on where the string puts it or on how the file is spelled. A rule anchored on the *whole* string (^sftp:upload /root/.*$) still does: that layout is ours to change, so anchor on the path instead.

sftp-upload-file and sftp-download-file stream between the remote host and local disk instead. Neither the bytes nor a base64 encoding of them ever reaches the model — the response is a byte count and two paths.

The two transfer tools are off until you configure `defaults.transferRoot`, and refuse with an explanation until then. (sftp-list has no local side and needs none of this.) That directory is the whole of their local reach:

[defaults]

transferRoot = "/srv/ssh-mcp-transfers" transferMaxBytes = 268435456 # 256MB per transfer transferTimeoutMs = 300000 # 5min with no bytes moving

Checked on every call, and refused rather than degraded if any of it fails: the directory must be 0700 and owned by the account running this server, with no group- or world-writable parent, and must not overlap the ssh-mcp installation, the config directory, the audit log directory, or ~/.ssh. Caller paths are confined to it, symlinks are refused rather than followed, and a download is staged as a sibling .part file and published atomically, so a failed transfer never leaves a half-written file at the destination.

transferTimeoutMs is an idle budget, not a total one: it bounds one metadata round-trip, or one stretch of the copy with no bytes moving, and is re-armed on progress. A slow but live transfer of a large file survives it; a stalled channel still fails within one window. That is why the byte cap above does not have to be divided by it — a total budget would have made a 256MB cap mean "only if the link sustains 900 KB/s".

Not available on Windows, where the transfer root cannot yet be verified private; the two transfer tools refuse there rather than writing into a directory other accounts may be able to read.

sftp-upload-file takes an optional mode (1–511; setuid, setgid and the sticky bit are refused). Omitted, a new remote file is published 0600; an overwritten one inherits the replaced file's permission bits — its permission bits only, not its setuid or setgid.

What a transfer is authorized for includes

Solo se muestra el principio; lee el resto en el repo

Pregunta a PopNx