@hbarhate/ssh-mcp-server
v0.1.0
Published
MCP server for SSH remote command execution
Downloads
80
Maintainers
Readme
SSH MCP Server
A Model Context Protocol (MCP) server for executing commands on remote servers via SSH, built with TypeScript and Node.js. Provides comprehensive tools for SSH command execution, Kubernetes management, and connection pooling.
Features
- Dual Authentication - SSH key and password authentication support
- 8 MCP Tools - Complete coverage of SSH operations
- Persistent Connections - Efficient connection pooling and reuse
- Host Aliases - Pre-configure named hosts with connection details
- Command Confirmation - Layered approval system for safe execution
- Kubernetes Support - Specialized kubectl command execution
- Batch Execution - Run up to 5 commands in parallel
- TypeScript - Full type safety and modern ES modules
Installation
Using npm (Global)
npm install -g @hbarhate/ssh-mcp-serverUsing npx (No Installation)
npx @hbarhate/ssh-mcp-serverUpdating
Update Global Installation
npm update -g @hbarhate/ssh-mcp-serverUpdate to Latest with npx
npx @hbarhate/ssh-mcp-server@latestCheck Current Version
npm list -g @hbarhate/ssh-mcp-serverConfiguration
Configure the server using environment variables or configuration files.
Environment Variables
export MCP_APP_CONFIG_PATH="/path/to/app.config.json"
export MCP_HOSTS_CONFIG_PATH="/path/to/hosts.json"
export SSH_PASSWORD_MYUSER="<encrypted-password>"| Variable | Description |
| ------------------------ | --------------------------------------------------------------------------- |
| MCP_APP_CONFIG_PATH | Path to app.config.json (defaults to ./app.config.json) |
| MCP_HOSTS_CONFIG_PATH | Path to hosts.json (defaults to ./hosts.json) |
| SSH_PASSWORD_<USER> | Encrypted password for SSH authentication (e.g., SSH_PASSWORD_MYUSER) |
App Configuration File
Create app.config.json in your project directory:
{
"defaultUser": "myuser",
"defaultAuthType": "password",
"sshPasswordEnvVar": "SSH_PASSWORD_MYUSER",
"askUserApproval": true,
"connectionTimeout": 30000,
"healthCheckInterval": 60000
}Host Configuration File
Create hosts.json to define host aliases:
{
"hosts": {
"k8s-prod": {
"host": "kubemaster01.prod.example.com",
"user": "myuser",
"authType": "password",
"description": "Kubernetes master production"
},
"jumpbox": {
"host": "10.0.1.100",
"user": "ubuntu",
"authType": "key",
"keyPath": "~/.ssh/jumpbox_rsa",
"description": "Jump server"
}
}
}MCP Client Configuration
Add to your MCP client config (e.g., Claude Desktop, Windsurf):
{
"mcpServers": {
"ssh-mcp-server": {
"command": "node",
"args": ["/path/to/ssh-mcp-server/dist/index.js"],
"env": {
"MCP_APP_CONFIG_PATH": "/path/to/app.config.json",
"MCP_HOSTS_CONFIG_PATH": "/path/to/hosts.json",
"SSH_PASSWORD_MYUSER": "<encrypted-password>"
}
}
}
}Tools Reference
SSH Execution
| Tool | Description | Parameters |
| --------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------- |
| ssh_execute | Execute command on remote server | host, command, dryRun?, user?, authType?, password?, keyPath?, passphrase? |
| ssh_execute_batch | Execute up to 5 commands in parallel | executions (array of execution objects) |
| ssh_kubectl | Execute kubectl on kubemaster nodes | pod, region, command, user? |
Connection Management
| Tool | Description | Parameters |
| --------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------- |
| ssh_connection_status | Get status of persistent connections | - |
| ssh_close_connection | Close a specific SSH connection | host, user? |
| ssh_close_all_connections | Close all persistent connections | - |
Host Management
| Tool | Description | Parameters |
| --------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------- |
| ssh_list_hosts | List all configured host aliases | - |
| generate_hosts | Generate hostnames based on patterns | nodeType, pod, region, count? |
Usage Examples
Execute Remote Command
{
"tool": "ssh_execute",
"arguments": {
"host": "k8s-prod",
"command": "uptime"
}
}Execute with Full Hostname
{
"tool": "ssh_execute",
"arguments": {
"host": "kubemaster01.prod.example.com",
"command": "ls -la /var/log",
"user": "admin"
}
}Dry Run Preview
{
"tool": "ssh_execute",
"arguments": {
"host": "k8s-prod",
"command": "rm -rf /tmp/logs",
"dryRun": true
}
}Kubernetes Command
{
"tool": "ssh_kubectl",
"arguments": {
"pod": "prod",
"region": "us-east",
"command": "get pods --all-namespaces"
}
}Batch Parallel Execution
{
"tool": "ssh_execute_batch",
"arguments": {
"executions": [
{
"host": "kubemaster01.prod.example.com",
"command": "uptime"
},
{
"host": "kubemaster02.prod.example.com",
"command": "uptime"
},
{
"host": "kubemaster03.prod.example.com",
"command": "uptime"
}
]
}
}Generate Hostnames
{
"tool": "generate_hosts",
"arguments": {
"nodeType": "kubenode",
"pod": "prod",
"region": "us-east",
"count": 5
}
}Connection Management
{
"tool": "ssh_connection_status",
"arguments": {}
}{
"tool": "ssh_close_connection",
"arguments": {
"host": "kubemaster01.prod.example.com"
}
}Security Features
Password Encryption
Encrypt passwords before storing them in environment variables. The encryption utility uses AES-256-GCM with a machine-specific key.
Users should implement their own password encryption utility or use the source code from this repository's scripts/encrypt-password.ts as a reference.
Authentication Methods
- SSH Key Authentication: Supports standard SSH keys with optional passphrase
- Password Authentication: Uses encrypted passwords from environment variables
- Secure Ciphers: AES-CTR, SHA2 algorithms for SSH connections
- Connection Timeouts: Prevents hanging connections
Command Confirmation
Layered confirmation system for safe execution:
- Server-Side Approval: Native dialog blocks execution (when
askUserApproval: true) - Tool Annotations: Tools marked
destructiveHint: truerequire client approval - Dry-Run Preview: Test commands without execution using
dryRun: true
Hostname Patterns
The server supports dynamic hostname generation following this pattern:
{nodeType}{number}.{pod}.{environment}.{region}.{domain}Examples:
kubemaster01.prod.env.us-east.example.comkubenode01.prod.env.us-east.example.comctrl01.prod.env.us-east.example.com
Valid Values:
- Environments: prod, staging, dev
- Regions: us-east, us-west, eu-central
- Node Types: kubemaster, kubenode, ctrl, app, db
Development
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Start development server
npm run dev
# Encrypt a password
npm run encrypt-passwordArchitecture
File Structure
src/
├── index.ts # MCP server entry point
├── config.ts # App configuration loader
├── ssh-manager.ts # SSH connection management & pooling
├── crypto-utils.ts # AES-256-GCM password encryption
├── host-generator.ts # Dynamic hostname generation
├── host-config.ts # Host alias configuration
├── logger.ts # Structured logging
├── types.ts # TypeScript interfaces
├── confirmation.ts # Command approval system
└── tool-schemas.ts # MCP tool definitions
scripts/
└── ssh-approval.vbs # Windows approval dialogKey Components
SSHConnectionManager
- Persistent connection pooling
- Automatic health monitoring
- Connection reuse for efficiency
- Graceful cleanup
HostConfigManager
- Load host aliases from
hosts.json - Resolve aliases to connection details
- Runtime configuration reload
HostGenerator
- Dynamic hostname generation
- Pattern validation
- Infrastructure mapping
Requirements
- Node.js >= 18.0.0
- SSH access to target servers
- SSH key or password authentication credentials
Error Handling
The server provides detailed error information:
- Connection failures with diagnostic messages
- Authentication errors with suggestions
- Command execution failures with exit codes
- Invalid parameter validation
- Network timeout issues
License
MIT © hbarhate
