โšก Quick Start: Linux Agent

November 11, 2025 ยท View on GitHub

Get your Linux device running as a UFOยณ device agent in 5 minutes. This guide walks you through server/client configuration and MCP service initialization.


๐Ÿ“‹ Prerequisites

Before you begin, ensure you have:

  • Python 3.10+ installed on both server and client machines
  • UFO repository cloned
  • Network connectivity between server and client machines
  • Linux machine for task execution (client)
  • Terminal access (bash, ssh, etc.)
  • LLM configured in config/ufo/agents.yaml (same as AppAgent)
ComponentMinimum VersionVerification Command
Python3.10python3 --version
Git2.0+git --version
NetworkN/Aping <server-ip>
LLM API KeyN/ACheck config/ufo/agents.yaml

โš ๏ธ LLM Configuration Required: The Linux Agent shares the same LLM configuration with the AppAgent. Before starting, ensure you have configured your LLM provider (OpenAI, Azure OpenAI, Gemini, Claude, etc.) and added your API keys to config/ufo/agents.yaml. See Model Setup Guide for detailed instructions.


๐Ÿ“ฆ Step 1: Install Dependencies

Install all dependencies from the requirements file:

pip install -r requirements.txt

Verify installation:

python3 -c "import ufo; print('โœ… UFOยฒ installed successfully')"

Tip: For production deployments, use a virtual environment to isolate dependencies:

python3 -m venv venv
source venv/bin/activate  # Linux/macOS
pip install -r requirements.txt

๐Ÿ–ฅ๏ธ Step 2: Start Device Agent Server

Server Component: The Device Agent Server is the central hub that manages connections from client devices and dispatches tasks. It can run on any machine (Linux, Windows, or remote server).

Server Machine Setup

You can run the server on:

  • โœ… Same machine as the client (localhost setup for testing)
  • โœ… Different machine on the same network
  • โœ… Remote server (requires proper network routing/SSH tunneling)

Basic Server Startup

On the server machine, run:

python -m ufo.server.app --port 5001

Expected Output:

2024-11-06 10:30:22 - ufo.server.app - INFO - Starting UFO Server on 0.0.0.0:5001
INFO:     Started server process [12345]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)

Once you see "Uvicorn running", the server is ready at ws://0.0.0.0:5001/ws.

Server Configuration Options

ArgumentDefaultDescriptionExample
--port5000Server listening port--port 5001
--host0.0.0.0Bind address (0.0.0.0 = all interfaces)--host 127.0.0.1
--log-levelINFOLogging verbosity--log-level DEBUG

Custom Server Configuration:

Custom Port:

python -m ufo.server.app --port 8080

Specific IP Binding:

python -m ufo.server.app --host 192.168.1.100 --port 5001

Debug Mode:

python -m ufo.server.app --port 5001 --log-level DEBUG

Verify Server is Running

# Test server health endpoint
curl http://localhost:5001/api/health

Expected Response:

{
  "status": "healthy",
  "online_clients": []
}

Documentation Reference: For detailed server configuration and advanced features, see Server Quick Start Guide.


๐Ÿง Step 3: Start Device Agent Client (Linux Machine)

Client Component: The Device Agent Client runs on the Linux machine where you want to execute tasks. It connects to the server via WebSocket and receives task commands.

Basic Client Startup

On the Linux machine where you want to execute tasks:

python -m ufo.client.client \
  --ws \
  --ws-server ws://172.23.48.1:5001/ws \
  --client-id linux_agent_1 \
  --platform linux

Client Parameters Explained

ParameterRequiredDescriptionExample
--wsโœ… YesEnable WebSocket mode--ws
--ws-serverโœ… YesServer WebSocket URLws://172.23.48.1:5001/ws
--client-idโœ… YesUnique device identifierlinux_agent_1
--platformโœ… Yes (Linux)Platform type (must be linux for Linux Agent)--platform linux

โš ๏ธ Critical Requirements:

  1. --client-id must be globally unique - No two devices can share the same ID
  2. --platform linux is mandatory - Without this flag, the Linux Agent won't work correctly
  3. Server address must be correct - Replace 172.23.48.1:5001 with your actual server IP and port

Understanding the WebSocket URL

The --ws-server parameter format is:

ws://<server-ip>:<server-port>/ws

Examples:

ScenarioWebSocket URLDescription
Localhostws://localhost:5001/wsServer and client on same machine
Same Networkws://192.168.1.100:5001/wsServer on local network
Remote Serverws://203.0.113.50:5001/wsServer on internet (public IP)
SSH Tunnelws://localhost:5001/wsAfter SSH reverse tunnel setup

Connection Success Indicators

Client Logs:

INFO - Platform detected/specified: linux
INFO - UFO Client initialized for platform: linux
INFO - [WS] Connecting to ws://172.23.48.1:5001/ws (attempt 1/5)
INFO - [WS] [AIP] Successfully registered as linux_agent_1
INFO - [WS] Heartbeat loop started (interval: 30s)

Server Logs:

INFO - [WS] โœ… Registered device client: linux_agent_1
INFO - [WS] Device linux_agent_1 platform: linux

Client is connected and ready to receive tasks when you see "Successfully registered"!

Verify Connection

# Check connected clients on server
curl http://172.23.48.1:5001/api/clients

Expected Response:

{
  "clients": [
    {
      "client_id": "linux_agent_1",
      "type": "device",
      "platform": "linux",
      "connected_at": 1730899822.0,
      "uptime_seconds": 45
    }
  ]
}

Documentation Reference: For detailed client configuration, see Client Quick Start Guide.


๐Ÿ”Œ Step 4: Start MCP Service (Linux Machine)

MCP Service Component: The MCP (Model Context Protocol) Service provides the execution layer for CLI commands. It must be running on the same Linux machine as the client to handle command execution requests.

Start the MCP Server

On the Linux machine (same machine as the client):

python -m ufo.client.mcp.http_servers.linux_mcp_server

Expected Output:

INFO:     Started server process [23456]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8010 (Press CTRL+C to quit)

The MCP service is now ready to execute CLI commands at http://127.0.0.1:8010.

What is the MCP Service?

The Linux MCP Server provides two main functionalities:

CommandPurposeExample Use Case
EXEC_CLIExecute shell commandsls -la, grep pattern file.txt, ps aux
SYS_INFORetrieve system informationCPU usage, memory stats, disk space

Architecture:

sequenceDiagram
    participant Agent as Linux Agent
    participant MCP as Linux MCP Server
    participant Shell as Bash Shell
    
    Agent->>MCP: EXEC_CLI<br/>{command: "ls -la"}
    MCP->>Shell: Execute command
    Shell-->>MCP: stdout, stderr, exit_code
    MCP-->>Agent: {result, output}

MCP Service Configuration

The MCP server typically runs on localhost:8010 by default. The client automatically connects to it when configured properly.

โš ๏ธ MCP Service Must Be Running: If the MCP service is not running, the Linux Agent cannot execute commands and will fail with:

ERROR: Cannot connect to MCP server at http://127.0.0.1:8010

Documentation Reference: For detailed MCP command specifications, see MCP Overview, Linux MCP Commands, and BashExecutor Server.


๐ŸŽฏ Step 5: Dispatch Tasks via HTTP API

Once the server, client, and MCP service are all running, you can dispatch tasks to the Linux agent through the server's HTTP API.

API Endpoint

POST http://<server-ip>:<server-port>/api/dispatch

Request Format

{
  "client_id": "linux_agent_1",
  "request": "Your natural language task description",
  "task_name": "optional_task_identifier"
}

Example: Simple File Listing

Using cURL:

curl -X POST http://172.23.48.1:5001/api/dispatch \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "linux_agent_1",
    "request": "List all files in the /tmp directory",
    "task_name": "list_tmp_files"
  }'

Using Python:

import requests

response = requests.post(
    "http://172.23.48.1:5001/api/dispatch",
    json={
        "client_id": "linux_agent_1",
        "request": "List all files in the /tmp directory",
        "task_name": "list_tmp_files"
    }
)
print(response.json())

Using HTTPie:

http POST http://172.23.48.1:5001/api/dispatch \
  client_id=linux_agent_1 \
  request="List all files in the /tmp directory" \
  task_name=list_tmp_files

Successful Response:

{
  "status": "dispatched",
  "task_name": "list_tmp_files",
  "client_id": "linux_agent_1",
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}

Example: System Information Query

curl -X POST http://172.23.48.1:5001/api/dispatch \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "linux_agent_1",
    "request": "Show disk usage for all mounted filesystems",
    "task_name": "check_disk_usage"
  }'

Example: Log File Analysis

curl -X POST http://172.23.48.1:5001/api/dispatch \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "linux_agent_1",
    "request": "Find all ERROR or FATAL entries in /var/log/app.log from the last hour",
    "task_name": "analyze_error_logs"
  }'

Task Execution Flow

sequenceDiagram
    participant API as HTTP Client
    participant Server as Agent Server
    participant Client as Linux Client
    participant MCP as MCP Service
    participant Shell as Bash
    
    Note over API,Server: 1. Task Submission
    API->>Server: POST /api/dispatch<br/>{client_id, request}
    Server->>Server: Generate session_id
    Server-->>API: {status: dispatched, session_id}
    
    Note over Server,Client: 2. Task Assignment
    Server->>Client: TASK_ASSIGNMENT<br/>(via WebSocket)
    Client->>Client: Parse request<br/>Plan actions
    
    Note over Client,MCP: 3. Command Execution
    Client->>MCP: EXEC_CLI<br/>{command: "ls -la /tmp"}
    MCP->>Shell: Execute command
    Shell-->>MCP: stdout, stderr, exit_code
    MCP-->>Client: {result, output}
    
    Note over Client,Server: 4. Result Reporting
    Client->>Server: TASK_RESULT<br/>{status, result}

Request Parameters

FieldRequiredTypeDescriptionExample
client_idโœ… YesstringTarget Linux agent ID (must match --client-id)"linux_agent_1"
requestโœ… YesstringNatural language task description"List files in /var/log"
task_nameโŒ OptionalstringUnique task identifier (auto-generated if omitted)"task_001"

โš ๏ธ Client Must Be Online: If the client_id is not connected, you'll receive:

{
  "detail": "Client not online"
}

Verify the client is connected:

curl http://172.23.48.1:5001/api/clients

๐ŸŒ‰ Network Connectivity & SSH Tunneling

When the server and client are on different networks or behind firewalls, you may need SSH tunneling to establish connectivity.

Scenario 1: Same Network (No Tunnel Needed)

Setup:

  • Server: 192.168.1.100:5001
  • Client: 192.168.1.50 (same LAN)

Client Command:

python -m ufo.client.client \
  --ws \
  --ws-server ws://192.168.1.100:5001/ws \
  --client-id linux_agent_1 \
  --platform linux

No additional configuration needed โœ…

Scenario 2: Client Behind Firewall (Reverse SSH Tunnel)

Problem:

  • Server: 203.0.113.50:5001 (public IP, accessible)
  • Client: 192.168.1.50 (private network, behind NAT/firewall)
  • Client cannot directly reach server

Solution: SSH Reverse Tunnel

On the client machine, create an SSH reverse tunnel:

ssh -N -R 5001:localhost:5001 user@203.0.113.50

Parameters:

  • -N: No remote command execution (tunnel only)
  • -R 5001:localhost:5001: Forward remote port 5001 to local port 5001
  • user@203.0.113.50: SSH server address (where the UFO server runs)

What This Does:

graph LR
    Client[Client Machine<br/>192.168.1.50]
    SSH[SSH Tunnel]
    Server[Server Machine<br/>203.0.113.50]
    
    Client -->|SSH Reverse Tunnel| SSH
    SSH -->|Port 5001| Server
    
    style Client fill:#e1f5ff
    style Server fill:#ffe1e1
    style SSH fill:#fffacd

After tunnel is established:

# Client can now connect to localhost:5001
python -m ufo.client.client \
  --ws \
  --ws-server ws://localhost:5001/ws \
  --client-id linux_agent_1 \
  --platform linux

Scenario 3: Server Behind Firewall (Forward SSH Tunnel)

Problem:

  • Server: 192.168.1.100:5001 (private network)
  • Client: 203.0.113.75 (public network)
  • Client cannot directly reach server

Solution: SSH Forward Tunnel

On the client machine, create an SSH forward tunnel to the server's network:

ssh -N -L 5001:192.168.1.100:5001 gateway-user@vpn.company.com

Parameters:

  • -N: No remote command execution
  • -L 5001:192.168.1.100:5001: Forward local port 5001 to remote 192.168.1.100:5001
  • gateway-user@vpn.company.com: SSH gateway that can access the server

After tunnel is established:

# Client connects to localhost, which forwards to server
python -m ufo.client.client \
  --ws \
  --ws-server ws://localhost:5001/ws \
  --client-id linux_agent_1 \
  --platform linux

Example: Complex Tunnel Setup

Situation:

  • Server IP: 10.0.0.50:5001 (corporate network)
  • Client IP: 192.168.1.75 (home network)
  • SSH Gateway: vpn.company.com (accessible from internet)

Step 1: Create SSH Tunnel

# On client machine
ssh -N -L 5001:10.0.0.50:5001 myuser@vpn.company.com

Step 2: Start Client (in another terminal)

python -m ufo.client.client \
  --ws \
  --ws-server ws://localhost:5001/ws \
  --client-id linux_agent_home_1 \
  --platform linux

SSH Tunnel Best Practices

For production use, add these flags to your SSH tunnel:

ssh -N \
  -L 5001:server:5001 \
  -o ServerAliveInterval=60 \
  -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes \
  user@gateway

Flags explained:

  • ServerAliveInterval=60: Send keep-alive every 60 seconds
  • ServerAliveCountMax=3: Disconnect after 3 failed keep-alives
  • ExitOnForwardFailure=yes: Exit if port forwarding fails

Persistent SSH Tunnel with Autossh

For production, use autossh to automatically restart the tunnel if it fails:

# Install autossh
sudo apt-get install autossh  # Debian/Ubuntu

# Start persistent tunnel
autossh -M 0 \
  -N \
  -L 5001:server:5001 \
  -o ServerAliveInterval=60 \
  -o ServerAliveCountMax=3 \
  user@gateway

โ„น๏ธ Network Configuration: For more network configuration details, see Server Quick Start - Troubleshooting.


๐ŸŒŒ Step 6: Configure as UFOยณ Galaxy Device

To use the Linux Agent as a managed device within the UFOยณ Galaxy multi-tier framework, you need to register it in the devices.yaml configuration file.

Device Configuration File

The Galaxy configuration is located at:

config/galaxy/devices.yaml

Add Linux Agent Configuration

Edit config/galaxy/devices.yaml and add your Linux agent under the devices section:

devices:
  - device_id: "linux_agent_1"
    server_url: "ws://172.23.48.1:5001/ws"
    os: "linux"
    capabilities:
      - "server"
      - "log_analysis"
      - "file_operations"
    metadata:
      os: "linux"
      performance: "medium"
      logs_file_path: "/var/log/myapp/app.log"
      dev_path: "/home/user/development/"
      warning_log_pattern: "WARN"
      error_log_pattern: "ERROR|FATAL"
    auto_connect: true
    max_retries: 5

Configuration Fields Explained

FieldRequiredTypeDescriptionExample
device_idโœ… YesstringMust match client --client-id"linux_agent_1"
server_urlโœ… YesstringMust match server WebSocket URL"ws://172.23.48.1:5001/ws"
osโœ… YesstringOperating system"linux"
capabilitiesโŒ OptionallistDevice capabilities (for task routing)["server", "log_analysis"]
metadataโŒ OptionaldictCustom metadata for task contextSee below
auto_connectโŒ OptionalbooleanAuto-connect on Galaxy startuptrue
max_retriesโŒ OptionalintegerConnection retry attempts5

Metadata Fields (Custom)

The metadata section can contain any custom fields relevant to your Linux agent:

FieldPurposeExample
logs_file_pathPath to application logs"/var/log/app.log"
dev_pathDevelopment directory"/home/user/dev/"
warning_log_patternRegex pattern for warnings"WARN"
error_log_patternRegex pattern for errors"ERROR|FATAL"
performancePerformance tier"high", "medium", "low"
descriptionHuman-readable description"Production database server"

Multiple Linux Agents Example

devices:
  - device_id: "linux_agent_1"
    server_url: "ws://172.23.48.1:5001/ws"
    os: "linux"
    capabilities:
      - "web_server"
    metadata:
      logs_file_path: "/var/log/nginx/access.log"
      dev_path: "/var/www/html/"
      warning_log_pattern: "WARN"
      error_log_pattern: "ERROR|FATAL"
    auto_connect: true
    max_retries: 5

  - device_id: "linux_agent_2"
    server_url: "ws://172.23.48.2:5002/ws"
    os: "linux"
    capabilities:
      - "database_server"
    metadata:
      logs_file_path: "/var/log/postgresql/postgresql.log"
      dev_path: "/var/lib/postgresql/"
      warning_log_pattern: "WARNING"
      error_log_pattern: "ERROR|FATAL|PANIC"
    auto_connect: true
    max_retries: 5

  - device_id: "linux_agent_3"
    server_url: "ws://172.23.48.3:5003/ws"
    os: "linux"
    capabilities:
      - "monitoring"
    metadata:
      logs_file_path: "/var/log/prometheus/prometheus.log"
      dev_path: "/opt/prometheus/"
      warning_log_pattern: "level=warn"
      error_log_pattern: "level=error"
    auto_connect: true
    max_retries: 5

Critical Requirements

โš ๏ธ Configuration Validation - These fields MUST match exactly:

  1. device_id in YAML โ†” --client-id in client command

    device_id: "linux_agent_1"  # In devices.yaml
    
    --client-id linux_agent_1   # In client command
    
  2. server_url in YAML โ†” --ws-server in client command

    server_url: "ws://172.23.48.1:5001/ws"  # In devices.yaml
    
    --ws-server ws://172.23.48.1:5001/ws    # In client command
    

If these don't match, Galaxy cannot control the device!

Using Galaxy to Control Linux Agents

Once configured, you can launch Galaxy and it will automatically manage the Linux agents:

python -m galaxy --interactive

Galaxy will:

  1. โœ… Automatically load device configuration from config/galaxy/devices.yaml
  2. โœ… Connect to all configured devices
  3. โœ… Orchestrate multi-device tasks
  4. โœ… Route tasks based on capabilities
  5. โœ… Monitor device health

โ„น๏ธ Galaxy Documentation: For detailed Galaxy configuration and usage, see:


๐Ÿ› Common Issues & Troubleshooting

Issue 1: Client Cannot Connect to Server

Error: Connection Refused

Symptoms:

ERROR - [WS] Failed to connect to ws://172.23.48.1:5001/ws
Connection refused

Diagnosis Checklist:

  • Is the server running? (curl http://172.23.48.1:5001/api/health)
  • Is the port correct? (Check server startup logs)
  • Can client reach server IP? (ping 172.23.48.1)
  • Is firewall blocking port 5001?
  • Is SSH tunnel established (if needed)?

Solutions:

Verify Server:

# On server machine
curl http://localhost:5001/api/health

# From client machine
curl http://172.23.48.1:5001/api/health

Check Network:

# Test connectivity
ping 172.23.48.1

# Test port accessibility
nc -zv 172.23.48.1 5001
telnet 172.23.48.1 5001

Check Firewall:

# On server machine (Ubuntu/Debian)
sudo ufw status
sudo ufw allow 5001/tcp

# On server machine (RHEL/CentOS)
sudo firewall-cmd --list-ports
sudo firewall-cmd --add-port=5001/tcp --permanent
sudo firewall-cmd --reload

Issue 2: MCP Service Not Responding

Error: Cannot Execute Commands

Symptoms:

ERROR - Cannot connect to MCP server at http://127.0.0.1:8010
ERROR - Command execution failed

Diagnosis:

  • Is the MCP service running?
  • Is it running on the correct port?
  • Are there any startup errors in MCP logs?

Solutions:

Verify MCP Service:

# Check if MCP service is running
curl http://localhost:8010/health

# Or check process
ps aux | grep linux_mcp_server

Restart MCP Service:

# Kill existing process (if hung)
pkill -f linux_mcp_server

# Start fresh
python -m ufo.client.mcp.http_servers.linux_mcp_server

Check Port Conflict:

# See if something else is using port 8010
lsof -i :8010
netstat -tuln | grep 8010

# If port is taken, start MCP on different port
python -m ufo.client.mcp.http_servers.linux_mcp_server --port 8011

Issue 3: Missing --platform linux Flag

Error: Incorrect Agent Type

Symptoms:

  • Client connects but cannot execute Linux commands
  • Server logs show wrong platform type
  • Tasks fail with "unsupported operation" errors

Cause: Forgot to add --platform linux flag when starting the client.

Solution:

# Wrong (missing platform)
python -m ufo.client.client --ws --client-id linux_agent_1

# Correct
python -m ufo.client.client \
  --ws \
  --client-id linux_agent_1 \
  --platform linux

Issue 4: Duplicate Client ID

Error: Registration Failed

Symptoms:

ERROR - [WS] Registration failed: client_id already exists
ERROR - Another device is using ID 'linux_agent_1'

Cause: Multiple clients trying to use the same client_id.

Solutions:

  1. Use unique client IDs:

    # Device 1
    --client-id linux_agent_1
    
    # Device 2
    --client-id linux_agent_2
    
    # Device 3
    --client-id linux_agent_3
    
  2. Check currently connected clients:

    curl http://172.23.48.1:5001/api/clients
    

Issue 5: Galaxy Cannot Find Device

Error: Device Not Configured

Symptoms:

ERROR - Device 'linux_agent_1' not found in configuration
WARNING - Cannot dispatch task to unknown device

Cause: Mismatch between devices.yaml configuration and actual client setup.

Diagnosis:

Check that these match exactly:

LocationFieldExample
devices.yamldevice_id"linux_agent_1"
Client command--client-idlinux_agent_1
devices.yamlserver_url"ws://172.23.48.1:5001/ws"
Client command--ws-serverws://172.23.48.1:5001/ws

Solution: Update devices.yaml to match your client configuration, or vice versa.

Issue 6: SSH Tunnel Keeps Disconnecting

Error: Tunnel Connection Lost

Symptoms:

  • Client disconnects after a few minutes
  • SSH tunnel closes unexpectedly
  • "Connection reset by peer" errors

Solutions:

Use ServerAliveInterval:

ssh -N \
  -L 5001:server:5001 \
  -o ServerAliveInterval=60 \
  -o ServerAliveCountMax=3 \
  user@gateway

Use Autossh:

autossh -M 0 \
  -N \
  -L 5001:server:5001 \
  -o ServerAliveInterval=60 \
  user@gateway

Run in Screen/Tmux:

# Start screen session
screen -S ssh-tunnel

# Run SSH tunnel
ssh -N -L 5001:server:5001 user@gateway

# Detach: Ctrl+A, then D
# Reattach: screen -r ssh-tunnel

๐Ÿ“š Next Steps

You've successfully set up a Linux Agent! Explore these topics to deepen your understanding:

Immediate Next Steps

PriorityTopicTimeLink
๐Ÿฅ‡Linux Agent Architecture10 minOverview
๐ŸฅˆState Machine & Processing15 minState Machine
๐Ÿฅ‰MCP Commands Reference10 minCommands

Advanced Topics

TopicDescriptionLink
Processing Strategy3-phase pipeline (LLM, Action, Memory)Strategy
Galaxy IntegrationMulti-device orchestrationGalaxy Overview
MCP ProtocolDeep dive into command executionMCP Overview
Server ArchitectureUnderstanding the server internalsServer Overview

Production Deployment

Best PracticeDescriptionLink
Systemd ServiceRun client as Linux serviceClient Guide
Log ManagementStructured logging and rotationServer Monitoring
Security HardeningSSL/TLS, authentication, firewallsServer Guide

โœ… Summary

โœ… What You've Accomplished

Congratulations! You've successfully:

โœ… Switched to the linux-client branch
โœ… Installed all dependencies
โœ… Started the Device Agent Server
โœ… Connected a Linux Device Agent Client
โœ… Launched the MCP service for command execution
โœ… Dispatched tasks via HTTP API
โœ… (Optional) Configured SSH tunneling for remote access
โœ… (Optional) Registered the device in Galaxy configuration

Your Linux Agent is Ready

You can now:

  • ๐ŸŽฏ Execute CLI commands on Linux machines remotely
  • ๐Ÿ“Š Analyze log files across multiple servers
  • ๐Ÿ”ง Manage development environments
  • ๐ŸŒŒ Integrate with UFOยณ Galaxy for multi-device workflows

Start exploring and automating your Linux infrastructure! ๐Ÿš€