ssh-mcp
Enables reading remote files over SSH, such as Caddy configuration files like /etc/caddy/Caddyfile.
Allows running commands on remote machines over SSH, such as managing Docker containers with 'docker ps' or other Docker CLI operations.
Enables reading and stat-ing remote files over SSH, such as NGINX configuration files like /etc/nginx/nginx.conf.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ssh-mcp run docker ps on my snow host and show me the output"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ssh-mcp
ssh-mcp is a local Model Context Protocol server that gives AI agents safe, structured access to remote machines over SSH. Instead of hand-assembling ssh snow "docker ps" commands, the agent calls typed tools like ssh_exec({host: "snow", command: "docker ps"}) and gets back stdout, stderr, exit code, timeout and truncation information.
AI Agent
│ MCP / stdio
▼
ssh-mcp
│ SSH (connection pool, your OpenSSH config/credentials)
▼
Remote machinesThe MCP server has essentially the same remote privileges as the SSH identity in use. Only connect it to agents you trust, on machines you are comfortable granting shell access to.
Requirements
Node.js >= 20
An SSH configuration you already use (
~/.ssh/config) with working credentials
Related MCP server: SSH MCP Server
Installation
From npm:
npm install -g @callumbicknell/ssh-mcpFrom source:
git clone https://github.com/CallumBicknell/ssh-mcp.git
cd ssh-mcp
pnpm install
pnpm run buildSSH configuration
ssh-mcp discovers hosts from your existing OpenSSH client config — ~/.ssh/config by default, or SSH_CONFIG_PATH if set. Nothing is duplicated: hostnames, users, ports and key paths all come from the file the ssh CLI already uses.
Per host, it resolves: HostName, Port, User, IdentityFile (tried in order), and IdentityAgent/SSH_AUTH_SOCK. Agent auth is preferred when available, then identity files.
MCP client configuration
Local/source usage:
{
"mcpServers": {
"ssh": {
"command": "node",
"args": ["/path/to/ssh-mcp/dist/index.js"]
}
}
}npm usage:
{
"mcpServers": {
"ssh": {
"command": "npx",
"args": ["-y", "@callumbicknell/ssh-mcp"]
}
}
}The server speaks MCP on stdio; all logs go to stderr.
Tools
Tool | Purpose |
| List the concrete host aliases available in your SSH config (no secrets) |
| Run a remote command; returns stdout/stderr/exit code/timeout/truncation |
| Read a remote text file (size-capped) |
| Atomically write a remote file (temp file + rename; never creates parent dirs) |
| Compact directory listing with type, size, mode, mtime |
| File/dir metadata: type, size, permissions, mtime, uid/gid |
| Persistent local port-forwards over the pooled SSH connection |
ssh_exec result shape
exit code: 0
stdout:
...
stderr:
...
[stdout truncated at 65536 bytes] ← only when truncatedNon-zero exit codes and stderr are always surfaced as MCP errors/text; timeouts return partial output plus a clear timeout message. On timeout the remote process is sent KILL and the channel is closed.
Configuration
Variable | Default | Meaning |
|
| Max bytes kept per output stream before truncation |
|
| Default |
|
| SSH connection timeout (ms) |
|
| Per-operation SFTP timeout (ms) |
|
| How long an idle pooled connection is kept (ms) |
|
| Path to the OpenSSH client config |
Timeout semantics: connection timeout bounds establishing the TCP/SSH session; command timeout bounds a single ssh_exec; operation timeout bounds one SFTP read/write/stat/readdir; idle timeout only evicts a connection with no active operations.
SSH compatibility limitations
ssh-mcp uses the ssh2 library plus a parser for ~/.ssh/config. It is not a full OpenSSH client:
Supported | Not supported (or approximate) |
|
|
|
|
|
|
Per-host aliases |
|
Agent and publickey auth | Password prompts (no interactive prompting — use keys/agent) |
For hosts that require jump hosts or proxy commands, either add direct HostName/Port entries you can reach, or front them with a reachable bastion address in your config. Switching to shelling out to the system ssh binary was evaluated and rejected: it would lose connection pooling, structured results, and make timeout/output control and atomic-write SFTP impossible to guarantee portably.
Security model
No command allowlist by design: the server is an administration tool, and a blanket allowlist would make it useless for that purpose. Command-policy/confirmation middleware is a clear extension point.
Private keys/passwords are read by
ssh2during auth only; they are never logged or returned.Host identifiers are validated and never interpolated into a local shell.
All output is byte-capped; all operations are timeout-bounded.
File writes are atomic and do not create parent directories.
Examples
ssh_hosts()
→ snow\nserver01\nfileserver
ssh_exec({host: "snow", command: "docker ps --format '{{.Names}} {{.Status}}'"})
ssh_read_file({host: "snow", path: "/etc/caddy/Caddyfile"})
ssh_write_file({host: "snow", path: "/tmp/deploy.yaml", content: "..."})
ssh_list_directory({host: "snow", path: "~/stacks"})
ssh_stat({host: "snow", path: "/etc/nginx/nginx.conf"})Quick install (one-liner for an AI agent)
Copy this into any agent that can read URLs and follow instructions:
Read https://raw.githubusercontent.com/CallumBicknell/ssh-mcp/main/AGENT_INSTALL.md and follow it exactly.Development
pnpm install # install
pnpm run dev # rebuild on change (tsc --watch)
pnpm run build # emit to dist/
pnpm run typecheck # strict type check
pnpm test # vitest — no real SSH server required
pnpm start # run on stdioTests mock the SSH/SFTP layer; they validate host parsing, validation, truncation (including UTF-8 edge cases), timeout logic, atomic write failure handling, connection-pool behaviour under concurrency, error formatting, and tool registration. CI runs install/typecheck/test/build on Node 22, 24 and 26.
Publishing
Package name on npm: @callumbicknell/ssh-mcp (the unscoped ssh-mcp name is owned by another project).
npm login
npm publish --access publicprepublishOnly runs typecheck + tests + build automatically. npm pack --dry-run shows that only dist/, README.md and LICENSE ship.
Available Tools
9 toolsssh_execA
Run a shell command on a remote machine over SSH. host is an alias from your local ~/.ssh/config (see ssh_hosts). The command runs via a non-interactive remote shell; stdout and stderr are captured, truncated at a configured size limit, and reported together with the exit code. Non-zero exit codes are surfaced, not hidden. Default timeout: 30s (override per call with timeout). For long-running jobs, run them in the background remotely and poll.
Inputs: host (required), command (required), timeout.
ssh_hostsA
List the SSH host aliases available in the local SSH client configuration (~/.ssh/config). Use these aliases as the host argument to the other ssh tools. Does not expose keys, usernames' credentials, or secrets.
Inputs: no named parameters.
ssh_list_directoryA
List the contents of a directory on a remote SSH host (defaults to the remote user's home directory). Each entry includes type, size, permission bits and modification time.
Inputs: host (required), path.
ssh_read_fileA
Read the contents of a text file on a remote SSH host. Large files are truncated at a configured size limit; for very large files prefer ssh_exec with head/tail/grep.
Inputs: host (required), path (required).
ssh_statA
Get metadata about a file or directory on a remote SSH host: type, size, permissions, modification time, owner/group ids.
Inputs: host (required), path (required).
ssh_tunnelA
Start a persistent local port-forward through the pooled SSH connection for host, e.g. forward local port 8080 to snow:80. The tunnel stays open until ssh_tunnel_stop is called. Returns the tunnel id and the local URL to use.
Inputs: host (required), localPort (required), remotePort (required), localHost, +1 more.
ssh_tunnelsB
List currently open SSH port-forward tunnels.
Inputs: no named parameters.
ssh_tunnel_stopA
Stop a port-forward tunnel by id (from ssh_tunnel / ssh_tunnels).
Inputs: id (required).
ssh_write_fileB
Write text to a file on a remote SSH host. The write is atomic (temporary file, then rename), so a failed or interrupted write never leaves a partially-written destination. Parent directories are NOT created automatically.
Inputs: host (required), path (required), content (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Each tool targets a distinct operation: file read/write, command execution, directory listing, metadata stat, host enumeration, and tunnel start/list/stop. The tunnel trio (ssh_tunnel, ssh_tunnels, ssh_tunnel_stop) is clearly differentiated by verb, and file/metadata tools do not overlap. No realistic misselection risk.
All tools use a consistent `ssh_` snake_case prefix, which is strong. Minor deviations exist: some are verb_noun (ssh_read_file, ssh_list_directory), some are bare resource plurals (ssh_hosts, ssh_tunnels), and ssh_tunnel_stop puts the verb last instead of following the verb_noun pattern.
Nine tools is well-scoped for an SSH remote-operations server. Each tool covers a distinct capability (file I/O, exec, directory listing, stat, hosts, tunnel lifecycle) without redundancy or bloat.
The surface covers core SSH workflows: read, write, execute, list, stat, host discovery, and tunnel lifecycle. Gaps exist for dedicated delete, mkdir, move, and binary/SCP-style transfer, but most of these are workable via ssh_exec with shell commands.
Maintenance
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Work on your own computers from Claude or ChatGPT: run commands, edit and search files.
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
- DNS-DATA RemoteDeprecatedcom.dns-data
Connect AI assistants to authorized Windows and macOS devices for files, commands, and management.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI coding agents to securely execute shell commands on remote SSH servers with granular per-host permission controls. Automatically discovers hosts from ~/.ssh/config and exposes dedicated tools for each allowed host to ensure proper authorization before remote execution.17,673 npmApache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.158 npm38Apache 2.0
- AlicenseAqualityDmaintenanceEnables AI agents to execute SSH commands, read files, and list directories on remote hosts with a configurable command-safety policy.5MIT
- FlicenseAqualityCmaintenanceEnables LLMs to securely SSH into remote servers, execute commands, and manage files via SFTP including listing, reading, writing, deleting, and renaming files.11-