ssh_execute
Run read-only commands on a remote machine via SSH, blocking write operations. Enables safe remote troubleshooting, monitoring, and auditing without risk of unintended changes.
Instructions
Execute a read-only command on the connected remote machine.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | Remote host (must be connected first) | |
| username | Yes | SSH username | |
| command | Yes | The read-only command to execute (e.g., 'ls -la', 'cat /etc/hostname') | |
| port | No | SSH port (default: 22) |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- ssh_readonly_fastmcp.py:104-149 (handler)The ssh_execute handler function implementing execution of read-only commands via SSH. It checks if connected, validates command safety via is_command_safe, executes via paramiko, and returns stdout/stderr.
@mcp.tool() def ssh_execute( host: str, username: str, command: str, port: int = 22 ) -> str: """ Execute a read-only command on the connected remote machine. Args: host: Remote host (must be connected first) username: SSH username command: The read-only command to execute (e.g., 'ls -la', 'cat /etc/hostname') port: SSH port (default: 22) Returns: Command output or error message """ connection_id = f"{username}@{host}:{port}" # Check if connected if connection_id not in ssh_clients: return f"Error: Not connected to {connection_id}. Please connect first using ssh_connect." # Validate command safety if not is_command_safe(command): return f"Error: Command not allowed for security reasons.\nOnly read-only commands are permitted.\nBlocked command: {command}" try: client = ssh_clients[connection_id]['client'] stdin, stdout, stderr = client.exec_command(command, timeout=30) output = stdout.read().decode('utf-8') error = stderr.read().decode('utf-8') exit_code = stdout.channel.recv_exit_status() if exit_code == 0: return output if output else "(command executed successfully with no output)" else: return f"Command failed with exit code {exit_code}\nError: {error if error else 'No error message'}" except paramiko.SSHException as e: return f"SSH error: {str(e)}" except Exception as e: return f"Command execution failed: {str(e)}" - ssh_readonly_fastmcp_mcast.py:218-263 (handler)The ssh_execute handler function in the multicast version of the server. Same logic as the base version: checks connection, validates command safety, executes via paramiko, and returns output.
@mcp.tool() def ssh_execute( host: str, username: str, command: str, port: int = 22 ) -> str: """ Execute a read-only command on the connected remote machine. Args: host: Remote host (must be connected first) username: SSH username command: The read-only command to execute (e.g., 'ls -la', 'cat /etc/hostname') port: SSH port (default: 22) Returns: Command output or error message """ connection_id = f"{username}@{host}:{port}" # Check if connected if connection_id not in ssh_clients: return f"Error: Not connected to {connection_id}. Please connect first using ssh_connect." # Validate command safety if not is_command_safe(command): return f"Error: Command not allowed for security reasons.\nOnly read-only commands are permitted.\nBlocked command: {command}" try: client = ssh_clients[connection_id]['client'] stdin, stdout, stderr = client.exec_command(command, timeout=30) output = stdout.read().decode('utf-8') error = stderr.read().decode('utf-8') exit_code = stdout.channel.recv_exit_status() if exit_code == 0: return output if output else "(command executed successfully with no output)" else: return f"Command failed with exit code {exit_code}\nError: {error if error else 'No error message'}" except paramiko.SSHException as e: return f"SSH error: {str(e)}" except Exception as e: return f"Command execution failed: {str(e)}" - ssh_readonly_fastmcp.py:15-24 (schema)The ALLOWED_COMMANDS set defining the read-only commands permitted for use with ssh_execute.
# List of allowed read-only commands ALLOWED_COMMANDS = { 'cat', 'ls', 'pwd', 'whoami', 'id', 'date', 'uptime', 'ps', 'top', 'df', 'du', 'free', 'netstat', 'ss', 'ifconfig', 'ip', 'hostname', 'uname', 'lsb_release', 'file', 'head', 'tail', 'wc', 'grep', 'find', 'locate', 'which', 'whereis', 'stat', 'lsof', 'mount', 'dmidecode', 'lscpu', 'lsblk', 'fdisk', 'blkid', 'journalctl', 'systemctl', 'service', 'curl', 'wget', 'dig', 'nslookup', 'ping', 'traceroute', 'mtr', 'iptables', 'firewall-cmd', 'ufw', 'awk', 'sed' } - ssh_readonly_fastmcp.py:29-52 (helper)The is_command_safe helper function used by ssh_execute to validate that a command is read-only safe and in the allowed list.
def is_command_safe(command: str) -> bool: """Verify that the command is read-only safe.""" cmd_parts = command.strip().split() if not cmd_parts: return False base_cmd = cmd_parts[0].split('/')[-1] # Get the command name without path # Block dangerous patterns dangerous_patterns = [ '>', '<', '|', '&', ';', '$(', '`', 'rm', 'dd', 'mkfs', 'chmod', 'chown', 'mv', 'cp', 'touch', 'mkdir', 'rmdir', 'kill', 'shutdown', 'reboot', 'halt', 'poweroff', 'su', 'sudo', 'passwd', 'usermod', 'useradd', 'userdel', 'nano', 'vi', 'vim', 'ed' ] # Check for dangerous patterns in command for pattern in dangerous_patterns: if pattern in command: return False # Check if base command is in allowed list return base_cmd in ALLOWED_COMMANDS - ssh_readonly_fastmcp.py:13-13 (registration)The @mcp.tool() decorator on line 104 registers ssh_execute as an MCP tool. The FastMCP instance is created on this line.
mcp = FastMCP("ssh-readonly")