A Rust MCP (Model Context Protocol) server for SSH/SFTP remote shell execution and file transfer. This allows AI agents to execute commands on remote hosts as easily as executing local shell commands.
- SSH Command Execution: Execute shell commands on remote hosts via SSH
- SFTP File Transfer: Upload and download files to/from remote hosts
- SSH Config Support: Uses your existing
~/.ssh/configfile for host configurations - Key-based Authentication: Supports SSH key-based authentication (no password auth)
- Connection Pooling: Maintains connections for efficient repeated operations
- SSH Key Setup: Ensure SSH key-based authentication is configured for your target hosts
- SSH Config: Configure your hosts in
~/.ssh/config(optional but recommended) - SFTP Enabled: For file transfer, ensure SFTP is enabled on the remote server (
Subsystem sftp internal-sftpin sshd_config)
cargo install --path .Or build from source:
cargo build --releaseThe binary will be at target/release/mcp-secure-shell.
Add to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"ssh": {
"command": "/path/to/mcp-secure-shell",
"args": []
}
}
}Execute a shell command on a remote host.
Parameters:
host(required): SSH host alias from~/.ssh/configor direct hostnamecommand(required): Shell command to executecwd(optional): Working directory to run the command from
Example:
{
"host": "myserver",
"command": "ls -la /var/log",
"cwd": "/home/user"
}Upload a local file to a remote host.
Parameters:
host(required): SSH host alias or hostnamelocal_path(required): Path to the local fileremote_path(required): Destination path on the remote host
Example:
{
"host": "myserver",
"local_path": "/tmp/myfile.txt",
"remote_path": "/home/user/myfile.txt"
}Download a file from a remote host.
Parameters:
host(required): SSH host alias or hostnameremote_path(required): Path to the file on the remote hostlocal_path(required): Destination path on the local machine
Example:
{
"host": "myserver",
"remote_path": "/var/log/app.log",
"local_path": "/tmp/app.log"
}List all SSH hosts configured in ~/.ssh/config.
Parameters: None
Get connection details for a specific SSH host.
Parameters:
host(required): SSH host alias to get info for
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User admin
Port 22
IdentityFile ~/.ssh/id_ed25519
Host devbox
HostName dev.example.com
User developer
IdentityFile ~/.ssh/id_rsa
RUST_LOG: Set logging level (e.g.,RUST_LOG=mcp_secure_shell=debug)
- This server executes commands on remote hosts with the permissions of the configured SSH user
- Only key-based authentication is supported (no password authentication)
- Host keys are verified against
~/.ssh/known_hostsby default - Be cautious about which hosts are configured and accessible
- Connection timeout is set to 30 seconds to prevent hanging
cargo buildUnit tests:
cargo testIntegration tests (requires Docker):
-
Start the test SSHD container:
./scripts/test-sshd.sh start
-
Run integration tests:
cargo test --test integration_test -
Stop the container when done:
./scripts/test-sshd.sh stop
The project includes a Docker-based test environment using panubo/sshd, a minimal Alpine Linux image with OpenSSH.
Container management:
./scripts/test-sshd.sh start # Start container
./scripts/test-sshd.sh stop # Stop container
./scripts/test-sshd.sh status # Check status
./scripts/test-sshd.sh test # Test SSH connection
./scripts/test-sshd.sh logs # View logs
./scripts/test-sshd.sh shell # Open shell in containerEnvironment variables:
SSH_PORT: Port to expose SSHD on (default: 2222)TEST_SSH_HOST: Host for integration tests (default: localhost)TEST_SSH_PORT: Port for integration tests (default: 2222)TEST_SSH_USER: User for integration tests (default: root)
Docker Compose alternative:
docker compose -f docker-compose.test.yml up -dAfter starting the test container, add this to ~/.ssh/config:
Host test-container
HostName localhost
Port 2222
User root
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Then test the MCP server with the test-container host.
MIT