ssh-mcp

frah/ssh-mcp

3.1

If you are the rightful owner of 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 Model Context Protocol (MCP) server that provides secure SSH control for Linux and Windows servers.

Tools
4
Resources
0
Prompts
0

SSH MCP Server

A Model Context Protocol (MCP) server that provides secure SSH control for Linux and Windows servers. Execute remote shell commands, transfer files, and manage multiple server connections through a standardized MCP interface.

Features

  • Multiple Authentication Methods: Password and SSH key authentication
  • Multi-hop SSH Support: Connect through multiple jump hosts/bastions
  • File Operations: Upload and download files via SFTP
  • Security Controls: Command whitelist/blacklist configuration
  • Connection Pooling: Efficient connection management and reuse
  • TypeScript: Full type safety and modern JavaScript features
  • Bun Runtime: Fast execution and built-in TypeScript support

Installation

Prerequisites

  • Bun runtime installed
  • Node.js 18+ (for compatibility)

Quick Start (using bunx)

Run directly without installation:

# Generate example config file
bunx @frah/ssh-mcp --example-config > config.json

# Run with default config (./config.json)
bunx @frah/ssh-mcp

# Run with custom config file
bunx @frah/ssh-mcp --config /path/to/your/config.json

# Show help
bunx @frah/ssh-mcp --help

Local Setup

  1. Clone the repository:
git clone https://github.com/frah/ssh-mcp.git
cd ssh-mcp
  1. Install dependencies:
bun install
  1. Copy and configure the example config:
cp config.example.json config.json
# Edit config.json with your server details

Configuration

Create a config.json file based on the provided example:

{
  "connections": [
    {
      "id": "dev-server",
      "host": "192.168.1.100",
      "port": 22,
      "username": "developer",
      "password": "your-password",
      "description": "Development environment server",
      "commandWhitelist": ["^ls", "^cat", "^grep"],
      "timeout": 30000
    },
    {
      "id": "prod-server",
      "host": "prod.example.com",
      "username": "admin",
      "privateKeyPath": "/path/to/key",
      "commandBlacklist": ["^rm", "^dd"]
    }
  ],
  "globalSettings": {
    "maxConnections": 10,
    "defaultTimeout": 30000,
    "idleTimeout": 60000
  }
}

Connection Configuration Options

  • id: Unique identifier for the connection
  • host: Server hostname or IP address
  • port: SSH port (default: 22)
  • username: SSH username
  • password: Password authentication (optional)
  • privateKey: Private key content as string (optional)
  • privateKeyPath: Path to private key file (optional)
  • passphrase: Private key passphrase (optional)
  • description: Human-readable description of the connection (optional)
  • proxy: Array of proxy configurations for multi-hop connections
  • commandWhitelist: Regex patterns for allowed commands
  • commandBlacklist: Regex patterns for blocked commands
  • timeout: Command execution timeout in milliseconds

Global Settings Options

  • defaultTimeout: Default command execution timeout in milliseconds
  • maxConnections: Maximum number of concurrent SSH connections
  • idleTimeout: SSH connection idle timeout in milliseconds (default: 60000)
  • commandWhitelist: Global regex patterns for allowed commands
  • commandBlacklist: Global regex patterns for blocked commands

Multi-hop SSH Configuration

For connections through bastion hosts:

{
  "id": "internal-server",
  "host": "10.0.1.50",
  "username": "app-user",
  "privateKeyPath": "/path/to/key",
  "proxy": [
    {
      "host": "bastion.example.com",
      "username": "bastion-user",
      "privateKeyPath": "/path/to/bastion/key"
    }
  ]
}

Usage

Running the Server

Using bunx (No Installation Required)
# Run with default config (./config.json)
bunx @frah/ssh-mcp

# Run with custom config file
bunx @frah/ssh-mcp --config /path/to/your/config.json
From Source

Start the MCP server (Bun natively supports TypeScript):

bun run dev
# or directly
bun src/index.ts
Production Build

For production deployment with Node.js:

bun run build
node dist/index.js

Command Line Options

  • -c, --config <path>: Specify path to configuration file (default: ./config.json)
  • -h, --help: Show help message
  • -v, --version: Show version number
  • --example-config: Output example configuration JSON to stdout

Examples:

ssh-mcp                                    # Start with default config
ssh-mcp --config /etc/ssh-mcp/config.json # Use custom config path
ssh-mcp --example-config > config.json    # Generate config file
ssh-mcp --help                            # Show help information
ssh-mcp --version                         # Show version

Available MCP Tools

1. ssh_execute

Execute commands on remote servers.

Parameters:

  • connectionId (string): Connection ID from config
  • command (string): Command to execute
  • timeout (number, optional): Timeout in milliseconds

Example:

{
  "tool": "ssh_execute",
  "arguments": {
    "connectionId": "dev-server",
    "command": "ls -la /var/log",
    "timeout": 5000
  }
}
2. ssh_upload

Upload files to remote server via SFTP.

Parameters:

  • connectionId (string): Connection ID from config
  • localPath (string): Local file path
  • remotePath (string): Remote destination path

Example:

{
  "tool": "ssh_upload",
  "arguments": {
    "connectionId": "dev-server",
    "localPath": "/local/file.txt",
    "remotePath": "/remote/file.txt"
  }
}
3. ssh_download

Download files from remote server via SFTP.

Parameters:

  • connectionId (string): Connection ID from config
  • remotePath (string): Remote file path
  • localPath (string): Local destination path

Example:

{
  "tool": "ssh_download",
  "arguments": {
    "connectionId": "dev-server",
    "remotePath": "/remote/log.txt",
    "localPath": "/local/log.txt"
  }
}
4. ssh_list_servers

List all configured SSH server definitions.

Parameters: None

Returns: Array of server configurations with:

  • id: Connection identifier
  • host: Server hostname
  • port: SSH port number
  • username: SSH username
  • description: Human-readable description (if configured)

Example:

{
  "tool": "ssh_list_servers",
  "arguments": {}
}

Response Example:

[
  {
    "id": "dev-server",
    "host": "192.168.1.100",
    "port": 22,
    "username": "developer",
    "description": "Development environment server"
  },
  {
    "id": "prod-server",
    "host": "prod.example.com",
    "port": 22,
    "username": "admin",
    "description": ""
  }
]

Security Features

Command Filtering

The server supports both whitelist and blacklist patterns for commands:

  • Whitelist: Only commands matching these patterns are allowed
  • Blacklist: Commands matching these patterns are blocked
  • Patterns are evaluated as regular expressions
  • Connection-specific rules override global rules

Built-in Dangerous Command Protection

The following dangerous commands are always blocked:

  • rm -rf / and variants
  • Disk formatting commands
  • Fork bombs
  • Direct disk write operations

Path Sanitization

All file paths are automatically sanitized to prevent directory traversal attacks.

Claude Code Integration

To use this MCP server with Claude Code, follow these steps:

1. Configure Claude Code

Add the MCP server to your Claude Code configuration file:

Configuration File Location:

Option A: Global Configuration

  • Linux/macOS: ~/.claude.json
  • Windows: %USERPROFILE%\.claude.json

Option B: Project-Specific Configuration Create .claude/settings.local.json in your project directory.

Configuration Example:

Using bunx (Recommended - No Installation Required):

{
  "mcpServers": {
    "ssh-mcp": {
      "command": "bunx",
      "args": ["@frah/ssh-mcp", "--config", "/absolute/path/to/your/config.json"]
    }
  }
}

Using Local Installation:

{
  "mcpServers": {
    "ssh-mcp": {
      "command": "bun",
      "args": ["run", "/absolute/path/to/ssh-mcp/src/index.ts", "--config", "/absolute/path/to/your/config.json"]
    }
  }
}

Example for Windows:

{
  "mcpServers": {
    "ssh-mcp": {
      "command": "bunx",
      "args": ["@frah/ssh-mcp", "--config", "C:\\Users\\YourName\\ssh-mcp-config.json"]
    }
  }
}

Important Notes:

  • When using bunx, you only need to specify the config file path
  • The config file path in --config must be absolute, not relative
  • bunx will automatically download and run the latest version of ssh-mcp

2. Create Configuration File

Ensure you have a config.json file in the ssh-mcp directory:

cd /absolute/path/to/ssh-mcp
cp config.example.json config.json
# Edit config.json with your server details

3. Verify Configuration

You can verify the MCP server is properly configured by running:

# Test the server directly
bun run /absolute/path/to/ssh-mcp/src/index.ts

# Or inside Claude Code, use the slash command
/mcp

If the server starts successfully, you should see log messages indicating the server is running.

4. Restart Claude Code

After configuring the MCP server, restart Claude Code to load the new configuration.

5. Usage in Claude Code

Once configured, you can use the SSH tools in Claude Code conversations:

Example commands:

  • "Show me the list of available SSH servers"
  • "Execute ls -la on my development server"
  • "Upload the local file app.log to /var/log/app.log on production"
  • "Download /etc/nginx/nginx.conf from the web server to my local machine"

With the ssh_list_servers tool, Claude can automatically discover available connections and select the appropriate server based on your natural language description.

Alternative: Using Node.js

If you prefer to use Node.js instead of Bun, you need to first build the project:

bun run build

Then configure it as:

{
  "mcpServers": {
    "ssh-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/ssh-mcp/dist/index.js", "--config", "/absolute/path/to/your/config.json"]
    }
  }
}

Notes:

  • Replace /absolute/path/to/ssh-mcp with the full absolute path to your ssh-mcp directory
  • Make sure Node.js 18+ is installed and run bun install to install dependencies
  • The --config parameter is optional if your config.json is in the ssh-mcp directory

Environment Variables

  • LOG_LEVEL: Set logging level (debug, info, warn, error)
  • LOG_FILE: Path to log file (optional)

Example:

LOG_LEVEL=debug LOG_FILE=ssh-mcp.log bun run dev

Development

Project Structure

ssh-mcp/
├── src/
│   ├── index.ts           # MCP server entry point
│   ├── ssh/
│   │   └── connection.ts  # SSH connection management
│   ├── tools/
│   │   ├── execute.ts     # Command execution
│   │   └── file.ts        # File operations
│   ├── security/
│   │   └── validator.ts   # Security validation
│   ├── config/
│   │   └── manager.ts     # Configuration management
│   └── utils/
│       └── logger.ts      # Logging utilities
├── tests/                 # Test files
├── config.example.json    # Example configuration
└── package.json

Running Tests

bun test

Type Checking

bun run lint

Troubleshooting

MCP Configuration Issues

  1. "No MCP servers configured":

    • Check file path in configuration is absolute, not relative
    • Verify .claude.json file location and JSON syntax
    • Make sure Bun is installed and in PATH
  2. Server not starting:

    • Test the command manually: bun run /full/path/to/ssh-mcp/src/index.ts
    • Check for TypeScript compilation errors
    • Verify all dependencies are installed: bun install

Connection Issues

  1. Authentication Failed: Check username/password or key file permissions
  2. Connection Timeout: Verify network connectivity and firewall rules
  3. Key Permission Error: Ensure private key has 600 permissions

Command Execution Issues

  1. Command Blocked: Check whitelist/blacklist configuration
  2. Timeout Error: Increase timeout value in config or command
  3. Permission Denied: Verify user has necessary permissions on remote server

Debug Mode

Enable debug logging for troubleshooting:

LOG_LEVEL=debug bun run dev

License

MIT