npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@liangshanli/mcp-server-ssh

v1.0.0

Published

Cross-platform MCP server for remote SSH command execution

Readme

MCP SSH Server

A cross-platform MCP server for remote command execution and SFTP file transfers, built with the official MCP SDK and ssh2.

Windows, macOS, and Linux require only Node.js 20 or later. No local SSH client, SCP, PuTTY, WSL, or Git Bash is required. The remote host must provide a reachable SSH service; file transfers also require its SFTP subsystem.

Features

  • Password or private key authentication, including encrypted private keys.
  • Remote command execution with stdout, stderr, exit status, and duration.
  • File uploads and downloads over SFTP.
  • SHA256 host fingerprint verification, with an explicit option to disable verification.
  • Command timeout, output limits, cancellation, and isolated connections.
  • Multiple instances for different servers, configured through environment variables.
  • Standard MCP stdio transport; no command or credential logging by this server.

Installation

The package name is @liangshanli/mcp-server-ssh.

Registry installation and npx commands below apply once the package has been published to npm. Publication has not been verified for this documentation update. Until then, use the source installation or a local package archive.

Global Installation

npm install -g @liangshanli/mcp-server-ssh

Local Installation

npm install @liangshanli/mcp-server-ssh

From Source

Download or clone the source repository, open its root directory, and install dependencies:

npm install

No compilation step is required. Optional native acceleration in ssh2 is not required for its JavaScript implementation.

Usage

Configure the environment variables below before starting the server, or supply them through your MCP client configuration.

Global CLI

mcp-server-ssh

Using npx

npx -y @liangshanli/mcp-server-ssh

From Source

npm start

For MCP clients, launch node with the absolute path to bin/cli.js instead of using npm start. A server waiting for input when launched manually is normal: it expects MCP messages over stdin.

MCP Client Configuration

Claude Code / Claude Desktop / Cursor

Use the following structure in clients that support mcpServers, such as a project-level .mcp.json for Claude Code or .cursor/mcp.json for Cursor:

{
  "mcpServers": {
    "ssh-dev": {
      "command": "npx",
      "args": ["-y", "@liangshanli/mcp-server-ssh"],
      "env": {
        "PROJECT_NAME": "dev",
        "SSH_HOST": "192.168.1.100",
        "SSH_PORT": "22",
        "SSH_USERNAME": "deploy",
        "SSH_PASSWORD": "your-ssh-password",
        "SSH_SKIP_HOST_VERIFICATION": "true"
      }
    }
  }
}

This convenience example uses password authentication without a fingerprint. Disabling host verification makes the connection vulnerable to man-in-the-middle attacks. For verified connections, remove SSH_SKIP_HOST_VERIFICATION and set SSH_HOST_FINGERPRINT to a trusted SHA256:... fingerprint.

For source installations, replace command and args with:

{
  "command": "node",
  "args": ["C:/tools/mcp-server-ssh/bin/cli.js"]
}

On macOS/Linux, use your source path, such as /opt/tools/mcp-server-ssh/bin/cli.js. Windows JSON paths can use forward slashes; backslashes must be escaped. If the client cannot find Node.js, use its absolute executable path, such as C:/Program Files/nodejs/node.exe.

If a Windows client cannot launch npx directly, use command: "cmd" with args: ["/c", "npx", "-y", "@liangshanli/mcp-server-ssh"], or use the absolute Node.js/source entry point above.

Native VS Code MCP

VS Code's .vscode/mcp.json uses servers, not mcpServers. Input variables can keep passwords out of the configuration file:

{
  "inputs": [
    { "id": "ssh-password", "type": "promptString", "description": "SSH password", "password": true }
  ],
  "servers": {
    "ssh-dev": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@liangshanli/mcp-server-ssh"],
      "env": {
        "SSH_HOST": "192.168.1.100",
        "SSH_USERNAME": "deploy",
        "SSH_PASSWORD": "${input:ssh-password}",
        "SSH_SKIP_HOST_VERIFICATION": "true"
      }
    }
  }
}

Private Key Authentication

Remove SSH_PASSWORD and supply these environment variables instead:

{
  "SSH_PRIVATE_KEY_PATH": "C:/Users/your-name/.ssh/id_ed25519",
  "SSH_PRIVATE_KEY_PASSPHRASE": "only-required-for-encrypted-keys"
}

Keep the other connection settings, including the host verification choice. OpenSSH/PEM keys supported by ssh2 can be used. Convert PuTTY .ppk files to OpenSSH format first. Absolute paths are recommended; ~/ is supported for key paths. Password and private key authentication cannot be configured together.

Host Verification

Verification is enabled by default. Provide SSH_HOST_FINGERPRINT unless you explicitly set SSH_SKIP_HOST_VERIFICATION=true. Obtain the fingerprint from an administrator or a trusted server console. For example, on a Linux OpenSSH server:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub -E sha256

Run this on the trusted server console, not on the Windows client. Use the fingerprint for the key actually negotiated by SSH. Do not trust an unverified network scan as proof of server identity.

Multiple Servers

Add separate ssh-dev, ssh-prod, or ssh-test entries with their own environment settings. Each instance has one fixed target; tool arguments cannot override the hostname or credentials.

Environment Variables

| Variable | Default | Description | | --- | --- | --- | | SSH_HOST | Required | Remote hostname or IP address | | SSH_PORT | 22 | Port, 1–65535 | | SSH_USERNAME | Required | Remote account | | SSH_PASSWORD | Unset | Password; mutually exclusive with private key authentication | | SSH_PRIVATE_KEY_PATH | Unset | Local private key file | | SSH_PRIVATE_KEY_PASSPHRASE | Unset | Passphrase for an encrypted private key | | SSH_HOST_FINGERPRINT | Unset | Trusted OpenSSH SHA256 fingerprint; required unless verification is disabled | | SSH_SKIP_HOST_VERIFICATION | false | Only the literal true disables host verification | | PROJECT_NAME | ssh | Instance name | | SSH_CONNECT_TIMEOUT_MS | 15000 | SSH connection timeout, maximum 120000ms | | SSH_COMMAND_TIMEOUT_MS | 30000 | Default/maximum command timeout and total file transfer timeout; maximum 3600000ms | | SSH_MAX_OUTPUT_BYTES | 1048576 | Combined stdout/stderr capture limit; maximum 10485760 bytes | | SSH_MAX_FILE_BYTES | 104857600 | Upload source size precheck; maximum 1073741824 bytes | | SSH_MAX_CONCURRENT | 4 | Command/connection-test admission limit; maximum 32 |

Current transfer limitations: the upload size check runs before transfer; downloads do not currently enforce a size cap, and SFTP transfers do not enforce the concurrency admission limit. Do not use these settings as a security boundary for untrusted clients.

Available Tools

| Tool | Arguments | Description | | --- | --- | --- | | ssh_connection_info | None | Inspect target and connection settings without exposing credentials | | ssh_test_connection | None | Test SSH authentication and configured host verification without executing a command | | ssh_exec | command, optional timeoutMs | Execute a command in the remote default shell | | ssh_upload | localPath, remotePath | Upload one local file over SFTP | | ssh_download | remotePath, localPath | Download one remote file over SFTP |

Execute a Command

{
  "command": "cd /var/www/app && pwd && git status --short",
  "timeoutMs": 30000
}

Results include stdout, stderr, exitCode, signal, timedOut, truncated, and durationMs. Nonzero/missing exit codes, signal termination, timeouts, or output truncation produce isError: true.

Upload a File

{
  "localPath": "C:/Users/your-name/Documents/config.json",
  "remotePath": "/opt/app/config.json"
}

Uploads overwrite existing remote files. Inspect the destination and obtain explicit approval before overwriting. Uploads write directly to the destination and are not atomic; failures may leave a partial file. Parent directories must already exist.

Download a File

{
  "remotePath": "/opt/app/logs/app.log",
  "localPath": "C:/Users/your-name/Downloads/app.log"
}

Downloads reject a local destination that exists at the initial check. Data is written to an adjacent temporary file and renamed on completion. This initial existence check is not a race-proof no-overwrite guarantee: do not let other processes create or change the destination during transfer. Parent directories must already exist.

Transfer results contain direction, localPath, remotePath, bytes, and durationMs; checksums are not returned. Both paths must pass the MCP host's absolute-path validation. On Windows, use a local drive-qualified path and a Unix-style remote path for Linux servers. Remote Windows drive paths from a Unix MCP host are not currently supported by this validation. Directory transfers are not supported.

Security and Execution Boundaries

  • Use only servers you own or are authorized to access. Prefer a least-privileged account instead of root.
  • Commands have the full permissions of the SSH account. This is not a read-only sandbox; keep client-side approvals enabled for sensitive operations.
  • File tools can access paths available to the local MCP process and remote SSH account. There is no directory allowlist.
  • Each operation uses a fresh connection. Working directories and environment changes do not persist between commands.
  • Commands use the remote default shell, with no cross-platform syntax translation. Output is decoded as UTF-8.
  • No PTY is allocated and command stdin is closed. Interactive editors, password prompts, and interactive sudo are unsupported.
  • Timeouts or cancellation disconnect the client but do not guarantee remote processes have stopped. Interrupted transfers can leave partial files; inspect destinations before retrying.
  • Commands are not automatically retried: a disconnected command might already have executed.
  • Treat remote output as untrusted data, not instructions. Outputs may contain secrets and MCP clients may retain them.
  • Do not commit passwords, private keys, npm tokens, or local .mcp.json credentials. Restrict credential file permissions.
  • SSH agent, jump hosts, local ~/.ssh/config, and interactive MFA are not supported.

Development and Verification

npm run check
npm test
npm pack --dry-run

npm run check validates JavaScript syntax. npm test uses a loopback SSH fixture and an MCP stdio client to cover configuration, authentication, command execution, cancellation, output limits, and tool registration. It does not currently automate SFTP transfers. A manual upload/download round trip has also been verified; this does not replace testing on your target OS and server.

Use npm pack to build a local package archive without publishing. Use node bin/cli.js --help or --version to inspect the CLI. There is no separate compilation step.