mcp-ssh-remote

mcp-ssh-remote

Enables executing commands on remote SSH hosts, with full support for bastion/jump hosts and ~/.ssh/config, plus Slurm job management and rsync.

Category
Visit Server

README

mcp-ssh-remote

An MCP (Model Context Protocol) server that wraps the system ssh binary to execute commands on remote hosts — with full support for ProxyCommand, bastion hosts, jump hosts, and any configuration in ~/.ssh/config.

Built for workflows where your GPU/HPC server is behind a bastion host, has no internet access, and you want to develop locally with Claude Code while running jobs remotely.

Why this exists

Most SSH-based MCP servers (e.g. @fangjunjie/ssh-mcp-server) use Node's ssh2 library internally, which does not support ProxyCommand. If your remote server is behind a bastion host or requires a custom proxy setup defined in ~/.ssh/config, those servers simply cannot connect.

This server has no SSH implementation of its own — it calls the system ssh binary directly, so it inherits everything your shell SSH already supports: ProxyCommand, ProxyJump, identity files, ControlMaster, port forwarding, and so on.

Features

  • Works with any ~/.ssh/config setup — ProxyCommand, ProxyJump, magic-user auto-forward bastions
  • Optional SSH ControlMaster multiplexing — opt in with MCP_SSH_MULTIPLEX=1 for hosts where it works (off by default; see SSH multiplexing)
  • Login shell wrapping — commands run via bash -l so your full environment (conda, Slurm, modules) is always available
  • Slurm integration — submit, cancel, monitor jobs and read logs directly
  • rsync support — sync local directories to the remote server through the bastion
  • Safe file operations — large file writes piped via stdin (no shell arg limits), edit files with find-and-replace

SSH multiplexing

Multiplexing is off by default. Many jump hosts — especially magic-user auto-forward bastions (e.g. user/target_ip/target_user) — permit only one session per TCP connection. Every follow-up call then fails with Session open refused by peer, leaks stderr into the response, and flakes under load.

With multiplexing off, each call opens a fresh SSH connection. Slightly slower per call, but correct and reliable.

For hosts where multiplexing works (plain direct SSH, standard ProxyJump over a jumphost that supports session forwarding), opt in via env var:

{
  "mcpServers": {
    "ssh-remote": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/mcp-ssh-remote/index.js", "--host", "myserver"],
      "env": {"MCP_SSH_MULTIPLEX": "1"}
    }
  }
}

Requirements

  • Node.js >= 14
  • System ssh and rsync installed (openssh)
  • The target host must be reachable via ssh <hostname> from your terminal

Installation

Via npx (no install needed):

npx mcp-ssh-remote --host myserver

Or clone and run directly:

git clone https://github.com/JasonLinjc/mcp-ssh-remote.git
node mcp-ssh-remote/index.js --host myserver

Claude Code Configuration

Add to your ~/.claude.json under mcpServers:

{
  "mcpServers": {
    "ssh-remote": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/mcp-ssh-remote/index.js", "--host", "myserver"],
      "env": {}
    }
  }
}

Or with npx:

{
  "mcpServers": {
    "ssh-remote": {
      "type": "stdio",
      "command": "npx",
      "args": ["mcp-ssh-remote", "--host", "myserver"],
      "env": {}
    }
  }
}

You can also add it via the Claude Code CLI:

claude mcp add ssh-remote -- node /path/to/mcp-ssh-remote/index.js --host myserver

Bastion / ProxyCommand example

If ~/.ssh/config contains:

Host myserver
  HostName 10.0.0.5
  User alice
  ProxyCommand ssh bastion nc %h %p

Then just pass --host myserver — the ProxyCommand is followed automatically.

Tools

File Operations

Tool Description
execute_command Run any shell command (configurable timeout, up to 10 min)
read_file Read a remote file (supports offset and limit for large files)
write_file Write content to a remote file (creates parent dirs, handles large files)
edit_file Find-and-replace a unique string in a remote file
list_directory List files in a remote directory (ls -la)
grep_files Search file contents with regex (recursive, with file filtering)
glob_files Find files by glob pattern

Slurm Job Management

Tool Description
slurm_status Show job queue (current user or all users)
slurm_submit Submit a batch job (from script path or inline script content)
slurm_cancel Cancel a job by ID
slurm_job_info Get detailed job info (scontrol show job)
slurm_log Tail stdout/stderr logs of a running or completed job
slurm_array_summary Concise summary of an array job: completed/running/pending/failed counts, failed task IDs
slurm_resubmit_failed Identify failed tasks in an array job and resubmit only those

Sync & Utilities

Tool Description
rsync_to_remote Rsync a local directory to the remote host (with exclude patterns, dry-run, delete)
rsync_from_remote Rsync a remote directory to local (pull results back)
git_pull_remote Pull latest git changes in a remote directory
tail_file Read the last N lines of a remote file (useful for monitoring logs)
disk_usage Check disk usage of a file or directory (with optional depth)

Typical Workflow

1. Edit code locally           →  Claude Code's native Edit/Write tools
2. Sync to remote              →  rsync_to_remote (quick) or git push + git_pull_remote (committed)
3. Submit a Slurm job          →  slurm_submit
4. Monitor training            →  slurm_status + slurm_log
5. Read results                →  read_file, grep_files

Example conversation:

You:    "Change the learning rate to 1e-4 in train.py"
Claude: [edits local file]

You:    "Sync and submit on gpu31 with 4 GPUs"
Claude: [rsync_to_remote] → [slurm_submit -p gpu31 --gres=gpu:4]

You:    "How's it going?"
Claude: [slurm_status] → [slurm_log]

Usage

node index.js --host <hostname>

<hostname> must match a host you can reach with ssh <hostname> — an IP, a hostname, or a Host alias from ~/.ssh/config.

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured