SSH Liaison
БесплатноНе проверенProvides secure remote server access and command execution through SSH connections with persistent shell sessions.
Описание
Provides secure remote server access and command execution through SSH connections with persistent shell sessions.
README
Stateful SSH connection and command execution via Model Context Protocol (MCP)
✨ Features
| Feature | Description |
|---|---|
| 🔄 Stateful Sessions | Core feature: Shell state (current directory, environment variables, working directory) is preserved between MCP tool calls. Each command runs in the same persistent shell session, allowing multi-step workflows. |
| 🔌 MCP Server Mode | Integrate with Cursor/Claude Desktop for AI-assisted SSH operations with stateful command execution |
| ⚙️ SSH Config Support | Uses ~/.ssh/config for host aliases and connection parameters |
| 🔐 Direct Connection | Connect directly using user/hostname/password/port without SSH config requirement |
| 💻 Standalone CLI Mode | Interactive terminal for debugging and testing (see below) |
📦 Installation
Pre-built Binaries
Download the latest release for your platform from the Releases page.
Available platforms:
- macOS (Intel x86_64, Apple Silicon aarch64)
- Linux (x86_64, aarch64)
- Windows (x86_64)
# macOS (Apple Silicon)
curl -LO https://github.com/Citizen4our/ssh-liaison-mcp/releases/latest/download/ssh-liaison-mcp-aarch64-apple-darwin.tar.gz
tar -xzf ssh-liaison-mcp-aarch64-apple-darwin.tar.gz
# macOS (Intel)
curl -LO https://github.com/Citizen4our/ssh-liaison-mcp/releases/latest/download/ssh-liaison-mcp-x86_64-apple-darwin.tar.gz
tar -xzf ssh-liaison-mcp-x86_64-apple-darwin.tar.gz
# Linux (x86_64)
curl -LO https://github.com/Citizen4our/ssh-liaison-mcp/releases/latest/download/ssh-liaison-mcp-x86_64-unknown-linux-gnu.tar.gz
tar -xzf ssh-liaison-mcp-x86_64-unknown-linux-gnu.tar.gz
Build from Source
git clone https://github.com/Citizen4our/ssh-liaison-mcp.git
cd ssh-liaison-mcp
cargo build --release
The binary will be located at target/release/ssh-liaison-mcp.
🚀 Usage
MCP Server Mode (Primary Use Case)
The main feature of this server is stateful SSH sessions - each SSH connection maintains a persistent shell session where state (current directory, environment variables, etc.) is preserved between MCP tool calls. This enables natural multi-step workflows where commands build upon each other.
How Stateful Sessions Work
When you connect to a host via ssh_connect, a persistent shell session is established. All subsequent ssh_run_command calls for that host execute in the same shell session, meaning:
- Current directory is preserved: If you
cd /var/login one command, the next command starts from/var/log - Environment variables persist: Variables set with
exportremain available in subsequent commands - Shell state is maintained: History, aliases, and other shell state persist between calls
- Efficient: No need to reconnect or re-establish context for each command
Example workflow:
1. ssh_connect("production") → Establishes persistent shell
2. ssh_run_command("production", "cd /var/log") → Changes directory
3. ssh_run_command("production", "pwd") → Returns "/var/log" (state preserved!)
4. ssh_run_command("production", "ls -la") → Lists files in /var/log
For Cursor IDE
Build the binary:
cargo build --releaseAdd to Cursor settings (
~/.cursor/mcp.jsonor Cursor settings UI):{ "mcpServers": { "ssh-liaison": { "command": "/absolute/path/to/ssh-liaison-mcp", "args": ["serve"] } } }Restart Cursor
For Claude Desktop
Build the binary:
cargo build --releaseAdd to Claude Desktop config (
~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS):{ "mcpServers": { "ssh-liaison": { "command": "/absolute/path/to/ssh-liaison-mcp", "args": ["serve"] } } }Restart Claude Desktop
Legacy Direct Connect Mode
For backward compatibility:
cargo run -- connect <user> <host> [--port <port>]
🔧 SSH Configuration
The server reads from ~/.ssh/config for host aliases. This is the recommended way to connect as it centralizes connection settings.
Example SSH Config
# Simple host alias
Host rpi
HostName 192.168.1.100
User pi
Port 22
IdentityFile ~/.ssh/id_ed25519
# Production server with custom port
Host production
HostName prod.example.com
User deploy
Port 2222
IdentityFile ~/.ssh/deploy_key
# Development server
Host dev
HostName dev.example.com
User developer
IdentityFile ~/.ssh/id_rsa
🛠️ MCP Tools
When running as MCP server, the following tools are available:
| Tool | Description | Parameters |
|---|---|---|
| ssh_connect | Connect to remote SSH server and establish a persistent shell session. The session maintains state between subsequent command calls. | host_alias (string) - Host alias defined in SSH config |
| ssh_connect_direct | Connect to remote SSH server directly using user, hostname/IP, optional password, and optional port. Establishes a persistent shell session that maintains state between subsequent command calls. Authentication tries SSH keys first, then password if provided. | host_alias (string) - Host alias to identify this connection, user (string) - SSH username, hostname (string) - Hostname or IP address, password (string, optional) - SSH password (if SSH keys fail or not available), port (integer, optional) - SSH port (default: 22) |
| ssh_run_command | Execute command in a persistent shell. Auto-connects via SSH config or a registered direct profile. Idle/max timeouts configurable. | host, command, optional sudo_password, timeout_secs, max_timeout_secs |
| ssh_run_detached | Run a long command in the background (tmux or native). Returns job_id. |
host, command |
| ssh_job_status | Non-blocking status and new output of a detached job. | host, job_id |
| ssh_job_wait | Block until job finishes or timeout. | host, job_id, optional timeout_secs |
| ssh_job_signal | Send int, term, or kill to a detached job worker. |
host, job_id, signal |
| ssh_read_log | Read last N lines from a log file. Auto-connects when needed. | host, file_path, lines |
Important Notes:
- Stateful (same MCP process): Commands for the same host share one shell session;
cdand env persist until the MCP server process restarts. - Auto-connect:
ssh_run_command, detached tools, andssh_read_logconnect automatically via~/.ssh/configor a profile saved byssh_connect_directin the same process. - Multi-process MCP clients: Each tool call may run in a fresh process — shell state does not carry over, but auto-connect still works for SSH-config and direct profiles registered in that process.
- Long commands: Prefer
ssh_run_detachedwhen runtime may exceed command timeouts. - Connection Methods:
- Use
ssh_connectfor SSH config-based connections (requires~/.ssh/config) - Use
ssh_connect_directfor direct connections without SSH config requirement
- Use
- Authentication Order (for
ssh_connect_direct):- SSH keys (SSH agent, then common key files)
- Password (if provided and SSH keys fail)
- Session Persistence: Once connected, the session remains active until the MCP server is restarted or explicitly disconnected
- Security: Passwords in
ssh_connect_directare transmitted securely over SSH protocol (encrypted). SSH key authentication is preferred when available.
Example Prompts for MCP Mode
Once the MCP server is configured, you can ask the AI assistant to perform SSH operations:
Example 1:
User: Connect to rpi and show me the current directory and disk usage
AI Response:
I'll connect to rpi and check the current directory and disk usage for you.
[Connecting to rpi...]
Current directory: /home/pi
Disk usage:
Filesystem Size Used Avail Use% Mounted on
/dev/root 15G 5.2G 8.8G 38% /
/dev/mmcblk0p1 253M 49M 204M 20% /boot
Example 2:
User: Connect to production and read the last 50 lines from /var/log/nginx/error.log
AI Response:
I'll connect to production and read the last 50 lines from the nginx error log.
[Connecting to production...]
Last 50 lines from /var/log/nginx/error.log:
2024-01-15 10:23:45 [error] 12345#0: *123 connect() failed (111: Connection refused)
2024-01-15 10:24:12 [error] 12345#0: *124 upstream timed out
...
Example 3:
User: Connect directly to 192.168.88.63 as user pi and show disk usage
AI Response:
I'll connect directly to 192.168.88.63 as user pi and check the disk usage.
[Connecting to 192.168.88.63 using SSH keys...]
Disk usage:
Filesystem Size Used Avail Use% Mounted on
/dev/root 15G 5.2G 8.8G 38% /
/dev/mmcblk0p1 253M 49M 204M 20% /boot
Example 3b (with password):
User: Connect to 192.168.88.63 as user admin with password mypass123 and check uptime
AI Response:
I'll connect to 192.168.88.63 as user admin and check the system uptime.
[Connecting to 192.168.88.63...]
[SSH key authentication failed, trying password...]
System uptime: 5 days, 12 hours, 30 minutes
Example 4:
User: Check system uptime and memory usage on the dev server
AI Response:
I'll check the system uptime and memory usage on the dev server.
[Connecting to dev...]
System uptime: 15 days, 3 hours, 22 minutes
Memory usage:
total used free shared buff/cache available
Mem: 7.8G 2.1G 3.2G 128M 2.5G 5.4G
Swap: 2.0G 0B 2.0G
Example 5:
User: Show me running processes and check if nginx service is running on production
AI Response:
I'll check the running processes and verify if nginx is running on production.
[Connecting to production...]
Nginx service status: active (running)
Top processes by CPU:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 nginx 20 0 123456 4567 1234 S 2.3 0.1 0:05:23 nginx
5678 app 20 0 234567 8901 2345 S 1.8 0.2 0:12:45 app
...
Stateful Session Example
This example demonstrates how state is preserved between commands:
User: Connect to rpi, navigate to /var/log, and show me the last 10 lines of syslog
AI Response:
I'll connect to rpi, navigate to /var/log, and show you the last 10 lines of syslog.
[Connecting to rpi...]
[Changing directory to /var/log...]
Last 10 lines of syslog:
Jan 15 10:23:45 rpi systemd[1]: Started Network Manager.
Jan 15 10:24:12 rpi sshd[1234]: Accepted publickey for pi from 192.168.1.50
...
What happened behind the scenes:
ssh_connect("rpi")- Established persistent shell sessionssh_run_command("rpi", "cd /var/log")- Changed directory (state saved)ssh_run_command("rpi", "tail -n 10 syslog")- Executed from/var/log(state preserved!)
The second command automatically started from /var/log because the shell state was preserved from the previous command.
Standalone CLI Mode (For Debugging)
Interactive terminal mode for testing and debugging. Useful for troubleshooting connection issues or testing commands manually.
Connection Methods
1. Using SSH Config Alias
# Connect immediately using alias from ~/.ssh/config
cargo run -- cli --host rpi
# or
./target/release/ssh-liaison-mcp cli --host rpi
2. Direct Connection via Command Line
# Direct connection with SSH keys (default port 22)
cargo run -- cli --user pi --hostname 192.168.1.100
# Direct connection with custom port
cargo run -- cli --user pi --hostname 192.168.1.100 --port 2222
# Direct connection with password authentication
cargo run -- cli --user pi --hostname 192.168.1.100 --password mypassword
# Direct connection with password and custom port
cargo run -- cli --user pi --hostname 192.168.1.100 --password mypassword --port 2222
Connection Examples
# Example 1: Connect via SSH config
cargo run -- cli --host production
# Example 2: Direct connection to Raspberry Pi
cargo run -- cli --user pi --hostname 192.168.1.100
# Example 3: Direct connection with password to custom port
cargo run -- cli --user admin --hostname server.example.com --password secret --port 2222
# Example 4: Interactive mode - connect later
cargo run -- cli
ssh> connect dev-server
[dev-server]> uname -a
[dev-server]> exit
🔐 Authentication
For ssh_connect (SSH Config)
The server attempts authentication in the following order:
- SSH agent (if available)
- Identity file from SSH config
- Common SSH keys (in order):
~/.ssh/id_ed25519~/.ssh/id_rsa~/.ssh/id_ecdsa~/.ssh/id_dsa
For ssh_connect_direct (Direct Connection)
- SSH keys (same order as above)
- Password (if provided and SSH keys fail or are not available)
⚠️ Security Notes
- Read-only operations recommended: The tools include warnings about destructive operations
- Password handling: Sudo password elicitation support is planned but not yet fully implemented
- No password logging: Passwords are never logged or exposed
🧪 Development
# Run in development mode
cargo run -- cli --host <your-host>
# Build release
cargo build --release
# Run tests
cargo test
# Run lints
cargo clippy --all-targets -- -D warnings
# Format code
cargo fmt
📊 Logging
The server uses structured logging via the tracing crate. Control log verbosity with:
SSH agent (Cursor / GUI)
Cursor often spawns MCP without SSH_AUTH_SOCK. Passphrase-protected keys then fail file auth (Wrong passphrase…), while terminal ssh still works via the agent.
ssh-liaison-mcp ≥ 0.2.2 discovers the agent socket via launchctl getenv SSH_AUTH_SOCK (macOS) and /tmp/ssh-*/agent.* before userauth_agent. After upgrading, restart the MCP server in Cursor so it loads the new binary.
Command-line flags
# Default (warnings only)
ssh-liaison-mcp serve
# Info level (-v)
ssh-liaison-mcp -v serve
# Debug level (-vv)
ssh-liaison-mcp -vv serve
# Trace level (-vvv)
ssh-liaison-mcp -vvv serve
Environment variable
# Set log level via RUST_LOG
RUST_LOG=debug ssh-liaison-mcp serve
# Target specific modules
RUST_LOG=ssh_liaison_mcp=debug ssh-liaison-mcp serve
# Multiple targets
RUST_LOG=ssh_liaison_mcp::ssh=trace,ssh_liaison_mcp::mcp=debug ssh-liaison-mcp serve
📋 TODO / Future Improvements
Infrastructure & Distribution
CI/CD Pipeline (GitHub Actions)
- Automated tests on push/PR
- Linting and formatting checks (clippy, rustfmt)
- Build for multiple platforms (Linux, macOS, Windows)
- Automated release workflow
Release Automation
- GitHub Actions workflow for creating releases
- Automatic binary builds for major platforms
- GitHub Releases with pre-built binaries
- Version bumping automation
Crates.io Publication
- Prepare crate metadata (description, keywords, categories)
- Add crate documentation
- Publish to crates.io
Features
Sudo Password Elicitation
- MCP prompt when password not provided (interactive elicitation)
- Password caching for session duration
Session Management
-
ssh_disconnecttool to explicitly close sessions -
ssh_list_sessionstool to show active connections - Automatic session cleanup on timeout
- Session health checks and reconnection
-
Enhanced Error Handling
- Better error messages with context
- Connection retry logic
- Graceful handling of network interruptions
- Session recovery mechanisms
File Operations
-
ssh_read_filetool for reading remote files -
ssh_write_filetool (with safety checks) -
ssh_list_directorytool for directory listings - Support for binary file transfers
-
Monitoring & Observability
- Connection status monitoring
- Optional verbose logging mode
Code Quality
Testing
- Unit tests for SSH config parsing
- Integration tests for MCP tools
- Mock SSH server for testing
- CLI mode tests
Documentation
- API documentation (rustdoc)
- Architecture documentation
- Contributing guidelines
- Security best practices guide
Code Improvements
- Refactor error handling patterns
- Add comprehensive logging (tracing)
- Performance optimizations
- Code coverage improvements
Platform Support
Cross-platform Binary Releases
- Linux (x86_64, ARM64)
- macOS (Intel, Apple Silicon)
- Windows (x86_64)
Package Managers
- Homebrew formula for macOS
- AUR package for Arch Linux
Security Enhancements
Security Audit
- Dependency security scanning
- Code security review
- Penetration testing considerations
Access Control
- Optional host allowlist/denylist
- Command whitelisting/blacklisting
- Rate limiting for connections
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
Установка SSH Liaison
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/citizen4our/ssh-liaison-mcpFAQ
SSH Liaison MCP бесплатный?
Да, SSH Liaison MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для SSH Liaison?
Нет, SSH Liaison работает без API-ключей и переменных окружения.
SSH Liaison — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить SSH Liaison в Claude Desktop, Claude Code или Cursor?
Открой SSH Liaison на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare SSH Liaison with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
