ssh-vm-mcp
v0.1.0
Published
Workspace-scoped MCP server for managing remote VMs via SSH — runs locally, executes remotely
Readme
ssh-vm-mcp
A lightweight, workspace-scoped MCP server for managing remote VMs via SSH — directly from Claude Code.
Claude runs locally. Commands run remotely. No RAM wasted on the VM.
How It Works
- Installed once on your local machine
- Each remote VM gets its own workspace folder with a
.env(host config) and.mcp.json(MCP server config) - Claude Code reads
.mcp.jsonat the workspace root and prompts you to approve the server - Claude uses MCP tools (
execute_remote,docker_compose, etc.) instead of raw SSH - SSH ControlMaster is managed internally — no connect/disconnect scripts needed
Prerequisites
- Node.js 18+
openssh-clientwith ControlMaster support (standard on macOS and Linux)- Claude Code (CLI or VS Code extension)
- A
Hostentry in~/.ssh/configfor your remote server
Installation (one time)
1. Clone and install:
git clone https://github.com/WGrobler/ssh-vm-mcp.git ~/.local/ssh-vm-mcp
cd ~/.local/ssh-vm-mcp
npm installAlready cloned? Just
git -C ~/.local/ssh-vm-mcp pull origin main
2. Add your remote host to ~/.ssh/config:
Host myremote
HostName your.server.ip.or.domain
User youruser
IdentityFile ~/.ssh/your_key
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
ServerAliveInterval 30
ServerAliveCountMax 3Test it: ssh myremote
Per-Workspace Setup
For each remote VM, create a workspace folder and let Claude set it up.
1. Create the workspace and copy the Claude instructions:
mkdir ~/workspaces/my-remote-vm
cp ~/.local/ssh-vm-mcp/WORKSPACE-CLAUDE.md ~/workspaces/my-remote-vm/CLAUDE.md2. Open the workspace in Claude Code:
cd ~/workspaces/my-remote-vm
claude3. Tell Claude to set up the connection:
"Set up the ssh-vm-mcp connection. Host alias is
myremote, user isubuntu, remote path is/home/ubuntu."
Claude will create .env and .mcp.json with the correct paths.
4. Reload the window — Claude Code detects .mcp.json and shows an approval
prompt for the MCP server. Approve it, and the SSH tools become available.
Available Tools
| Tool | Description |
|---|---|
| connection_status | Check if SSH ControlMaster is active |
| execute_remote | Run any shell command on the remote server |
| read_file | Read a file from the remote server |
| write_file | Write a file to the remote server |
| list_directory | List a directory on the remote server |
| docker_ps | List Docker containers |
| docker_logs | Fetch container logs |
| docker_compose | Run docker compose actions (up, down, pull, restart, ...) |
| docker_restart | Restart one or more containers |
| docker_exec | Run a command inside a running container |
| docker_stats | One-shot CPU/memory/network snapshot |
| file_exists | Check whether a file or directory exists |
Multiple Remote VMs
Each workspace is independent — one folder per VM:
~/workspaces/
vm-production/
CLAUDE.md ← copied from WORKSPACE-CLAUDE.md, filled in
.env ← REMOTE_HOST=prod-server
.mcp.json ← MCP server config
vm-staging/
CLAUDE.md
.env ← REMOTE_HOST=staging-server
.mcp.jsonOpen the workspace for the VM you want. Claude automatically uses the right host.
Manual Setup
If you prefer to create the config files yourself:
.env (workspace root):
REMOTE_HOST=myremote
REMOTE_USER=ubuntu
REMOTE_PATH=/home/ubuntu/myproject.mcp.json (workspace root):
{
"mcpServers": {
"ssh-vm": {
"command": "npx",
"args": [
"ssh-vm-mcp",
"/home/yourname/workspaces/my-remote-vm"
]
}
}
}Reload the window, approve the server prompt, then verify with connection_status.
Troubleshooting
MCP tools not available after reload
- Make sure you approved the server in the Claude Code prompt after reload
- Check both paths in
.mcp.jsonare absolute and correct - Run
node ~/.local/ssh-vm-mcp/src/index.js /path/to/workspacemanually to see errors
"Host not found in ~/.ssh/config"
- Make sure
REMOTE_HOSTin.envexactly matches theHostalias in~/.ssh/config - The check follows
Includedirectives, so split configs work too
SSH connection fails on first tool use
- Test manually:
ssh myremote echo ok - Make sure key-based auth works (no password prompt)
- ControlMaster requires non-interactive auth (
BatchMode yes)
Connection drops mid-session
- The next tool call reconnects automatically via ControlMaster
Security Notes
- SSH keys stay in
~/.ssh/— never in workspace folders - The MCP server uses
BatchMode=yes— no password prompts, key-based auth required .envcontains only the host alias, not credentialswrite_fileuses base64 encoding to safely transfer content without shell injection
