AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP unreviewed MIT Self-run

Ssh Mcp

mcp-n0madic-ssh-mcp · by n0madic

SSH MCP server

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add mcp-n0madic-ssh-mcp

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Destructive filesystem operation.

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Ssh Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

SSH MCP Server

A Model Context Protocol (MCP) server that provides AI agents with secure SSH access to remote hosts. Supports connection pooling, key-based and password authentication, sudo, file operations via SFTP, SSH tunnels (local port forwarding), command filtering, rate limiting, output truncation, and graceful shutdown.

Features

  • SSH Connection Pool — reuses connections, auto-reconnect on failure, idle cleanup, auto-detection of remote OS and shell
  • Authentication — explicit key_path first, then ssh-agent, then auto-discovered ~/.ssh/id_* keys (when no agent), then password; automatic ~/.ssh/config alias resolution
  • Command Execution — with sudo support, working directory, timeout, graceful kill (SIGTERM → SIGKILL), ANSI stripping
  • SFTP File Operations — upload/download files and directories, read files with line offset/limit, edit files (replace/patch/create), file info with directory listing, ~ path expansion
  • Interactive PTY Terminals — buffered PTY sessions for interactive programs (vim, htop, REPL), dialogs, and real-time output (opt-in with --enable-terminal)
  • SSH Tunnels — local port forwarding (localhost:port → remote:port via SSH) for accessing remote services like databases, APIs, and web servers (opt-in with --enable-tunnels)
  • Output Truncation — configurable per-stream output size limit (--max-output-size) to prevent LLM context overflow
  • Security — host/command allowlist/denylist (regex + CIDR), per-host rate limiting, path traversal protection, filename length validation
  • Transports — stdio (default) and Streamable HTTP (localhost only)
  • Graceful Shutdown — closes all tunnels, SSH connections, and terminal sessions on SIGINT/SIGTERM

Installation

go install github.com/n0madic/ssh-mcp@latest

Or build from source:

git clone https://github.com/n0madic/ssh-mcp.git
cd ssh-mcp
go build -o ssh-mcp .

Usage

Stdio transport (default)

./ssh-mcp

HTTP transport

./ssh-mcp --enable-http
# Listens on localhost:8081/mcp

Both transports

./ssh-mcp --enable-http
# Stdio + HTTP on localhost:8081/mcp

HTTP only (no stdio)

./ssh-mcp --enable-http --disable-stdio

CLI Flags

| Flag | Env Var | Default | Description | |------|---------|---------|-------------| | --enable-http | MCP_SSH_ENABLE_HTTP | false | Enable HTTP transport | | --http-port | MCP_SSH_HTTP_PORT | 8081 | HTTP transport port | | --disable-stdio | MCP_SSH_DISABLE_STDIO | false | Disable stdio transport | | --no-verify-host-key | MCP_SSH_NO_VERIFY_HOST_KEY | false | Disable host key verification | | --known-hosts | MCP_SSH_KNOWN_HOSTS | ~/.ssh/known_hosts | Path to knownhosts file | | --ssh-config | MCP_SSH_CONFIG | ~/.ssh/config | Path to SSH config file | | --enable-sudo | MCP_SSH_ENABLE_SUDO | false | Allow sudo execution | | --command-timeout | MCP_SSH_COMMAND_TIMEOUT | 60s | Command execution timeout | | --host-allowlist | MCP_SSH_HOST_ALLOWLIST | (empty) | Host allowlist (can be specified multiple times) | | --host-denylist | MCP_SSH_HOST_DENYLIST | (empty) | Host denylist (can be specified multiple times) | | --command-allowlist | MCP_SSH_COMMAND_ALLOWLIST | (empty) | Command allowlist regex (can be specified multiple times) | | --command-denylist | MCP_SSH_COMMAND_DENYLIST | (empty) | Command denylist regex (can be specified multiple times) | | --rate-limit | MCP_SSH_RATE_LIMIT | 60 | Rate limit (requests per minute per host) | | --rate-limit-file-ops | MCP_SSH_RATE_LIMIT_FILE_OPS | false | Apply rate limiting to SFTP file operations | | --local-base-dir | MCP_SSH_LOCAL_BASE_DIR | (empty) | Restrict local file operations to this directory | | --max-file-size | MCP_SSH_MAX_FILE_SIZE | 0 | Maximum file size for read operations (0=unlimited) | | --max-connections | MCP_SSH_MAX_CONNECTIONS | 0 | Maximum concurrent SSH connections (0=unlimited) | | --http-token | MCP_SSH_HTTP_TOKEN | (empty) | Bearer token for HTTP transport authentication | | --disable-tools | MCP_SSH_DISABLE_TOOLS | (empty)_ | Disable specific tools (can be specified multiple times) | | --enable-terminal | MCP_SSH_ENABLE_TERMINAL | false | Allow interactive PTY terminal sessions (ssh_open_terminal) | | --max-terminals | MCP_SSH_MAX_TERMINALS | 0 | Maximum concurrent PTY terminal sessions (0=unlimited) | | --max-output-size | MCP_SSH_MAX_OUTPUT_SIZE | 0 | Maximum output size per stream in bytes for execute/terminal results (0=unlimited) | | --enable-tunnels | MCP_SSH_ENABLE_TUNNELS | false | Allow SSH tunnel creation (ssh_tunnel_create) | | --max-tunnels | MCP_SSH_MAX_TUNNELS | 0 | Maximum concurrent SSH tunnels (0=unlimited) | | --version | — | — | Show version and exit |

Priority: CLI flags > environment variables > defaults.

Examples

Allow only specific hosts (regex patterns):

./ssh-mcp --host-allowlist "192.168.1.*" --host-allowlist "10.0.0.*"

Allow hosts by CIDR range:

./ssh-mcp --host-allowlist "10.0.0.0/8" --host-allowlist "192.168.0.0/16"

Block dangerous commands (multiple flags):

./ssh-mcp --command-denylist "rm\s+-rf.*" --command-denylist "shutdown.*" --command-denylist "reboot.*"

> Note: Command/host filter patterns are auto-anchored with ^ and $ for full-string matching. Use .* for substring matching (e.g., rm\s+-rf.* matches rm -rf / but rm alone won't match format). Host patterns also support CIDR notation (e.g., 10.0.0.0/8) — CIDR patterns are detected automatically and match by IP range instead of regex.

Using environment variables (comma-separated):

export MCP_SSH_HOST_ALLOWLIST="host1.example.com,host2.example.com,host3.example.com"
export MCP_SSH_COMMAND_DENYLIST="rm\s+-rf.*,shutdown.*,reboot.*"
export MCP_SSH_ENABLE_SUDO=true
./ssh-mcp

Restrict local file operations to a directory:

./ssh-mcp --local-base-dir /tmp/ssh-workspace

Enable HTTP transport with bearer token authentication:

./ssh-mcp --enable-http --http-token "my-secret-token"

Limit concurrent connections and file size:

./ssh-mcp --max-connections 5 --max-file-size 10485760

Limit output size to prevent LLM context overflow:

./ssh-mcp --max-output-size 65536

Limit concurrent SSH tunnels:

./ssh-mcp --max-tunnels 5

Disable specific tools (multiple flags):

./ssh-mcp --disable-tools ssh_execute --disable-tools ssh_edit_file

Disable tools via environment variable:

export MCP_SSH_DISABLE_TOOLS="ssh_execute,ssh_edit_file"
./ssh-mcp

MCP Tools

ssh_connect

Connect to a remote host via SSH.

Minimal (key auth from ssh-agent or ~/.ssh/id_*):

{
  "host": "example.com"
}

Full format — user, password, port inline:

{
  "host": "admin:secret@example.com:2222"
}

Explicit parameters (override inline values):

{
  "host": "example.com",
  "port": 2222,
  "user": "admin",
  "key_path": "~/.ssh/id_ed25519"
}

SSH config alias (resolved automatically from ~/.ssh/config):

{
  "host": "my-server"
}

SSH config aliases are resolved automatically — no extra flags needed. Explicit parameters (port, user, key_path) override values from the config.

Returns session_id for use with other tools. Also auto-detects remote OS, architecture, and shell.

ssh_execute

Execute a command on a remote host. On timeout, sends SIGTERM first (5s grace period) then SIGKILL, and returns partial stdout/stderr with a [TIMEOUT] marker in stderr.

{
  "session_id": "admin@example.com:22",
  "command": "ls -la /var/log",
  "timeout": 30,
  "sudo": true,
  "sudo_password": "secret",
  "working_dir": "/home/admin"
}

ssh_disconnect

Disconnect an SSH session.

{
  "session_id": "admin@example.com:22"
}

sshlistsessions

List all active SSH sessions with their connection details, statistics, active terminal sessions, and active tunnels (no parameters required).

ssh_upload

Upload a local file or directory to a remote host via SFTP. Automatically detects whether the local path is a file or directory. Preserves file permissions and directory structure. Supports ~ for remote home directory.

Upload a file:

{
  "session_id": "admin@example.com:22",
  "local_path": "/tmp/config.yaml",
  "remote_path": "~/config.yaml"
}

Upload a directory (recursive):

{
  "session_id": "admin@example.com:22",
  "local_path": "/tmp/myapp",
  "remote_path": "/opt/myapp"
}

ssh_download

Download a file or directory from a remote host via SFTP. Automatically detects whether the remote path is a file or directory. Preserves file permissions and directory structure. Supports ~ for remote home directory.

Download a file:

{
  "session_id": "admin@example.com:22",
  "remote_path": "~/app.log",
  "local_path": "/tmp/app.log"
}

Download a directory (recursive):

{
  "session_id": "admin@example.com:22",
  "remote_path": "/opt/myapp",
  "local_path": "/tmp/myapp-backup"
}

ssheditfile

Edit a file on a remote host. Two modes:

Replace mode (default) — full content replacement or new file creation:

{
  "session_id": "admin@example.com:22",
  "remote_path": "/etc/myapp/config.yaml",
  "mode": "replace",
  "content": "new file content here",
  "backup": true
}

Patch mode — find and replace:

{
  "session_id": "admin@example.com:22",
  "remote_path": "/etc/myapp/config.yaml",
  "mode": "patch",
  "old_string": "old_value",
  "new_string": "new_value",
  "backup": true
}

sshreadfile

Read a file from a remote host with optional line offset and limit. Returns content with line numbers (like cat -n). Supports ~ for home directory.

Read entire file:

{
  "session_id": "admin@example.com:22",
  "remote_path": "~/app.log"
}

Read with offset and limit (pagination):

{
  "session_id": "admin@example.com:22",
  "remote_path": "/var/log/syslog",
  "offset": 100,
  "limit": 50
}

Read with max file size limit:

{
  "session_id": "admin@example.com:22",
  "remote_path": "~/large-file.csv",
  "max_size": 1048576
}

Returns file content with line numbers, total line count, file size, and which lines are shown.


Interactive PTY Terminal Tools

These four tools provide buffered PTY access for interactive programs. Requires --enable-terminal.

Typical workflow:

ssh_open_terminal   →  opens shell, returns terminal_id + initial prompt
ssh_send_input      →  write text or keystrokes, get new output
ssh_read_output     →  poll for new output without writing
ssh_close_terminal  →  close the session

Active terminals are also listed in ssh_list_sessions output.

sshopenterminal

Open a PTY terminal session. Requires --enable-terminal flag on the server.

{
  "session_id": "admin@example.com:22",
  "cols": 120,
  "rows": 50,
  "term_type": "xterm-256color",
  "wait_ms": 500,
  "protect_exit": true
}

Returns terminal_id and the initial shell output (prompt). cols/rows/term_type/wait_ms/protect_exit are optional.

protect_exit (default true) overrides the shell's exit command with a no-op function so an accidental exit from the agent cannot kill the session. Use ssh_close_terminal to terminate the session explicitly. Subshells (sudo, python, ssh into another host) are unaffected. Automatically disabled for Windows hosts.

sshsendinput

Send text or a special key to a terminal and read new output.

Send a command:

{
  "terminal_id": "term-1",
  "text": "ls -la\n",
  "wait_ms": 300
}

Send a special key:

{
  "terminal_id": "term-1",
  "special_key": "CTRL_C"
}

Supported special keys: CTRL_C, CTRL_D, CTRL_Z, ESC, TAB, BACKSPACE, ENTER, ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT.

Use \n for newline and \r for carriage return in text. Exactly one of text or special_key must be provided — setting both is an error.

sshreadoutput

Read buffered output since the last read without writing anything.

{
  "terminal_id": "term-1",
  "wait_ms": 1000,
  "limit": 100
}
  • wait_ms — wait up to N milliseconds for new data (default 0 = return immediately).
  • limit — maximum number of complete lines to return per call (default 0 = return everything). Remaining lines stay in the buffer for subsequent calls. Response includes lines (count returned) and has_more (true if more lines are buffered); the text response also appends a marker line when more output is pending.

sshcloseterminal

Close a PTY terminal session.

{
  "terminal_id": "term-1"
}

SSH Tunnel Tools

These three tools provide local port forwarding through SSH connections. Useful for accessing remote databases, web servers, or APIs that aren't directly reachable. Requires --enable-tunnels.

Typical workflow:

ssh_tunnel_create  →  binds local port, forwards to remote address
ssh_tunnel_list    →  show active tunnels
ssh_tunnel_close   →  stop forwarding and release the port

Active tunnels are also listed in ssh_list_sessions output. Tunnels are automatically closed when the parent SSH session is disconnected.

sshtunnelcreate

Create a local port forwarding tunnel.

Auto-assign local port:

{
  "session_id": "admin@example.com:22",
  "remote_addr": "localhost:5432",
  "local_port": 0
}

Specific local port:

{
  "session_id": "admin@example.com:22",
  "remote_addr": "10.0.0.5:3306",
  "local_port": 13306
}

Returns tunnel_id, the bound local address and port, and the remote address.

sshtunnellist

List all active tunnels. Optionally filter by session ID.

{
  "session_id": "admin@example.com:22"
}

sshtunnelclose

Close an active tunnel.

{
  "tunnel_id": "admin@example.com:22-1"
}

Codex Configuration

Add to Codex using the CLI:

codex mcp add ssh \
  --env SSH_AUTH_SOCK="$SSH_AUTH_SOCK" \
  -- /path/to/ssh-mcp --enable-terminal

Verify the saved configuration:

codex mcp get ssh

For passphrase-protected SSH keys, ssh-mcp must be able to use your ssh-agent. It does not prompt for private-key passphrases itself. If Codex starts ssh-mcp without a working SSH_AUTH_SOCK, ssh_connect can fail before any network connection attempt with:

connect failed: auth config: no authentication methods available

Before adding the MCP server, make sure the key is loaded:

ssh-add -l

On macOS, load the key into the agent and store the passphrase in Keychain:

/usr/bin/ssh-add --apple-use-keychain ~/.ssh/id_rsa

If SSH_AUTH_SOCK changes after reboot or after restarting your terminal, update the Codex MCP entry by running codex mcp add again with the current value. Existing Codex sessions may keep an already-started ssh-mcp process with the old environment; restart Codex or remove the stale ssh-mcp process after changing the config.

Manual equivalent in ~/.codex/config.toml:

[mcp_servers.ssh]
command = "/path/to/ssh-mcp"
args = ["--enable-terminal"]

[mcp_servers.ssh.env]
SSH_AUTH_SOCK = "/var/run/com.apple.launchd.XYZ/Listeners"

Claude Code Configuration

Add to Claude Code using the CLI:

claude mcp add --transport stdio --scope user ssh -- /path/to/ssh-mcp --no-verify-host-key

Or manually edit ~/.claude.json:

{
  "mcpServers": {
    "ssh": {
      "type": "stdio",
      "command": "/path/to/ssh-mcp",
      "args": ["--no-verify-host-key"]
    }
  }
}

Claude Desktop Configuration

Add to your Claude Desktop config (`~/Library

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.