README.md•16.1 kB
# SSH MCP Server
A Model Context Protocol (MCP) server that provides SSH session management for Claude Code with browser-based terminal monitoring.
## Features
### Core Functionality
- **Persistent SSH Sessions** - Named SSH connections that maintain state across commands
- **Interactive Terminal Interface** - Full browser-based terminal with keyboard input and command execution
- **Multi-Session Support** - Manage multiple independent SSH sessions simultaneously
- **Real-time Output Streaming** - Live terminal output via WebSocket with single clean display
- **Command History** - Track executed commands with timestamps and exit codes
- **Session Isolation** - Each session maintains separate terminal history and state
### Interactive Terminal Capabilities
- **Direct Command Input** - Type commands directly in the browser terminal interface
- **Local Echo** - Immediate character display with terminal cursor movement
- **Command Line Editing** - Full keyboard navigation (arrows, Home, End, backspace)
- **Terminal State Management** - Smart locking/unlocking based on command execution status
- **Source Attribution** - Commands from browser users vs Claude Code are properly tracked
- **Concurrent Execution** - User and Claude Code commands execute through shared SSH session with queuing
### Advanced Features
- **Multiple Authentication Methods** - SSH keys (encrypted/unencrypted), username/password, direct key content
- **Command Queuing** - FIFO execution prevents output interleaving between user and Claude Code commands
- **WebSocket Communication** - Bidirectional messaging for command execution and output streaming
- **Session State Synchronization** - Multiple browser clients stay in sync with terminal state
- **Clean Terminal Display** - Single output with preserved ANSI colors and formatting
## Installation & Setup
### Prerequisites
- Node.js 16+ and npm
- Claude Code CLI installed and configured
- SSH server access (for remote connections)
- TypeScript (for development)
### 1. Clone and Build
```bash
git clone <repository-url> ls-ssh-mcp
cd ls-ssh-mcp
npm install
npm run build
```
### 2. Register with Claude Code
```bash
# Use the installation script (recommended)
./install-mcp.sh
# Or manually register
claude mcp add ssh node /absolute/path/to/ls-ssh-mcp/dist/src/mcp-server.js
```
### 3. Verify Installation
```bash
# Check that the server was registered
claude mcp list
```
**How it works:**
- The `install-mcp.sh` script **registers** the server with Claude Code with an auto-discovered port
- Claude Code **automatically starts** the server when you use SSH tools
- No need to manually start/stop - the server runs on-demand
- Web monitoring interface is available at `http://localhost:{port}/session/{session-name}`
The installation script handles port discovery, cleanup of existing configurations, and proper registration.
## Usage
### Basic Workflow
1. **Connect to SSH server**: Use `ssh_connect` with your credentials
2. **Execute commands**: Use `ssh_exec` to run commands on the remote server
3. **Monitor sessions**: Use `ssh_get_monitoring_url` to get browser monitoring URL
4. **Manage sessions**: Use `ssh_list_sessions` and `ssh_disconnect` as needed
### Available MCP Tools
| Tool | Purpose | Required Parameters |
|------|---------|-------------------|
| `ssh_connect` | Establish SSH connection | `name`, `host`, `username`, auth method* |
| `ssh_exec` | Execute commands on remote server | `sessionName`, `command` |
| `ssh_list_sessions` | List all active SSH sessions | None |
| `ssh_get_monitoring_url` | Get browser monitoring URL | `sessionName` |
| `ssh_disconnect` | Disconnect an SSH session | `sessionName` |
\* **Authentication methods**: Choose one:
- `password` - SSH user account password
- `privateKey` - Direct private key content (+ optional `passphrase` if key is encrypted)
- `keyFilePath` - Path to private key file (+ optional `passphrase` if key is encrypted)
### Example Usage
```bash
# 1. Connect to a server (multiple authentication methods)
# Option A: Username/password authentication
ssh_connect name="myserver" host="example.com" username="user" password="pass"
# Option B: SSH key file (recommended)
ssh_connect name="myserver" host="example.com" username="user" keyFilePath="~/.ssh/id_rsa"
# Option C: SSH key file with passphrase (encrypted key)
ssh_connect name="myserver" host="example.com" username="user" keyFilePath="~/.ssh/id_ed25519" passphrase="mypassphrase"
# Option D: Direct private key content (unencrypted)
ssh_connect name="myserver" host="example.com" username="user" privateKey="-----BEGIN OPENSSH PRIVATE KEY-----..."
# Option E: Direct private key content (encrypted with passphrase)
ssh_connect name="myserver" host="example.com" username="user" privateKey="-----BEGIN OPENSSH PRIVATE KEY-----..." passphrase="keypassword"
# 2. Execute commands
ssh_exec sessionName="myserver" command="ls -la"
ssh_exec sessionName="myserver" command="htop"
# 3. Get monitoring URL for real-time terminal
ssh_get_monitoring_url sessionName="myserver"
# Returns: http://localhost:8082/session/myserver
# 4. List all active sessions
ssh_list_sessions
# 5. Disconnect when done
ssh_disconnect sessionName="myserver"
```
### Interactive Web Terminal
The browser interface provides a fully interactive terminal experience:
#### Terminal Input & Navigation
- **Direct Command Input** - Type commands directly in the terminal, just like a native SSH client
- **Local Echo** - Characters appear immediately as you type with cursor movement
- **Command Line Editing** - Use arrow keys, Home, End, and backspace for full editing
- **Terminal Locking** - Interface locks during command execution, unlocks when complete
#### Real-time Features
- **Live Output Streaming** - See command results in real-time via WebSocket
- **Concurrent Commands** - User-typed commands and Claude Code commands execute seamlessly
- **Session Synchronization** - Multiple browser windows stay synchronized
- **Command History** - Complete history with timestamps and exit codes
#### Advanced Capabilities
- **Source Attribution** - Terminal tracks whether commands came from user input or Claude Code
- **Queue Management** - Commands execute in order without output mixing
- **State Persistence** - Session state maintained across browser reconnects
- **Clean Output Display** - Single command output without duplication or formatting issues
**Usage**: Navigate to the monitoring URL and interact with the terminal exactly like a local SSH session. Type commands, press Enter, and see results instantly. Claude Code can also execute commands in the same session without interference.
## SSH Authentication Methods
The server supports multiple SSH authentication methods with automatic fallback:
### 1. SSH Key Files (Recommended)
- **Best for**: Regular usage, automated deployments, security-conscious users
- **Supports**: RSA, ED25519, ECDSA key formats
- **Encryption**: Both encrypted (with passphrase) and unencrypted keys
- **Path expansion**: Supports tilde expansion (`~/.ssh/id_rsa`)
```bash
# Unencrypted key
ssh_connect name="prod" host="server.com" username="deploy" keyFilePath="~/.ssh/id_ed25519"
# Encrypted key with passphrase
ssh_connect name="secure" host="server.com" username="admin" keyFilePath="~/.ssh/id_rsa" passphrase="mysecretpass"
```
### 2. Username/Password
- **Best for**: Quick testing, one-off connections, legacy systems
- **Security note**: Less secure than key-based authentication
```bash
ssh_connect name="test" host="server.com" username="user" password="password"
```
### 3. Direct Private Key Content (Legacy)
- **Best for**: Programmatic usage, CI/CD systems with key management
- **Note**: Requires pasting full private key content
```bash
ssh_connect name="ci" host="server.com" username="deploy" privateKey="-----BEGIN OPENSSH PRIVATE KEY-----..."
```
### Authentication Priority
1. `privateKey` (if provided) - highest priority
2. `keyFilePath` (if provided) - recommended method
3. `password` (if provided) - fallback method
## Configuration
### Environment Variables
- `SSH_TIMEOUT` - SSH operation timeout in milliseconds (default: 30000)
- `MAX_SESSIONS` - Maximum concurrent SSH sessions (default: 10)
- `LOG_LEVEL` - Logging level: 'error', 'warn', 'info', 'debug' (default: 'info')
Web server port is automatically discovered and managed by the installation script.
## Development
### Setup Development Environment
```bash
# Install dependencies
npm install
# Run in development mode with auto-reload
npm run dev
# Run tests
npm test
# Run E2E tests (requires SSH server on localhost)
npm run test:e2e
# Build for production
npm run build
# Lint code
npm run lint
```
### Testing Requirements
For running tests, you need:
- SSH server running on localhost
- Test user account: `test_user` with password `password123`
- Or configure your own test credentials in the test files
### Project Structure
```
├── src/
│ ├── mcp-server.ts # Main server orchestrator
│ ├── mcp-ssh-server.ts # MCP protocol handler
│ ├── web-server-manager.ts # Web interface server + WebSocket handlers
│ ├── ssh-connection-manager.ts # SSH session management + command queuing
│ └── types.ts # TypeScript definitions + command source types
├── static/ # Interactive xterm.js terminal interface
│ ├── terminal-input-handler.js # Browser input handling and state management
│ └── [xterm.js assets] # Terminal rendering components
├── plans/
│ ├── interactive-terminal-epic.md # Complete implementation documentation
│ └── [other planning docs] # Additional project planning
├── tests/ # Comprehensive test suite
│ ├── story*.test.ts # User story validation tests
│ ├── e2e-*.test.ts # End-to-end functionality tests
│ └── manual-tests/ # Manual testing scripts and plans
├── install-mcp.sh # Installation script
└── dist/ # Compiled output
```
## Security Considerations
- SSH sessions are kept in memory only
- Credentials are not persisted
- Web interface runs on localhost by default
- Use SSH key authentication when possible
## Architecture
### Overall Design
The SSH MCP Server implements a sophisticated architecture that seamlessly integrates Claude Code's MCP tools with interactive browser terminals:
```
┌─────────────────┐ stdio ┌─────────────────┐ WebSocket ┌─────────────────┐
│ Claude Code │◄──────────►│ MCP Server │◄──────────────►│ Browser Terminal│
└─────────────────┘ commands └─────────────────┘ bidirectional └─────────────────┘
│
▼
┌─────────────────┐
│ SSH Connection │
│ Manager │
│ (with Queue) │
└─────────────────┘
│
▼
┌─────────────────┐
│ Remote SSH │
│ Server │
└─────────────────┘
```
### Core Components
- **MCP Server**: Handles Claude Code communication via stdio protocol (no network port)
- **Web Server**: Provides interactive terminal interface via HTTP and WebSocket
- **SSH Connection Manager**: Centralized session management with command queuing
- **Interactive Terminal**: Browser-based xterm.js interface with input handling
### Key Architectural Features
#### 1. **Unified Command Execution**
- Both Claude Code tools and browser user input execute through the same SSH sessions
- Commands are queued in FIFO order to prevent output interleaving
- Source attribution tracks whether commands came from "user" or "claude"
#### 2. **Real-time Communication**
- **MCP Protocol**: stdio transport between Claude Code and server
- **WebSocket**: Bidirectional communication between browser and server
- **SSH Connection**: Persistent shell channels with streaming output
#### 3. **State Management**
- **Session Persistence**: SSH sessions maintain state across all command sources
- **Terminal Synchronization**: Multiple browser clients stay synchronized
- **Queue Management**: Commands execute sequentially with proper cleanup
### Port Management
- **MCP Communication**: Uses stdio transport only (stdin/stdout with Claude Code)
- **Web Interface**: Single auto-discovered port serves both HTTP routes and WebSocket connections
- **Port Discovery**: Installation script discovers available port and stores as `WEB_PORT` environment variable
- **URL Generation**: MCP tools return monitoring URLs pointing to the web interface
### Interactive Terminal Architecture
#### Browser-Side Components
- **xterm.js Terminal**: Renders terminal interface with full VT100 compatibility
- **Input Handler**: Manages keyboard input, local echo, and command submission
- **WebSocket Client**: Handles bidirectional communication with server
- **State Manager**: Tracks terminal lock/unlock state and command execution
#### Server-Side Processing
- **WebSocket Handler**: Processes terminal input messages from browser
- **Command Router**: Routes commands to SSH connection manager with source attribution
- **Output Broadcaster**: Streams command results back to all connected clients
- **Queue Coordinator**: Ensures proper execution order for mixed command sources
### Deployment Modes
- **Production**: Claude Code automatically starts server on-demand when SSH tools are used
- **Development**: Manual testing with independent port discovery
- **Interactive Mode**: Browser clients can connect and interact with existing SSH sessions
### Data Flow
1. **Claude Code Command**: `ssh_exec` → MCP Server → SSH Manager → Queue → SSH Session
2. **Browser Command**: Terminal Input → WebSocket → Web Server → SSH Manager → Queue → SSH Session
3. **Output Streaming**: SSH Session → SSH Manager → WebSocket → Browser Terminal
4. **State Updates**: Command completion → Terminal unlock (for user commands only)
## Troubleshooting
### Common Issues
**Server not starting after registration:**
```bash
# Check if Claude Code recognizes the server
claude mcp list
# Verify build exists
ls -la dist/src/mcp-server.js
# Test the server directly
node dist/src/mcp-server.js
```
**Port conflicts:**
```bash
# Re-run installation to discover new port
./install-mcp.sh
# Verify new configuration
claude mcp get ssh
```
**SSH connection failures:**
- Verify SSH server is running and accessible
- Check credentials (username/password or privateKey)
- Ensure SSH server allows password authentication if using passwords
**Web interface not accessible:**
- Use `ssh_get_monitoring_url` to get the correct URL with current port
- Check that the server is running: `ps aux | grep mcp-server`
### Logs and Debugging
```bash
# Enable debug logging when using Claude Code
export LOG_LEVEL=debug
# Check MCP server configuration
claude mcp get ssh
# Test server manually with debug output
LOG_LEVEL=debug node dist/src/mcp-server.js
```
## License
MIT License - see [LICENSE](LICENSE) file for details.