All projects

AI agents & MCP

Beszel MCP

Ask your monitoring stack questions.

Query server health, metrics, Docker containers and alerts from Claude or any MCP client, with automatic token refresh.

Why I built it

Beszel already watches my servers. I wanted to ask about them in plain words instead of clicking through charts.

Architecture

How it fits together

AI client

  • Claude or any MCP app

beszel-mcp

  • Systems and stats

    CPU, RAM, disk, temps

  • Containers

  • Alerts

Beszel

  • Hub

    PocketBase API

  • Agents on each server

Documentation

From the README

Open on GitHub

A Model Context Protocol (MCP) server for Beszel — the lightweight server monitoring platform. Query your servers' health, metrics, containers, and alerts directly from Claude or any MCP-compatible client.

Features

ToolDescription
list_systemsAll monitored servers with status, CPU/memory/disk %, uptime
search_systemsFilter servers by name, host, status (PocketBase filter syntax)
get_system_statsDetailed CPU, RAM, swap, disk I/O, network, temperatures
list_docker_containersDocker/Podman containers — CPU, memory, health, network
list_alertsActive (triggered) alerts, or all configured alert rules

Prerequisites

  • Go 1.22+
  • A running Beszel hub
  • A Beszel user account (email + password)

Installation

git clone https://github.com/yourusername/beszel-mcp
cd beszel-mcp
go mod tidy
go build -o beszel-mcp .

Configuration

The server is configured entirely via environment variables:

VariableRequiredDescription
BESZEL_URL✅Beszel hub URL, e.g. http://localhost:8090
BESZEL_EMAIL✅Beszel user email
BESZEL_PASSWORD✅Beszel user password

Tip: Admin accounts can see all systems; regular users only see systems they own.

Claude Desktop Setup

Add the following to your claude_desktop_config.json:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "beszel": {
      "command": "/absolute/path/to/beszel-mcp",
      "env": {
        "BESZEL_URL": "http://localhost:8090",
        "BESZEL_EMAIL": "your@email.com",
        "BESZEL_PASSWORD": "yourpassword"
      }
    }
  }
}

Restart Claude Desktop. You should see the Beszel tools available in the tools menu.

Claude Code / Other MCP Clients

Run directly:

BESZEL_URL=http://localhost:8090 \
BESZEL_EMAIL=your@email.com \
BESZEL_PASSWORD=yourpassword \
./beszel-mcp

Or with environment file:

# .env
BESZEL_URL=http://localhost:8090
BESZEL_EMAIL=your@email.com
BESZEL_PASSWORD=yourpassword
env $(cat .env | xargs) ./beszel-mcp

Example Prompts

Once connected to Claude, try these:

  • "List all my servers and their current status"
  • "Which servers are down right now?"
  • "Show me the CPU and memory stats for my prod-web server"
  • "List all Docker containers on system abc123xyz"
  • "Are there any active alerts I should know about?"
  • "Find all servers with 'nginx' in the name"
  • "Which servers have status down or paused?"

Tool Reference

list_systems

Lists all systems accessible to the authenticated user.

Parameters:

  • status_filter (optional) — "up", "down", "paused", or "pending"

Example output:

Found 3 system(s):

### ✅ prod-web
  ID:      abc123xyz
  Host:    192.168.1.10:45876
  Status:  up
  OS:      Linux
  Agent:   v0.18.6
  CPU:     12.3%
  Memory:  45.1%
  Disk:    61.0%
  Load:    0.85 / 0.72 / 0.68
  Uptime:  14d 6h 22m

search_systems

Filter systems using PocketBase filter syntax.

Parameters:

  • filter (required) — Filter expression

Filter examples:

GoalFilter
Name contains "web"name~"web"
Exact name matchname="prod-db"
Specific statusstatus="down"
Host in subnethost~"10.0.0"
Down or pausedstatus="down"||status="paused"

get_system_stats

Detailed metrics for a single system.

Parameters:

  • system_id (required) — System record ID
  • resolution (optional) — Data granularity:
    • "1m" — most recent ~1 hour of 1-minute samples
    • "10m" — last ~12 hours (default)
    • "20m" — last ~24 hours
    • "120m" — last ~7 days
    • "480m" — last ~30 days

list_docker_containers

Lists Docker/Podman containers.

Parameters:

  • system_id (optional) — Limit to one system; omit for all systems

Columns: Name, CPU%, Memory (GB), Network (bytes/s), Health, Image

list_alerts

Shows alert rules and their triggered state.

Parameters:

  • all (optional, bool) — true = show all rules; false (default) = only triggered

Architecture

beszel-mcp/
├── main.go                  # Entry point, env config, server bootstrap
├── go.mod
├── internal/
│   ├── client/
│   │   └── beszel.go        # PocketBase REST client, auth token cache
│   └── tools/
│       └── tools.go         # MCP tool definitions and handlers
└── README.md

The client automatically handles JWT authentication and token refresh. Tokens are cached in-memory and refreshed proactively before expiry.

Security Notes

  • Credentials are passed via environment variables, never hardcoded
  • The JWT token is stored in memory only; never written to disk
  • Use a dedicated read-only Beszel user for the MCP server where possible
  • If your Beszel instance is behind a reverse proxy with TLS, use https:// in BESZEL_URL

AI agents & MCP

More like this