Skip to main content
Glama
mirenchaps
by mirenchaps

home-network-mcp

A personal MCP server that lets an LLM client (Claude Desktop, etc.) monitor my home network and home lab: which devices are online, whether key services are healthy, disk space, and uptime — across both my Windows Server 2022 home lab and a Raspberry Pi running Homebridge.

Alongside the MCP server, a Prometheus metrics exporter runs continuously, scraped by the home lab's own kube-prometheus-stack for dashboarding and alerting.

Why I built this

I wanted to understand how MCP actually works under the hood — not just use it, but build a server from scratch and see how tool schemas, async dispatch, and client/server message flow fit together. Wiring it up against my own home lab (a Windows Server 2022 environment) rather than a toy example forced me to deal with real problems: WinRM auth, parsing PowerShell's JSON output cleanly, timeouts on unreachable hosts, and so on.

Adding observability was a deliberate second layer — the MCP server is reactive (Claude asks, it answers), but a metrics exporter makes the monitoring continuous. Disk usage creeping up over weeks, a service that restarts every Tuesday because of Windows Update, a Pi that's been silently unreachable for hours — none of that is visible from on-demand polling alone.

It's also a deliberate split of responsibilities:

  • Python / MCP — protocol layer: tool definitions, schemas, async orchestration

  • PowerShell — automation layer for Windows targets: the actual Windows-native work (Get-Volume, Get-Service, WMI queries, Invoke-Command over WinRM)

  • Bash over SSH — automation layer for Linux targets: querying systemd, df, /proc/uptime on my Raspberry Pi

  • Prometheus + Grafana — observability layer: continuous metric collection, time-series storage, dashboarding and alerting

Status

scan_network is built and tested end-to-end on macOS against my home subnet, both via the MCP Inspector and Claude Desktop. The Windows-specific tools (check_service_health, check_disk_usage, check_uptime) are implemented but not yet verified against a live host — next step is pointing them at my Windows Server 2022 home lab over WinRM. The Raspberry Pi / Homebridge tools (check_pi_service, check_pi_disk_usage, check_pi_uptime) are newly added and not yet tested against the real Pi.

Tools exposed

Tool

Description

scan_network

Ping-sweeps a subnet, returns which hosts are up and their latency

check_service_health

Checks status of named Windows services on a host

check_disk_usage

Reports free/used space per volume on a Windows host, flags low free space

check_uptime

Returns last boot time and uptime for a Windows host

check_pi_service

Checks status of a systemd service (defaults to Homebridge) on the Pi over SSH

check_pi_disk_usage

Reports free/used space per mounted filesystem on the Pi, flags low free space

check_pi_uptime

Returns last boot time and uptime for the Pi

Metrics exposed

The exporter (exporter.py) continuously collects and serves the following Prometheus metrics:

Metric

Labels

Description

home_device_up

host

1 if the device responded to ping, 0 if unreachable

home_disk_free_ratio

host, volume

Fraction of disk space free (0.0–1.0) on Windows hosts

home_service_up

host, service

1 if the Windows service is running, 0 otherwise

home_uptime_seconds

host

System uptime in seconds for Windows hosts

home_pi_service_up

host, service

1 if the systemd service is active on the Pi

home_pi_disk_free_ratio

host, mount

Fraction of disk space free (0.0–1.0) on the Pi

home_pi_uptime_seconds

host

System uptime in seconds for the Pi

Requirements

  • Python 3.10+

  • PowerShell 7+ (pwsh) on PATH

  • mcp[cli] and prometheus_client — see requirements.txt

  • For remote hosts: WinRM enabled and reachable (Enable-PSRemoting), and the account running the server needs appropriate rights on target machines

  • For the Raspberry Pi: SSH key-based auth set up (ssh-copy-id pi@<pi-host>) — password auth is intentionally not supported

  • The home lab's kube-prometheus-stack scrapes both Deployments in-cluster; no external metrics account is needed

Setup

git clone https://github.com/mirenchaps/home-network-mcp.git
cd home-network-mcp
python3 -m venv .venv
source .venv/bin/activate  # or .venv\Scripts\activate on Windows
pip install -r requirements.txt
cp config.example.json config.json  # then edit with your own hosts

Config

config.json (gitignored — never committed) tells both the MCP server and the exporter which hosts and services to monitor:

{
  "subnet": "192.168.1",
  "known_hosts": [
    { "name": "HOMELAB-DC01", "watch_services": ["DNS", "NTDS"] }
  ],
  "disk_warn_threshold_percent": 15,
  "pi": {
    "host": "raspberrypi.local",
    "user": "pi",
    "ssh_key_path": null,
    "watch_services": ["homebridge"]
  }
}

Running the MCP server

python server.py

Running the metrics exporter

In a separate terminal (or as a Windows service):

python exporter.py

Metrics are served at http://localhost:8000/metrics.

In-cluster Prometheus scraping

Both Deployments are scraped by the home lab's kube-prometheus-stack. Each one ships a ServiceMonitor rendered by the shared Helm chart in home-lab-gitops, enabled per app via metrics.enabled in that app's values file.

App

Port

Path

Metrics

home-network-mcp

8000

/metrics

home_device_up, home_service_up, disk/uptime gauges

home-network-mcp-server

8001

/metrics

mcp_tool_calls_total, mcp_tool_call_duration_seconds

The ServiceMonitor must carry release: prometheus -- that Prometheus only adopts ServiceMonitors with that label, and one without it is ignored silently.

Previously the exporter's metrics went to Grafana Cloud via a Grafana Alloy agent running directly on the Windows box. That was dropped once the app moved into Kubernetes: two metrics destinations meant two places to look, and the Alloy config still described scraping localhost:8000 on a host the app no longer ran on.

macOS-specific notes

PowerShell isn't native to macOS but runs fine via pwsh:

brew install --cask powershell@preview

scan_network works locally on macOS since it only uses cross-platform .NET networking APIs. check_service_health, check_disk_usage, and check_uptime call Windows-only cmdlets and will only work against a remote Windows host passed via computer_name.

Testing locally with the MCP Inspector

mcp dev server.py

This launches a local web UI where you can call each tool directly and inspect the generated schema and raw JSON-RPC traffic.

Register with Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "home-network": {
      "command": "/absolute/path/to/home-network-mcp/.venv/bin/python3",
      "args": ["/absolute/path/to/home-network-mcp/server.py"]
    }
  }
}

Project structure

home-network-mcp/
├── server.py                   # MCP server + tool definitions
├── runner.py                   # Shared async helpers (pwsh + SSH)
├── exporter.py                 # Prometheus metrics exporter
├── config.example.json         # Example host inventory (copy to config.json)
├── scripts/
│   ├── Get-DeviceStatus.ps1    # subnet ping sweep
│   ├── Get-ServiceHealth.ps1   # Windows service status
│   ├── Get-DiskUsage.ps1       # disk/volume free space (Windows)
│   ├── Get-SystemUptime.ps1    # uptime / last boot (Windows)
│   └── pi/
│       ├── check-service.sh    # systemd service status
│       ├── check-disk.sh       # disk/volume free space (Linux)
│       └── check-uptime.sh     # uptime / last boot (Linux)
└── requirements.txt

Notes / limitations

  • Credentials are never hardcoded — config.json is gitignored, and WinRM/Homebridge/SSH credentials are injected from Kubernetes Secrets.

  • This is a personal project for my own home lab, not hardened for production or multi-tenant use — no auth on the PowerShell remoting beyond standard WinRM, no rate limiting, no retry logic beyond a basic timeout.

  • Local (non-domain) WinRM setups may need TrustedHosts configured for cross-machine calls without Kerberos.

  • Tested against Windows Server 2022 and Windows 11 hosts on PowerShell 7.4.