BlockSecCA/generic-ssh-mcp
If you are the rightful owner of generic-ssh-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
A flexible MCP server for executing commands on remote servers via SSH with optional command wrappers.
Generic SSH MCP
A flexible MCP server for executing commands on remote servers via SSH with optional command wrappers.
Features
- Persistent SSH Connection: Fast command execution using ssh2 library
- Configurable Wrapper: Optional command wrapper for sandboxing, timeouts, or other control
- Configurable Tool Name: Custom tool name per instance for easy identification in Claude UI
- Multiple Systems: Build separate packages for different target systems
- Simple Tool Interface: Single tool with string parameter
Quick Start
1. Build for your target system
./build.sh ssh-ubuntupc
This creates ssh-ubuntupc.mcpb which you can install in Claude Desktop. The tool will appear as "ssh-ubuntupc" in the Claude UI.
2. Install in Claude Desktop
- Transfer the
.mcpbfile to Windows - Double-click to install
- Configure:
- SSH Host:
192.168.1.70(use IP address, not hostname) - SSH Username:
YourUsername - SSH Private Key Path:
C:\Users\YourUsername\.ssh\id_ed25519 - Command Timeout:
30(seconds) - Command Wrapper: leave empty for direct execution, or
srtfor sandboxing - Tool Name:
ssh-ubuntupc(auto-populated, helps distinguish multiple SSH servers)
- SSH Host:
3. Use in Claude
Using ssh-ubuntupc, run: ls -la /home/YourUsername
Tool Name Configuration
When running multiple SSH MCP servers (e.g., one for each remote system), the tool name helps distinguish them in the Claude UI.
The build script automatically sets the tool name to match the package name:
./build.sh ssh-kali # Tool appears as "ssh-kali" in Claude UI
./build.sh ssh-ubuntupc # Tool appears as "ssh-ubuntupc" in Claude UI
Without this, all instances would show as "command" making them indistinguishable.
Command Wrapper
The wrapper field allows you to control how commands execute:
No wrapper (empty string):
- Commands execute directly via bash
- Fast, unrestricted
- Use for trusted environments
With srt wrapper:
- Commands sandboxed with kernel-level restrictions
- Requires SRT installed on remote system
- Filesystem and network policy enforcement
- See INSTALLATION.md for SRT setup
With timeout N wrapper:
- Commands limited to N seconds
- Automatic termination on timeout
- Useful for potentially long-running commands
With nice -n N wrapper:
- Commands run at lower priority
- Less impact on system load
Custom wrappers:
- Any command that accepts a command string
- Example:
strace -e trace=filefor debugging
[!WARNING] Command Wrapper Configuration: For direct bash execution, leave the wrapper field empty or use a single space
" ". Never use"bash"as the wrapper - this creates a double bash invocation (wrapper bash + SSH daemon bash) causing command failures.
Multiple Systems
Build a package for each system you want to connect to:
./build.sh ssh-ubuntupc # Creates ssh-ubuntupc.mcpb
./build.sh ssh-kali # Creates ssh-kali.mcpb
./build.sh ssh-pihole # Creates ssh-pihole.mcpb
./build.sh ssh-prodserver # Creates ssh-prodserver.mcpb
Each package is independent with its own configuration in Claude Desktop. Each will display with its own name in the Claude UI for easy identification.
Architecture
graph TD
subgraph "Windows Machine"
Claude[Claude Desktop App]
MCP[MCP Server<br/>Node.js Process]
SSH2[SSH2 Library<br/>Persistent Connection]
Claude -->|MCP Protocol<br/>stdio| MCP
MCP -->|uses| SSH2
end
subgraph "Ubuntu Server ubuntupc"
SSH_Daemon[SSH Daemon<br/>sshd]
Wrapper[Optional Wrapper<br/>srt/timeout/direct]
Shell[Bash Shell]
SSH_Daemon -->|spawns| Shell
Shell -->|may wrap via| Wrapper
Wrapper -->|executes| Commands[Commands & Programs]
end
SSH2 -->|SSH Connection<br/>Port 22<br/>PERSISTENT| SSH_Daemon
SSH_Daemon -->|stdout/stderr| SSH2
SSH2 -->|results| MCP
MCP -->|JSON-RPC| Claude
style Claude fill:#e1f5ff
style MCP fill:#fff4e1
style SSH2 fill:#ffe1e1
style SSH_Daemon fill:#e1ffe1
style Wrapper fill:#fff9e1
style Shell fill:#f0f0f0
Claude Desktop (Windows)
→ MCP Server (Node.js on Windows)
→ SSH2 library
→ SSH connection to remote server
→ [Optional wrapper command]
→ Actual command execution
Example with SRT wrapper:
User asks: "list files"
→ Tool call: command(command="ls -la")
→ Server wraps: srt 'ls -la'
→ SSH executes on remote: srt 'ls -la'
→ SRT applies policy, spawns bubblewrap
→ Sandboxed bash executes: ls -la
Tool Definition
Name: Configurable via tool_name parameter (defaults to package name)
Parameters:
command(string, required): The command to execute
Behavior:
- Checks for interactive commands (rejects vim, top, sudo without args, etc.)
- Applies wrapper if configured
- Executes via persistent SSH connection
- Returns stdout, stderr, and exit code
Files
manifest.json- MCP package definitionserver/index.js- MCP server implementationpackage.json- Node.js dependenciesbuild.sh- Build script for creating named packagesINSTALLATION.md- Detailed setup guide (SRT-focused)COMPARISON.md- Standard vs SRT comparisonQUICKSTART.md- 5-minute setup
Security with SRT
When using the srt wrapper:
- Install prerequisites on remote system:
sudo apt install bubblewrap
sudo chmod u+s /usr/bin/bwrap
npm install -g @anthropic-ai/sandbox-runtime
- Create policy file (
~/.srt-settings.json):
{
"filesystem": {
"denyRead": ["~/.ssh/id_rsa", "~/.ssh/id_ed25519", "~/.srt-settings.json"],
"allowWrite": ["~/projects", "/tmp"],
"denyWrite": ["/etc", "/usr", "~/.ssh", "~/.srt-settings.json"]
},
"network": {
"allowedDomains": ["github.com", "pypi.org"],
"deniedDomains": []
}
}
- Test SRT:
srt 'ls -la' # Should work
srt 'cat ~/.ssh/id_ed25519' # Should be blocked
⚠️ Critical SRT Security Warning
Default SRT configuration has a security vulnerability: SRT does not block access to its own config file by default. Without proper configuration, Claude can modify ~/.srt-settings.json to escape the sandbox.
Required protection:
{
"filesystem": {
"denyRead": ["~/.srt-settings.json"],
"denyWrite": ["~/.srt-settings.json"]
}
}
Verification test:
# This should be BLOCKED
srt 'cat ~/.srt-settings.json'
srt 'echo "malicious" >> ~/.srt-settings.json'
If these commands succeed, your sandbox is compromised. SRT must deny both read and write access to its own configuration file to prevent escape.
Reference: See Anthropic Sandbox Runtime for more details on SRT configuration and security considerations.
See INSTALLATION.md for complete setup instructions.
Version History
-
3.1.0 - Configurable tool name
- Added
--tool-nameparameter for custom tool names in Claude UI - Build script auto-sets tool name to match package name
- Helps distinguish multiple SSH server instances
- Added
-
3.0.0 - Generic SSH with configurable wrapper
- Tool renamed from
bashtocommand - Added configurable wrapper field
- Build script for creating multiple named packages
- Tool renamed from
-
2.1.0 - SRT-specific version (deprecated)
- Hardcoded SRT wrapper
-
2.0.0 - Persistent SSH2 connection
- Original ubuntu-shell-mcp with SSH2
License
MIT License
Author
Carlos - BlockSecCA