Files
claudetools/projects/msp-tools/guru-rmm/GURURMM_DOCUMENTATION.md
Mike Swanson 8b6f0bcc96 sync: Multi-project updates - SolverBot, GuruRMM, Dataforth
SolverBot:
- Inject active project path into agent system prompts so agents
  know which directory to scope file operations to

GuruRMM:
- Bump agent version to 0.6.0
- Add serde aliases for PowerShell/ClaudeTask command types
- Add typed CommandType enum on server for proper serialization
- Support claude_task command type in send_command API

Dataforth:
- Fix SCP space-escaping in Sync-FromNAS.ps1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 16:16:18 -07:00

23 KiB

GuruRMM - Complete Reference Documentation

Project: GuruRMM - Remote Monitoring and Management Platform Version: Server 0.2.0 / Agent 0.3.5 (deployed as 0.5.1) Last Updated: 2026-02-17


Table of Contents

  1. Project Overview
  2. Architecture
  3. API Endpoints
  4. WebSocket Protocol
  5. Command Execution
  6. Claude Code Integration
  7. Agent Configuration
  8. Deployed Agents
  9. Database
  10. Authentication
  11. Auto-Update System
  12. Known Issues
  13. Development
  14. File Structure

Project Overview

GuruRMM is a Remote Monitoring and Management (RMM) platform built entirely in Rust. It provides real-time agent monitoring, remote command execution, system metrics collection, and service watchdog capabilities for managed IT environments.

Technology Stack

Component Technology Version
Server Rust (Axum 0.7, SQLx 0.8, PostgreSQL) 0.2.0
Agent Rust (cross-platform, native service) 0.3.5 (deployed as 0.5.1)
Dashboard React + TypeScript + Vite --
Real-time WebSocket (tokio-tungstenite) --
Database PostgreSQL --

Architecture

Server

  • Internal Address: 172.16.3.30:3001
  • Production URL: https://rmm-api.azcomputerguru.com
  • WebSocket Endpoint: wss://rmm-api.azcomputerguru.com/ws
  • Database: PostgreSQL (same server)
  • Service: systemd unit gururmm-server
  • Source: D:\ClaudeTools\projects\msp-tools\guru-rmm\server\

Agent

  • Windows Service Name: GuruRMM (uses native-service feature)
  • Legacy Mode: NSSM wrapper for Windows 7 / Server 2008 R2
  • Config Path: C:\ProgramData\GuruRMM\agent.toml
  • Binary Path: C:\Program Files\GuruRMM\gururmm-agent.exe
  • Source: D:\ClaudeTools\projects\msp-tools\guru-rmm\agent\

Communication Model

+-------------------+       WebSocket (persistent, bidirectional)       +-------------------+
|   GuruRMM Agent   | <-----------------------------------------------> |  GuruRMM Server   |
| (Windows/Linux)   |                                                   |  (Axum + Tokio)   |
+-------------------+                                                   +-------------------+
                                                                               |
                                                                               | REST API (JWT)
                                                                               v
                                                                        +-------------------+
                                                                        |    Dashboard      |
                                                                        |  (React + TS)     |
                                                                        +-------------------+
  • Primary: WebSocket -- persistent bidirectional connection between agent and server
  • Legacy Fallback: REST heartbeat polling -- [WARNING] NOT FULLY IMPLEMENTED
  • Auth: API key sent in initial WebSocket authentication message
  • Site-Based Auth: WORD-WORD-NUMBER format site codes combined with device_id

API Endpoints

Authentication

Method Path Description Auth Required
POST /api/auth/login User login (email/password -> JWT) No
POST /api/auth/register User registration No (disabled)
GET /api/auth/me Get current user info Yes

Clients

Method Path Description Auth Required
GET /api/clients List all clients Yes
POST /api/clients Create client Yes
GET /api/clients/:id Get client by ID Yes
PUT /api/clients/:id Update client Yes
DELETE /api/clients/:id Delete client Yes
GET /api/clients/:id/sites List client's sites Yes

Sites

Method Path Description Auth Required
GET /api/sites List all sites Yes
POST /api/sites Create site Yes
GET /api/sites/:id Get site by ID Yes
PUT /api/sites/:id Update site Yes
DELETE /api/sites/:id Delete site Yes
POST /api/sites/:id/regenerate-key Regenerate site API key Yes

Agents

Method Path Description Auth Required
GET /api/agents List all agents Yes
POST /api/agents Register agent (authenticated) Yes
GET /api/agents/stats Agent statistics Yes
GET /api/agents/unassigned List unassigned agents Yes
GET /api/agents/:id Get agent details Yes
DELETE /api/agents/:id Delete agent Yes
POST /api/agents/:id/move Move agent to different site Yes
GET /api/agents/:id/state Get agent state (network, metrics) Yes

Commands

Method Path Description Auth Required
POST /api/agents/:id/command Send command to agent Yes
GET /api/commands List recent commands Yes
GET /api/commands/:id Get command status/result Yes

Metrics

Method Path Description Auth Required
GET /api/agents/:id/metrics Get agent metrics history Yes
GET /api/metrics/summary Metrics summary Yes

Legacy Agent Endpoints

These endpoints do not require JWT authentication. They are used by agents in legacy polling mode.

Method Path Description Auth Required
POST /api/agent/register-legacy Register with site code No
POST /api/agent/heartbeat Agent heartbeat No
POST /api/agent/command-result Submit command result No

[WARNING] Legacy heartbeat returns empty pending_commands -- not implemented (agents.rs line 334). [WARNING] Legacy command-result endpoint does not store results (agents.rs lines 354-360).

WebSocket

Method Path Description Auth Required
GET /ws WebSocket upgrade API key in auth msg

WebSocket Protocol

Connection Flow

  1. Client initiates WebSocket upgrade to wss://rmm-api.azcomputerguru.com/ws
  2. Agent sends authentication message with API key and device info
  3. Server validates API key (SHA256 hash match or site code lookup)
  4. On success, server registers the WebSocket connection for the agent
  5. Bidirectional message exchange begins

Message Types

Agent -> Server:

  • Auth -- Initial authentication payload (api_key, hostname, os_info, version)
  • Heartbeat -- Periodic keepalive
  • MetricsReport -- System metrics (CPU, memory, disk, network)
  • NetworkState -- Network configuration snapshot (hash-based change detection)
  • CommandResult -- Result of executed command (exit_code, stdout, stderr, duration)
  • WatchdogEvent -- Service monitoring event

Server -> Agent:

  • AuthResponse -- Success/failure of authentication
  • Command -- Command to execute (CommandPayload)
  • Update -- Auto-update instruction (download_url, checksum)
  • Ping -- Keepalive ping

Command Execution

Command Types

Type Description Shell Used
shell System shell command cmd.exe (Windows), /bin/sh (Unix)
powershell PowerShell command powershell -NoProfile -NonInteractive -Command
python Python inline code python -c
script Custom interpreter Configurable
claude_task Claude Code task execution (special handler) Claude Code CLI

Command Flow

1. Dashboard sends POST /api/agents/:id/command
   Body: { command_type, command, timeout_seconds, elevated }

2. Server creates command record in database (status = pending)

3. If agent is connected via WebSocket:
   -> Server sends command via WebSocket
   -> Status updated to "running"

4. If agent is offline:
   -> Command stays as "pending" (queued)

5. Agent receives command and executes it

6. Agent sends CommandResult back via WebSocket
   -> { id, exit_code, stdout, stderr, duration_ms }

7. Server updates database with result

Command States

State Description
pending Created, agent offline or not yet sent
running Sent to agent via WebSocket, awaiting result
completed Agent reported exit_code = 0
failed Agent reported exit_code != 0

[BUG] Server-Agent Command Type Mismatch

This is a critical known bug that prevents all remote command execution.

Root Cause:

The server's CommandPayload serializes command_type as a plain JSON string:

{"command_type": "powershell", "command": "Get-Process", ...}

The agent's CommandPayload expects command_type as a Rust enum (CommandType::PowerShell), which serde deserializes from an object or tagged format, not a bare string.

Result: Serde deserialization fails silently on the agent side. Commands are never executed. All commands remain in "running" state permanently because no CommandResult is ever sent back.

Fix Required: Either:

  • Change the server to serialize command_type in the enum format the agent expects, OR
  • Change the agent to accept plain string values for command_type

Claude Code Integration

Architecture

The agent includes a built-in Claude Code executor for running AI-assisted tasks.

  • Singleton: Global ClaudeExecutor via once_cell::Lazy
  • Working Directory: Restricted to C:\Shares\test\ only
  • Rate Limit: 10 tasks per hour (sliding window)
  • Max Concurrent: 2 simultaneous tasks
  • Default Timeout: 300 seconds (max 600)
  • Input Sanitization: Blocks & | ; $ ( ) < > \ \n \r`

Claude Task Command Format

The server sends:

{
  "type": "command",
  "payload": {
    "id": "uuid",
    "command_type": "claude_task",
    "command": "task description",
    "timeout_seconds": 300,
    "elevated": false
  }
}

[WARNING] This also suffers from the command type mismatch bug. The agent expects command_type to be an object for ClaudeTask:

{
  "claude_task": {
    "task": "...",
    "working_directory": "...",
    "context_files": [...]
  }
}

Exit Codes

Code Meaning
0 Task completed successfully
1 Task failed
124 Task timed out
-1 Executor error (rate limit, validation)

Agent Configuration

agent.toml Format

[server]
url = "wss://rmm-api.azcomputerguru.com/ws"
api_key = "SITE-CODE-1234"  # or grmm_xxxxx API key

[metrics]
interval_seconds = 60  # Range: 10-3600, default: 60
collect_cpu = true
collect_memory = true
collect_disk = true
collect_network = true

[watchdog]
enabled = true
check_interval_seconds = 30

[[watchdog.services]]
name = "ServiceName"
action = "restart"
max_restarts = 3
restart_cooldown_seconds = 60

Hardcoded Intervals

These values are currently not configurable via agent.toml:

Interval Value Notes
Heartbeat 30 seconds
Network state check 30 seconds Uses hash-based change detection
Connection idle timeout 90 seconds
Auth timeout 10 seconds
Reconnect delay 10 seconds
Command execution timeout 300 seconds Configurable per command

Deployed Agents

Hostname Agent ID (prefix) Version OS Status
ACG-M-L5090 97f63c3b-... 0.5.1 Windows 11 (26200) online
AD2 d28a1c90-... 0.5.1 Windows Server 2016 (14393) online
gururmm 8cd0440f-... 0.5.1 Ubuntu 22.04 offline
SL-SERVER 2585f6d5-... 0.5.1 unknown offline
SL-SERVER dff818e6-... 0.5.1 unknown online

Database

Connection Details

Parameter Value
Host 172.16.3.30
Port 5432
Database gururmm
User gururmm
Password 43617ebf7eb242e814ca9988cc4df5ad

Key Tables

Table Description
users User accounts (JWT auth, Argon2id hashing)
clients Client organizations
sites Physical locations with API keys
agents RMM agent instances
agent_state Latest agent state (network, metrics snapshot)
agent_updates Agent update tracking
alerts System alerts
commands Remote command execution log
metrics Performance metrics time series
policies Configuration policies
registration_tokens Agent registration tokens
watchdog_events Service monitoring events

Authentication

API Authentication (JWT)

  1. Send POST /api/auth/login with { email, password }
  2. Server validates credentials (Argon2id password hash)
  3. Returns JWT token (24-hour expiry)
  4. Include token in subsequent requests: Authorization: Bearer <token>

Admin Credentials:

Field Value
Email claude-api@azcomputerguru.com
Password ClaudeAPI2026!@#

Agent Authentication (API Key)

Two authentication modes:

  1. Direct API Key -- Agent sends grmm_xxxxx format key, server matches against api_key_hash (SHA256) in agents table
  2. Site-Based -- Agent sends site code (WORD-WORD-NUMBER format, e.g., DARK-GROVE-7839) combined with device_id, server looks up site and registers/matches agent

SSO (Optional)

  • Provider: Microsoft Entra ID
  • Client ID: 18a15f5d-7ab8-46f4-8566-d7b5436b84b6

Auto-Update System

Update Flow

1. Agent connects via WebSocket and sends its version in the auth payload

2. Server checks if a newer version is available for the agent's OS/architecture

3. If update needed:
   -> Server sends Update message with download_url and SHA256 checksum

4. Agent downloads the new binary from the download URL

5. Agent verifies the SHA256 checksum

6. Agent replaces its own binary and restarts

7. On reconnection, agent reports previous_version in auth payload

8. Server marks the update as completed

Download Location

  • Server Path: /var/www/gururmm/downloads/
  • Public URL: https://rmm-api.azcomputerguru.com/downloads/

Known Issues

CRITICAL

ID Type Description
1 [BUG] Command type mismatch between server (String) and agent (Enum) -- commands never execute
2 [TODO] Legacy heartbeat returns empty pending_commands (agents.rs line 334)
3 [TODO] Legacy command-result endpoint does not store results (agents.rs lines 354-360)
4 [SECURITY] CORS configured with AllowOrigin::Any -- should be restricted to known origins

MAJOR

ID Description
1 No command timeout enforcement on server side
2 No retry logic for failed WebSocket sends
3 Database inconsistency: agent shows "online" but command sends fail silently
4 Missing database indexes on frequently queried columns
5 No rate limiting on command submissions

MINOR

ID Description
1 Hardcoded intervals (heartbeat, network check) not configurable
2 Watchdog events logged but not stored in database
3 No log rotation configured
4 Unicode characters in agent output (should use ASCII per coding guidelines)

Development

Building

# Server
cd server && cargo build --release

# Agent (Windows, native service mode)
cd agent && cargo build --release

# Agent (Legacy mode for Windows 7 / Server 2008 R2)
cd agent && cargo build --release --features legacy --no-default-features

Testing

cargo test         # Run unit tests
cargo clippy       # Run linter
cargo fmt --check  # Check formatting

Deploying the Server

# On gururmm server (172.16.3.30)
systemctl stop gururmm-server
cp target/release/gururmm-server /opt/gururmm/
systemctl start gururmm-server
journalctl -u gururmm-server -f

Deploying the Agent

REM On target Windows machine
sc stop GuruRMM
copy gururmm-agent.exe "C:\Program Files\GuruRMM\gururmm-agent.exe"
sc start GuruRMM

File Structure

D:\ClaudeTools\projects\msp-tools\guru-rmm\
|
+-- agent/
|   +-- src/
|   |   +-- main.rs              # Entry point, CLI parsing, service install
|   |   +-- config.rs            # TOML config loading and validation
|   |   +-- claude.rs            # Claude Code executor (rate-limited singleton)
|   |   +-- service.rs           # Windows service handler (native-service feature)
|   |   +-- device_id.rs         # Hardware-based device ID generation
|   |   +-- transport/
|   |   |   +-- mod.rs           # Message types (AgentMessage, ServerMessage, CommandType enum)
|   |   |   +-- websocket.rs     # WebSocket client, reconnection, command execution
|   |   +-- metrics/
|   |   |   +-- mod.rs           # System metrics collection, network state hashing
|   |   +-- updater/
|   |       +-- mod.rs           # Self-update logic (download, verify, replace)
|   +-- deploy/                  # Deployment configs per site
|   +-- Cargo.toml               # v0.3.5, features: native-service, legacy
|
+-- server/
|   +-- src/
|   |   +-- main.rs              # Axum server setup, router, middleware
|   |   +-- api/
|   |   |   +-- mod.rs           # Route definitions and grouping
|   |   |   +-- agents.rs        # Agent management + legacy polling endpoints
|   |   |   +-- commands.rs      # Command dispatch and status tracking
|   |   |   +-- auth.rs          # JWT login, registration, user info
|   |   |   +-- clients.rs       # Client CRUD operations
|   |   |   +-- sites.rs         # Site management and API key regeneration
|   |   |   +-- metrics.rs       # Metrics query endpoints
|   |   +-- ws/
|   |   |   +-- mod.rs           # WebSocket handler, ServerMessage types, CommandPayload (String type)
|   |   +-- db/
|   |   |   +-- agents.rs        # Agent database operations
|   |   |   +-- commands.rs      # Command database operations
|   |   +-- auth/
|   |       +-- mod.rs           # JWT middleware and token validation
|   +-- Cargo.toml               # v0.2.0
|
+-- dashboard/                   # React frontend (if present)
|
+-- docs/
    +-- FEATURE_ROADMAP.md       # Complete feature plan (654 lines)
    +-- REMEDIATION_PLAN.md      # Security and code review (1277 lines)

Quick Reference

Item Value
Server URL https://rmm-api.azcomputerguru.com
WebSocket URL wss://rmm-api.azcomputerguru.com/ws
Internal Address 172.16.3.30:3001
Database PostgreSQL @ 172.16.3.30:5432/gururmm
Service Name gururmm-server (systemd)
Agent Service GuruRMM (Windows SCM)
Agent Config C:\ProgramData\GuruRMM\agent.toml
Agent Binary C:\Program Files\GuruRMM\gururmm-agent.exe
Downloads https://rmm-api.azcomputerguru.com/downloads/
Admin Email claude-api@azcomputerguru.com
SSO Client ID 18a15f5d-7ab8-46f4-8566-d7b5436b84b6

Document generated 2026-02-17. Source of truth for GuruRMM project reference.