ssh-mcp

repository·main·Indexed 20 days ago

https://github.com/tufantunc/ssh-mcp

An MCP server (v1.5.0) that allows LLMs and MCP clients to execute shell commands on remote Linux and Windows systems via SSH. It provides tools for standard command execution (exec) and sudo elevation (sudo-exec), supporting both password and private key authentication. The server includes configurable timeout protections, command length limits, and a connection manager for persistent SSH sessions.

Tokens
2.5K
Snippets
9
Records
11
Agent score
67%

What's inside ssh-mcp

  1. Install SSH MCP Server

    main

    To install the SSH MCP Server from source, clone the repository and install the dependencies using npm.

    # Clone the repository
    git clone https://github.com/tufantunc/ssh-mcp.git
    cd ssh-mcp
    
    # Install dependencies
    npm install
    git clone https://github.com/tufantunc/ssh-mcp.git
    cd ssh-mcp
    npm install
  2. Add SSH MCP Server to Claude Code

    main

    The recommended way to add this server to Claude Code is using the claude mcp add command. You can specify different scopes: local (default), project (via .mcp.json), or user (available across all projects).

    Examples

    With Password Authentication:

    claude mcp add --transport stdio ssh-mcp -- npx -y ssh-mcp -- --host=192.168.1.100 --port=22 --user=admin --password=your_password

    With SSH Key Authentication:

    claude mcp add --transport stdio ssh-mcp -- npx -y ssh-mcp -- --host=example.com --user=root --key=/path/to/private/key

    With Custom Timeout and No Character Limit:

    claude mcp add --transport stdio ssh-mcp -- npx -y ssh-mcp -- --host=192.168.1.100 --user=admin --password=your_password --timeout=120000 --maxChars=none

    With Sudo and Su Support:

    claude mcp add --transport stdio ssh-mcp -- npx -y ssh-mcp -- --host=192.168.1.100 --user=admin --password=your_password --sudoPassword=sudo_pass --suPassword=root_pass
    claude mcp add --transport stdio ssh-mcp -- npx -y ssh-mcp -- --host=YOUR_HOST --user=YOUR_USER --password=YOUR_PASSWORD
  3. Configure SSH MCP Server for MCP Clients

    main

    To use the SSH MCP Server with clients like Cursor, Windsurf, or Claude Desktop, you must provide connection parameters via command-line arguments.

    Required Parameters

    • host: Hostname or IP of the Linux or Windows server
    • user: SSH username

    Optional Parameters

    • port: SSH port (default: 22)
    • password: SSH password
    • key: Path to private SSH key (use instead of password for key-based auth)
    • sudoPassword: Password for sudo elevation
    • suPassword: Password for su elevation (for persistent root shells)
    • timeout: Command execution timeout in milliseconds (default: 60000)
    • maxChars: Maximum allowed characters for the command input (default: 1000). Use none or 0 to disable.
    • disableSudo: Flag to disable the sudo-exec tool completely.
    {
        "mcpServers": {
            "ssh-mcp": {
                "command": "npx",
                "args": [
                    "ssh-mcp",
                    "-y",
                    "--",
                    "--host=1.2.3.4",
                    "--port=22",
                    "--user=root",
                    "--password=pass",
                    "--key=path/to/key",
                    "--timeout=30000",
                    "--maxChars=none"
                ]
            }
        }
    }
  4. Configure the SSH MCP Server via CLI arguments

    main

    When running the SSH MCP server as a CLI application, you can provide connection details using --key=value arguments.

    Available Arguments:

    • --host: The remote host address (Required).
    • --port: The SSH port (Default: 22).
    • --user: The SSH username (Required).
    • --password: The SSH password.
    • --suPassword: The password for su elevation.
    • --sudoPassword: The password for sudo commands.
    • --key: Path to a private key file.
    • --timeout: Command execution timeout in milliseconds (Default: 60000).
    • --disableSudo: Flag to disable the sudo-exec tool.
    • --maxChars: Limits command length. Use 0, a negative number, or none (case-insensitive) to disable the limit. Default is 1000.

    Example Command:

    node build/index.js --host=1.2.3.4 --port=22 --user=root --password=pass --key=path/to/key --timeout=5000 --disableSudo
    node build/index.js --host=1.2.3.4 --port=22 --user=root --password=pass --key=path/to/key --timeout=5000 --disableSudo
  5. SSH MCP Server Tools: exec and sudo-exec

    main

    The server exposes two primary tools for remote command execution:

    exec

    Executes a shell command on the remote server.

    • Parameters:
      • command (required): The shell command to execute.
      • description (optional): A description of the command (appended as a comment).

    sudo-exec

    Executes a shell command with sudo elevation.

    • Parameters:
      • command (required): The shell command to execute as root using sudo.
      • description (optional): A description of the command (appended as a comment).
    • Notes:
      • Requires --sudoPassword to be set in the server configuration.
      • If the server is started with the --disableSudo flag, this tool will not be available.
      • For persistent root access, consider using --suPassword to establish a root shell instead.
  6. Configure the SSH service via Docker Compose

    main

    When running the SSH service using Docker Compose, you can configure user credentials and access permissions using the following environment variables:

    • USER_NAME: The username for the SSH account.
    • PASSWORD_ACCESS: A boolean (true/false) determining if password-based authentication is allowed.
    • USER_PASSWORD: The password for the specified USER_NAME.
    • SUDO_ACCESS: A boolean (true/false) determining if the user has sudo privileges.

    By default, the service maps port 2222 on the host to port 2222 in the container.

    services:
      ssh:
        image: lscr.io/linuxserver/openssh-server:latest
        environment:
          - USER_NAME=test
          - PASSWORD_ACCESS=true
          - USER_PASSWORD=secret
          - SUDO_ACCESS=true
        ports:
          - "2222:2222"
  7. Sanitize and escape shell commands

    main

    To prevent injection or errors when running commands in different shell contexts, use these utility functions:

    • sanitizeCommand(command: string): Trims the command and validates it is a non-empty string. It also enforces the MAX_CHARS limit configured at startup. Throws McpError with ErrorCode.InvalidParams if validation fails.
    • escapeCommandForShell(command: string): Escapes single quotes within a command to make it safe for use in shell contexts (e.g., when wrapping a command inside another command like pkill).
    import { sanitizeCommand, escapeCommandForShell } from './src/index';
    
    const clean = sanitizeCommand("ls -la");
    const escaped = escapeCommandForShell("echo 'hello'"); // returns "echo '"'"'hello'""
  8. Use SSHConnectionManager to manage persistent SSH sessions

    main

    The SSHConnectionManager class maintains a persistent SSH connection and can handle user elevation (via su).

    Interface SSHConfig:

    export interface SSHConfig {
      host: string;
      port: number;
      username: string;
      password?: string;
      privateKey?: string;
      suPassword?: string;
      sudoPassword?: string;
    }

    Key Methods:

    • connect(): Establishes the SSH connection. If suPassword is provided, it attempts to elevate to a su shell automatically (unless in test mode).
    • ensureConnected(): Ensures the connection is active, calling connect() if necessary.
    • setSuPassword(pwd?: string): Updates the suPassword and attempts to re-elevate the shell if a password is provided.
    • close(): Closes the SSH connection and any active su shells.
    • isConnected(): Returns true if the connection is active and the socket is not destroyed.
    const manager = new SSHConnectionManager({
      host: '1.2.3.4',
      port: 22,
      username: 'root',
      suPassword: 'my-password'
    });
    await manager.connect();
  9. Execute commands via `execSshCommandWithConnection`

    main

    This function executes a command using an existing SSHConnectionManager. It is the primary way to run commands while leveraging persistent connections or an existing elevated su shell.

    Behavior:

    1. If the manager has an active su shell (elevated), the command is written directly to that shell. The function waits for the root prompt (#) to signal completion and extracts the output.
    2. If no su shell is available, it uses standard conn.exec().
    3. It supports an optional stdin string for providing input (like passwords) to the command.

    Returns: A promise resolving to an object containing a content array with the command output as text.

    Signature: async function execSshCommandWithConnection(manager: SSHConnectionManager, command: string, stdin?: string): Promise<{ content: { type: 'text', text: string }[] }>

    const result = await execSshCommandWithConnection(connectionManager, "uptime");
    console.log(result.content[0].text);
  10. Reference: MCP Server Tools

    main

    The SSH MCP Server exposes the following tools to MCP clients:

    ToolDescriptionParameters
    execExecutes a shell command on the remote server.command (string, required), description (string, optional)
    sudo-execExecutes a command using sudo. Uses sudoPassword if provided, otherwise assumes passwordless sudo.command (string, required), description (string, optional)