Remote SSH MCP
Click on "Install 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., "@Remote SSH MCPOpen a session to prod and run 'df -h'"
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.
Remote SSH MCP
English | 简体中文
A local MCP server that exposes persistent, stateful remote Bash sessions to AI agents. Reusing the same session ID preserves the working directory, environment variables, and shell side effects. Open a new session whenever a clean environment is required.
Remote SSH MCP uses the system OpenSSH client instead of reimplementing SSH.
Your existing ~/.ssh/config, known hosts, SSH agent, ProxyJump routes, and
hardware-key policies continue to work.
Why
Running ssh host "command" for every remote action repeatedly reconnects,
loses shell state, reproduces banners and environment probes, and wastes model
context. Remote SSH MCP keeps one remote shell alive behind a small, explicit
tool interface:
ssh_open(host) → session id
ssh_run(id, command) → same cwd and environment
ssh_peek(id) / ssh_interrupt(id) → observe or recover a stuck command
ssh_close(id) → release the shell and connectionRelated MCP server: TerminusAI
Features
Persistent remote Bash sessions with stable IDs
Working-directory and environment persistence within each session
Separate
stdoutandstderrin tool resultsNon-blocking observation of long commands with a separate hard timeout
Safe fail-closed behavior when shell recovery cannot be confirmed
Head-and-tail output truncation with valid UTF-8 boundaries
Exact SSH Host alias allowlist from
ssh_configand explicit configurationSession limits, idle reaping, command auditing, and a minimal safety denylist
MCP stdio support for both legacy and current protocol handshakes
No password, private-key text, or arbitrary SSH option arguments
MCP tools
Tool | Purpose |
| Open a clean persistent shell for an allowed SSH Host alias |
| Run a non-interactive command in an existing session |
| Inspect status and the latest N output lines; optional |
| Send Ctrl-C and wait for confirmed shell recovery |
| List sessions, cwd, state, idle countdown, and capacity |
| Clean up and close a session |
Requirements
Node.js 20 or newer
An OpenSSH client
A remote host with Bash,
base64,stty,mkdir,cat, andrmA configured SSH Host alias and a known host key
The server enforces BatchMode=yes and StrictHostKeyChecking=yes. Complete
first-connection host-key confirmation and authentication setup in a normal
terminal before using the MCP server. It never opens password or confirmation
prompts.
Install
git clone https://github.com/the-nine-nation/remote-ssh-mcp.git
cd remote-ssh-mcp
npm install
npm run build
npm testRun the server directly:
node /absolute/path/to/remote-ssh-mcp/dist/index.jsOr, after installing it as a package, use the remote-ssh-mcp executable.
MCP host configuration
Most stdio MCP hosts accept a configuration shaped like this; the outer key may differ by host:
{
"mcpServers": {
"remote-ssh": {
"command": "node",
"args": [
"/absolute/path/to/remote-ssh-mcp/dist/index.js"
],
"env": {
"SSH_MCP_ALLOWED_HOSTS": "prod,staging"
}
}
}
}SSH_MCP_ALLOWED_HOSTS adds explicit aliases to the allowlist. By default, the
server also discovers exact Host aliases from ~/.ssh/config and its
Include files. Patterns containing *, ?, or ! are ignored. Tool inputs
accept only safe aliases, not user@host, ports, or extra SSH options.
Configuration
The optional configuration file defaults to:
~/.config/remote-ssh-mcp/config.jsonExample:
{
"allowedHosts": ["prod", "staging"],
"sshConfigPath": "~/.ssh/config",
"sshPath": "ssh",
"maxTimeoutSec": 1800,
"defaultWaitSec": 10,
"maxWaitSec": 30,
"openTimeoutSec": 20,
"idleTimeoutSec": 1800,
"interruptGraceSec": 5,
"maxSessions": 8,
"outputMaxBytes": 32768,
"outputHeadBytes": 4096,
"auditLogPath": "~/.local/state/remote-ssh-mcp/audit.jsonl"
}Environment variables override file settings:
Environment variable | Purpose |
| Configuration file path |
| Comma-separated additional Host aliases |
| SSH config path |
| OpenSSH executable |
| Maximum explicitly requested command timeout |
| How long |
| Maximum permitted |
| Connection and handshake timeout |
| Idle session lifetime |
| Marker recovery grace period after Ctrl-C |
| Maximum live sessions |
| Per-stream retained output limit |
| Retained head bytes when truncating |
| JSONL audit-log path |
The audit log is created with mode 0600. It records the session, host,
result, duration, command length, command name, and SHA-256 hash. Full command
arguments are intentionally omitted to reduce the chance of logging secrets.
Execution semantics
One session accepts only one foreground command at a time. Concurrent
ssh_runcalls returnbusyinstead of being queued.wait_seclimits only how long the MCP call waits. If it expires,ssh_runreturnsstatus: "running"while the remote command continues. Do not start the command again. Poll withssh_peek(wait_sec=...)so the call blocks until the command finishes or the wait expires; do not busy-loop withwait_sec: 0. Stop it withssh_interrupt, or open another session for concurrent work.Commands have no automatic execution timeout by default. The model owns their lifecycle. Only an explicitly supplied
timeout_seccreates a hard deadline that sends Ctrl-C.ssh_peekreturns the newest 50 lines from stdout and stderr by default. Passlines(maximum 1,000) when a different tail length is needed. Byte limits still apply, so a very long individual line remains bounded. Optionalwait_sec(default 0, capped bymaxWaitSec) long-polls while the session is running and returns immediately when idle.User-command stdin is
/dev/null. Do not runvim,top, interactive installers, or other TUI/input-driven programs.A timeout sends Ctrl-C. If a complete protocol marker arrives during the grace period, the session returns to idle. Otherwise, the session is closed to prevent an unknown foreground process from corrupting the next command.
stdoutandstderrindependently retain their beginning and end. Responses always end on valid UTF-8 boundaries.The built-in denylist blocks only a few obviously destructive patterns. It is not a complete policy engine.
This project targets a trusted local developer environment. It is not a multi-tenant remote execution service.
If the MCP host exits or its stdio/parent connection disappears, the server closes every tracked SSH connection, including connections still opening. Normal foreground processes end with their PTY; deliberately detached processes such as
nohup,setsid, services, and containers may continue.
For example, start a docker pull with wait_sec: 10 and omit
timeout_sec. A running result means the original pull remains active—not
that it should be retried. Call ssh_peek with the same session ID and a
positive wait_sec until it becomes idle, interrupt it explicitly, or open
another session for parallel work.
Development
npm run typecheck
npm test
npm run build
npm audit --omit=devThe test suite covers MCP stdio discovery and calls, persistent cwd/environment state, stream separation, framing across arbitrary chunk boundaries, timeout fail-closed behavior, shell death, allowlist discovery, output truncation, and the safety denylist.
Security
Please do not report security vulnerabilities through public GitHub issues. Until a private security-advisory workflow is configured, contact the maintainer through the email listed on their GitHub profile.
Remote commands can have irreversible side effects even when the MCP transport works correctly. Review host permissions, use least-privilege accounts, and keep the allowlist narrow.
License
The wire protocol and detailed design decisions are documented in 远程SSH-MCP设计.md.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceEnables AI assistants to securely execute shell commands on local machines through an SSH interface with session management, command execution, and sudo support.Last updated1
- AlicenseBqualityDmaintenanceExecute terminal commands locally or remotely via SSH with session persistence and environment variable support. Manage terminal sessions that maintain state for up to 20 minutes, enabling efficient command execution workflows. Connect using stdio or SSE for flexible integration with AI models and aLast updated11MIT
- Alicense-qualityDmaintenanceProvides LLM clients with safe, persistent SSH access to remote machines through the Model Context Protocol. Maintains shell sessions that preserve environment state between commands, enabling multi-step workflows and interactive diagnostics on remote systems.Last updated7116MIT
- Flicense-qualityCmaintenanceEnables AI assistants to run commands on remote SSH-accessible devices via persistent sessions, supporting both POSIX and CLI shells with safety filters.Last updated
Related MCP Connectors
Operate your own Linux servers from your LLM. Requires the SentinelX agent installed per host.
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Persistent memory and cross-session learning for AI coding assistants (hosted remote MCP).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/the-nine-nation/remote-ssh-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server