A Model Context Protocol (MCP) server that enables AI agents like Claude Code and Cursor to execute commands on remote servers via persistent SSH sessions. Built with Bun and Hono for high performance and ease of deployment.
This MCP server provides a secure, stateful SSH interface for AI-powered development tools. It maintains persistent SSH connections in memory, allowing agents to execute commands across sessions without requiring any software installation on remote hosts.
Key Benefits:
- Zero Installation: No agent software needed on remote servers
- Stateful Sessions: Maintain context across multiple commands (e.g.,
cdfollowed byls) - Dual Transport: Works as both an HTTP service and stdio-based command
- Secure by Default: Key-based authentication with automatic session cleanup
- Persistent SSH Sessions: Powered by
ssh2with automatic idle cleanup after 30 minutes - Three Simple Tools:
ssh_open,ssh_exec, andssh_closefor complete session control - Flexible Transport: HTTP endpoint (
POST /mcp) or stdio for command-based MCP clients - Lightweight & Fast: Built on Bun runtime and Hono web framework
- Container Ready: Pre-built Docker images available on GitHub Container Registry
Pull the pre-built image:
docker pull ghcr.io/kiyo-e/ssh-mcp-server:latestRun in stdio mode for MCP clients:
docker run --rm -i ghcr.io/kiyo-e/ssh-mcp-server:latestWith SSH key authentication:
docker run --rm -i \
-e SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" \
ghcr.io/kiyo-e/ssh-mcp-server:latestInstall dependencies:
bun installStart the server:
# HTTP mode (default port 3000)
bun run start:http
# STDIO mode for command-based MCP clients
bun run start:stdioThis server exposes three tools for managing SSH sessions:
| Tool | Description | Parameters |
|---|---|---|
ssh_open |
Opens a new SSH session with password or key-based auth | host, username, optional port, optional password |
ssh_exec |
Executes a command on an existing session | sessionId, command, optional timeoutMs |
ssh_close |
Closes an active session and frees resources | sessionId |
// 1. Open a session
const session = await ssh_open({
host: "example.com",
username: "deploy",
port: 22
});
// 2. Execute commands (maintains state)
await ssh_exec({ sessionId: session.id, command: "cd /var/www" });
await ssh_exec({ sessionId: session.id, command: "ls -la" });
// 3. Close when done
await ssh_close({ sessionId: session.id });Quick Setup (Using Docker):
# Add the MCP server using Claude Code CLI
claude mcp add ssh-mcp docker run --rm -i ghcr.io/kiyo-e/ssh-mcp-server:latestWith SSH key authentication:
# Add with SSH_PRIVATE_KEY environment variable
claude mcp add ssh-mcp docker run --rm -i -e SSH_PRIVATE_KEY ghcr.io/kiyo-e/ssh-mcp-server:latest \
--env SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)"Or manually edit your Claude Code configuration file (~/.config/claude/claude_desktop_config.json):
{
"mcpServers": {
"ssh-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/kiyo-e/ssh-mcp-server:latest"
]
}
}
}With SSH key (manual configuration):
{
"mcpServers": {
"ssh-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"SSH_PRIVATE_KEY",
"ghcr.io/kiyo-e/ssh-mcp-server:latest"
],
"env": {
"SSH_PRIVATE_KEY": "$(cat ~/.ssh/id_rsa)"
}
}
}
}Add to your Codex MCP configuration:
# Add via command line
codex mcp add ssh-mcp docker run --rm -i ghcr.io/kiyo-e/ssh-mcp-server:latestWith SSH key authentication:
# Add with SSH_PRIVATE_KEY environment variable
codex mcp add ssh-mcp docker run --rm -i -e SSH_PRIVATE_KEY ghcr.io/kiyo-e/ssh-mcp-server:latest \
--env SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)"Or manually configure:
{
"mcpServers": {
"ssh-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/kiyo-e/ssh-mcp-server:latest"
]
}
}
}With SSH key (manual configuration):
{
"mcpServers": {
"ssh-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"SSH_PRIVATE_KEY",
"ghcr.io/kiyo-e/ssh-mcp-server:latest"
],
"env": {
"SSH_PRIVATE_KEY": "$(cat ~/.ssh/id_rsa)"
}
}
}
}{
"mcpServers": {
"ssh-mcp": {
"type": "http",
"url": "http://localhost:3000/mcp"
}
}
}| Variable | Description | Required |
|---|---|---|
SSH_PRIVATE_KEY |
Private key content for key-based authentication | No* |
PORT |
HTTP server port (default: 3000) | No |
*Required if not using password authentication with ssh_open
# HTTP mode with custom port
PORT=4000 bun run src/index.ts
# Docker with custom port
docker run --rm -p 4000:4000 \
-e PORT=4000 \
-e SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" \
ghcr.io/kiyo-e/ssh-mcp-server:latestIf Bun cannot write to your temp directory (common in sandboxed environments):
TMPDIR=$(pwd)/.tmp bun install# Clone the repository
git clone https://github.com/kiyo-e/ssh-mcp-server.git
cd ssh-mcp-server
# Install dependencies
bun install
# Build Docker image
docker build -t ssh-mcp-server .- Session Management: Always call
ssh_closewhen done to free resources immediately - Idle Timeout: Sessions automatically expire after 30 minutes of inactivity
- Stateful Commands: Take advantage of persistent shells for multi-step operations (e.g.,
cdthenls) - Security: Use key-based authentication when possible; avoid hardcoding passwords
- Runtime: Bun v1.1+ (for local development)
- Container: Docker (optional but recommended)
- SSH Access: Valid credentials for target remote hosts
- Repository: github.com/kiyo-e/ssh-mcp-server
- Container Images: ghcr.io/kiyo-e/ssh-mcp-server
- Issues: Report bugs or request features
MIT License - see LICENSE file for details.