Engineering Deep Dive

Can You Build Your Own RMM with Claude Code?

I used Claude Code to build a proof-of-concept Remote Monitoring and Management tool without writing a single line of code myself. Here is the architecture, the features, and what I learned along the way.

Gary Goodson
Gary Goodson
March 2026

Why Build an RMM?

Every MSP relies on an RMM. It is the backbone of how we monitor devices, push scripts, manage patches, and respond to issues. But most of us treat these tools as black boxes. We log in, run our scripts, and move on.

I wanted to understand what actually happens under the hood. How does the agent authenticate? How do commands get from the dashboard to a device in real time? What does it take to build something like this from scratch?

So I decided to build one. The twist: I did not write a single line of code. Every file, every class, every line of C# was generated by Claude Code, Anthropic's AI coding agent. My starting point was screenshots of a commercial RMM tool as a visual reference. I showed them to Claude Code and said "this is the sort of thing I want." From there I steered the architecture, reviewed what came back, and pushed it in the right direction. Claude Code did all the typing. I called the project Grenadier.

Platform Architecture

A three-tier design: a Windows agent on each endpoint, a central server, and a browser-based admin dashboard. Everything communicates over HTTPS and SignalR.

Admin Dashboard
Blazor WebAssembly
Browser-based, JWT auth, real-time updates
HTTPS + SignalR WebSocket
Grenadier Server
ASP.NET Core 9.0 + SignalR Hub
JWT Auth Rate Limiting RBAC
EF Core ORM
SQL Server
Devices, metrics, jobs, customers
HTTPS + SignalR • JWT Bearer Token
Windows Agent
.NET Worker Service
Runs as Local System
Windows Agent
.NET Worker Service
Runs as Local System
More Agents...
One per managed device
Admin Dashboard
Blazor WASM
Grenadier Server
ASP.NET Core + SignalR
Agent
Windows
Agent
Windows

How the Pieces Connect

The magic glue is SignalR. It gives you persistent, bidirectional communication over WebSockets (with automatic fallback to long polling). That means the server can push a command to an agent instantly, and the agent can stream results back in real time.

Every agent connects to the server's AgentHub on startup. The server tracks which SignalR connection belongs to which device, so when an admin clicks "Run Script" in the dashboard, the server knows exactly which WebSocket to send the command down.

The dashboard is a Blazor WebAssembly app. It runs entirely in the browser, connects to the same SignalR hub as the agents, and receives live updates. When an agent sends a metrics payload, the dashboard sees it within milliseconds.

All of this was generated by Claude Code. I described the communication model I wanted, and it produced the SignalR hub, the agent connection logic, and the dashboard bindings. I reviewed the output, pointed out issues, and asked for changes, but the code itself was entirely AI-generated.

What It Can Do

Even as a proof of concept, the feature set covers the core of what you would expect from a commercial RMM.

Real-Time Monitoring

CPU, memory, disk, and network metrics collected every 30 seconds. Hardware inventory via WMI including BIOS, TPM status, and serial numbers.

Interactive Shell

Open a live PowerShell session on any device. stdin/stdout piped through SignalR in real time. Like SSH, but through your browser.

Remote Control

Live screen capture with mouse and keyboard injection. Multi-monitor support with monitor switching. All session-validated server-side.

File Management

Browse, upload, download, rename, and delete files on remote devices. Create directories. All from the dashboard.

Process & Service Control

List running processes with CPU and memory usage. Kill processes, adjust priority. Start, stop, and restart Windows services.

Software Inventory

Enumerate installed software from the Windows registry. Track publisher, version, install date, and architecture. Trigger uninstalls remotely.

Device Health Dashboard

At-a-glance health summary across all customers. Online/offline status, device counts, and quick access to offline devices that need attention.

Registry Editor

Browse, read, write, rename, and delete registry keys and values remotely. Full support for all value types including multi-string.

Multi-Tenancy

Customer-based device grouping with separate enrollment tokens. Each customer has their own agent secret, hashed with BCrypt.

The Platform in Action

Every screen you see here was generated by Claude Code. Click any screenshot to enlarge.

Grenadier RMM Dashboard

Dashboard overview

The main dashboard shows customers, device health at a glance, and a list of offline devices that need attention. Everything updates in real time over SignalR.

Device detail with metrics and hardware info

Device detail and live metrics

CPU, memory, disk, and network metrics with sparkline charts. Hardware inventory, device info, and an activity log showing connection history and script runs.

Remote control session

Remote control

Live screen capture with mouse and keyboard input. Multi-monitor support with a monitor picker at the top. FPS counter and resolution info shown in real time.

Interactive PowerShell shell session

Interactive shell

A live PowerShell session slides up from the bottom of the device view. stdin and stdout piped through SignalR. Like SSH, but in the browser.

Remote task manager

Task Manager

Remote service manager

Service Manager

Remote file browser

File Browser

Software inventory

Software Inventory

Remote registry editor

Registry Editor

Security Model

An RMM has the keys to the kingdom. If the security model is wrong, nothing else matters.

Agent Authentication Flow

1
Agent starts up

The agent reads its server URL and secret from local config, then sends an AgentAuthRequest to the server over HTTPS with its hostname and hardware info.

2
Server verifies identity

On first connection, the server registers the device and BCrypt-hashes the secret. On subsequent connections, it verifies the secret against the stored hash.

3
JWT issued

The server issues a JWT with a 4-hour expiry, the agent role claim, and the device ID. This token is used for all subsequent communication.

4
SignalR connection established

The agent opens a SignalR connection using the JWT as its access token. Every hub method invocation is validated against the token's role and claims.

5
Periodic telemetry begins

The agent starts sending metrics every 30 seconds, software inventory every hour, and Windows Update data every 12 hours.

Security Controls

JWT + Role-Based Access

Agents and admins get separate JWTs with different role claims. Every SignalR hub method checks IsAgent() or IsAdmin() before executing. Admin API endpoints require [Authorize(Roles = "admin")].

Session Ownership Validation

Remote control and shell sessions are tracked server-side with a RemoteSessionTracker. Before relaying any mouse, keyboard, or shell input to an agent, the server verifies the requesting admin owns that session. This prevents one admin from hijacking another's session.

Rate Limiting & Size Guards

Auth endpoints are rate-limited to 10 attempts per IP per minute. Script content is capped at 512 KB. Script output is truncated at 2 MB. Metrics payloads are limited to 5 MB.

HTTPS Everywhere

All communication is encrypted in transit. The server enforces HTTPS redirection and HSTS in production. Agent secrets and JWTs never travel over plaintext.

BCrypt Password Hashing

Admin passwords and agent secrets are hashed with BCrypt before storage. Raw secrets are never persisted. Enrollment tokens use a separate, purpose-specific mechanism.

Security Headers

X-Content-Type-Options: nosniff, X-Frame-Options: DENY, strict referrer policy, and a permissions policy that disables camera, microphone, and geolocation APIs.

CORS Lockdown

Only configured origins can make requests to the API. The Blazor WASM frontend uses JWT bearer tokens, not cookies, which avoids the entire class of CSRF vulnerabilities.

Session-Scoped Tokens

Admin JWTs are stored in sessionStorage, not localStorage. Close the browser tab and the session ends. Token expiry is checked before every API call.

Multi-Tenant Isolation

Each customer has their own BCrypt-hashed agent secret and enrollment token. Devices are scoped to their customer. No cross-tenant data access exists in the query layer.

Tech Stack

Built entirely on .NET 9. One language, one ecosystem, across server, agent, and frontend.

Server

  • ASP.NET Core 9.0 with Kestrel
  • SignalR for real-time bidirectional communication
  • Entity Framework Core 9.0 with SQL Server
  • JWT Bearer authentication middleware
  • Rate limiting middleware (fixed window)

Windows Agent

  • .NET Worker Service running as a Windows Service
  • SignalR Client with automatic reconnect
  • Performance Counters and WMI for system data
  • System.Drawing for screen capture
  • Win32 API for input injection and process impersonation
  • WiX Toolset MSI installer for deployment

Dashboard

  • Blazor WebAssembly (.NET in the browser)
  • SignalR JS Client for real-time updates
  • JS Interop for sessionStorage and DOM access
  • HttpClient with JWT headers
  • Component-based UI with Razor syntax

Why .NET for Everything?

Using the same language and runtime across the server, agent, and frontend means shared models and contracts. The Grenadier.Core project contains all the message types, and both the server and agent reference it directly. No code generation, no keeping two schemas in sync, no serialisation mismatches.

SignalR also works seamlessly across all three tiers. The server defines hub methods once, and both the .NET agent and the Blazor frontend call them using the same strongly-typed contracts. Adding a new command means defining the message in Core, handling it in the hub, wiring it up in the agent, and adding a button in the dashboard. One language the whole way through.

This consistency also made the AI-driven workflow smoother. Because Claude Code only had to think in one language and one framework, it kept the architecture coherent across all four projects without me having to constantly re-explain context.

The Verdict

Can you build your own RMM with Claude Code? Yes, genuinely. Should you ship it? That is a different question.

What I Learned

I have been building software for 30 years. The MSP side of things is newer for me, only since 2021, but writing code is what I have done my entire career. So when I say Claude Code built this entire project, I am not saying that from the perspective of someone who could not have written it themselves. I am saying it because I wanted to see what happens when you take an experienced developer out of the driver's seat and let AI handle the implementation.

The answer: it works remarkably well, but it is not magic. My three decades of experience were still doing heavy lifting. I knew what a good SignalR architecture looks like. I knew to push back when the auth model was not right. I knew which corners could be cut in a proof of concept and which ones could not. Claude Code wrote every line of code, but the decisions behind that code were mine.

The speed was the real eye-opener. Building something like this from scratch would have taken me months. Not because the AI is smarter, but because it never gets tired, never loses context, and never has to look up the syntax for a WMI query.

The Bottom Line

Would I try to productionise this? Absolutely not. I fed Claude Code screenshots of a commercial RMM as a visual reference, and the result reflects that. The UI, the layout, the feel of it is heavily influenced by what I showed it. Shipping that would be a fast track to a legal conversation I do not want to have.

For a production MSP? Use the established tools. They have had years of hardening, compliance certifications, and teams dedicated to patching vulnerabilities at scale.

But as a proof of concept, this was one of the most valuable exercises I have done. It showed me just how much AI-assisted development can accelerate the journey from idea to working prototype.

The experience matters, though. Claude Code is a force multiplier, not a replacement for knowing what you are doing. The more you bring to the conversation, the better the output. If you have the domain knowledge and the architectural instinct, the AI removes the bottleneck of typing it all out yourself.

Want to talk shop?

Whether it is AI-assisted development, RMM architecture, or how we approach technology for our clients, I am always happy to chat.