Skip to main content
Glama
wtnb75
by wtnb75

rrdmcp

An MCP server that exposes Munin's RRD metric data to an LLM, so you can ask questions about your monitored hosts in plain language instead of writing rrdtool incantations or one-off scripts. Supports both stdio and streamable-http transports.

What it's for

Munin collects rich time-series data (CPU, memory, disk, network, custom plugins...) but analyzing it usually means digging through graph images or writing throwaway scripts against the RRD files. rrdmcp exposes that data directly to an LLM through a handful of tools, so you can just ask:

  • "Which days this month had the highest CPU usage?"

  • "Free memory has been dropping — is that a trend or a one-off?"

  • "fail2ban's ban count spiked a few days ago — does that line up with higher process counts or TCP resets on this host?"

  • "Is disk usage on this host trending toward full, and how soon?"

The server deliberately stays "dumb" about interpretation: it discovers hosts/plugins/fields, fetches raw or lightly-aggregated series (bucketed averages, whole-range summaries, top-N rankings), and renders graphs — but leaves judgment calls (what counts as "high", whether two metrics are actually related, what to do about it) to the LLM doing the analysis. This keeps the tool surface small and lets the LLM reason over real numbers instead of a pre-baked interpretation.

Related MCP server: Datadog MCP Server

Setup

uv sync

Requires the rrdtool command on PATH (already present on any host running Munin, since it's a dependency of munin-node/munin).

Configuration (environment variables)

Variable

Default

Description

MUNIN_RRD_BASE_PATH

/var/lib/munin

Root directory of the RRD files

MUNIN_DATAFILE_PATH

${MUNIN_RRD_BASE_PATH}/datafile

Location of Munin's datafile (config cache)

RRDMCP_TRANSPORT

stdio

Transport to serve: stdio or streamable-http

RRDMCP_HOST

127.0.0.1

Bind host for streamable-http

RRDMCP_PORT

8000

Bind port for streamable-http

SAR_BASE_PATH

(unset — sar support disabled)

Root directory of sar logs, laid out as <group>/<host>/saXX (requires the sadf command on PATH, from the sysstat package)

WTMP_BASE_PATH

(unset — wtmp/btmp support disabled)

Root directory of wtmp/btmp logs, laid out as <group>/<host>/{wtmp,btmp} (rotated generations like wtmp.1/wtmp.2.gz are also read; requires the utmpdump command on PATH, from the util-linux package)

Running

uv run rrdmcp

Transport can also be selected with CLI flags, which take precedence over the environment variables above:

uv run rrdmcp --transport streamable-http --host 0.0.0.0 --port 8000

MCP client configuration example

{
  "mcpServers": {
    "rrdmcp": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/rrdmcp", "rrdmcp"],
      "env": {
        "MUNIN_RRD_BASE_PATH": "/var/lib/munin"
      }
    }
  }
}

Running in Docker

docker build -t rrdmcp .

Since this is a stdio transport, mount the directory holding the real Munin data read-only and keep stdin open with -i:

docker run --rm -i -v /var/lib/munin:/var/lib/munin:ro rrdmcp

MCP client configuration example (Docker):

{
  "mcpServers": {
    "rrdmcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "/var/lib/munin:/var/lib/munin:ro",
        "rrdmcp"
      ]
    }
  }
}

If you mount MUNIN_RRD_BASE_PATH at a different path, add -e MUNIN_RRD_BASE_PATH=... to docker run (the image default is /var/lib/munin).

Tools

  • list_hosts — list every discovered (group, host) pair

  • list_plugins(group, host) — list plugins for a host

  • list_fields(group, host, plugin) — list a plugin's fields (label, type, thresholds, etc.)

  • get_metadata(group, host, plugin, field?) — detailed metadata for a whole plugin, or a single field

  • fetch_series(group, host, plugin, field, start, end, resolution?, summary?, top_n?, top_by?, order?) — fetch time series data. start/end accept a unix timestamp, an ISO 8601 timestamp (e.g. 2026-09-07T12:00:00Z; naive timestamps are treated as UTC), or any string rrdtool understands (-1d, now, etc.). Fields backed by the sar data source only accept a unix timestamp or an ISO 8601 timestamp for start/end (rrdtool-style relative expressions like -1d are munin-only).

    • With no options, returns raw points as-is

    • resolution (seconds) aggregates into UTC-epoch-aligned buckets (avg/min/max/count) instead of raw points

    • summary=true aggregates the whole range into a single summary (avg/min/max/count); cannot be combined with resolution

    • top_n (requires resolution) returns only the top N buckets sorted by top_by ("avg"/"min"/"max", default "avg") in order ("desc"/"asc", default "desc"); total_buckets reports the count before filtering, so you can ask things like "the 10 days with the highest average" or "the 5 days with the lowest minimum" directly

  • render_graph(group, host, plugin, fields, start, end, width?, height?) — render a PNG graph overlaying the given fields

  • list_login_sources() — list every discovered (group, host, kind) triple from wtmp/btmp logs (kind is "wtmp" or "btmp")

  • list_login_events(group, host, kind, start, end, limit?) — fetch raw login-event records for one host (no session pairing or duration computed), sorted ascending by timestamp. start/end accept a unix timestamp or an ISO 8601 timestamp only. If limit is given, only the most recent limit events are returned; total_events reports the count before truncation

Known limitations

  • If datafile is unavailable, discovery falls back to best-effort parsing of RRD filenames, losing precision on host/plugin boundaries and all metadata

  • Graph rendering is a simplified version — it doesn't reproduce Munin's own threshold bands, stacking, CDEFs, etc.

  • sar support requires log files pre-aggregated under SAR_BASE_PATH/<group>/<host>/saXX (e.g. via rsync from each host's /var/log/sa); it does not read /var/log/sa directly or collect data itself

  • sar plugin/field discovery only recognizes activities matching a fixed set of sadf -j JSON shapes (scalar dicts, or arrays keyed by one of cpu/disk-device/iface/filesystem/number); activities matching a recognized shape but missing from sar_index.SAR_ACTIVITY_META/SAR_FIELD_META show up without a human-friendly title/label, while activities with an unrecognized shape are not discovered at all

  • wtmp/btmp support requires log files pre-aggregated under WTMP_BASE_PATH/<group>/<host>/{wtmp,btmp} (e.g. via rsync) and the utmpdump command on PATH; it returns raw per-record events only — no login/logout session pairing, duration computation, or wtmpdb (SQLite-based) support

Available Tools

6 tools
fetch_seriesA

Fetch time series data for a single field.

start/end accept a unix timestamp or any string rrdtool understands (e.g. "-1d", "now").

If resolution (seconds) is given, points are aggregated into UTC-epoch-aligned buckets of that size (avg/min/max/count) instead of returning every raw sample — use this for long time ranges to avoid returning hundreds of raw points.

If summary is true, the whole range is aggregated into a single avg/min/max/count instead of buckets or raw points. Cannot be combined with resolution.

If top_n is given (requires resolution), only the N buckets with the highest (or, with order="asc", lowest) top_by value ("avg", "min", or "max") are returned, sorted by that value; total_buckets in the result reports how many buckets existed before filtering.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYes
hostYes
fieldYes
groupYes
orderNodesc
startYes
top_nNo
pluginYes
top_byNoavg
summaryNo
resolutionNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It explains that resolution aggregates into UTC-aligned buckets with avg/min/max/count, summary collapses the whole range, top_n filters and sorts buckets, and the result includes total_buckets. This goes well beyond a simple 'fetch' statement, though it does not fully specify the response structure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently organized: a one-sentence purpose statement followed by compact, scannable sections for each option. Every sentence adds operational value and there is no filler. Parameter names are consistently formatted, aiding quick reference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 11 parameters and no output schema, the description covers the important invocation logic and combination constraints (summary vs resolution, top_n requiring resolution, order/top_by semantics). It even mentions the total_buckets field in the result. The only notable gap is that the exact return format is not described, though the aggregation semantics make it largely inferable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It defines start/end input formats (unix timestamp or rrdtool strings), resolution, summary, top_n, order, and top_by semantics with examples and constraints. However, the identifiers group, host, and plugin are not explicitly explained, leaving some parameters to be inferred from domain knowledge.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with 'Fetch time series data for a single field,' a specific verb and resource that clearly differentiates it from siblings like list_hosts or get_metadata. The 'single field' qualifier adds precision about what data is returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong conditional guidance for parameters ('use this for long time ranges to avoid returning hundreds of raw points', 'Cannot be combined with resolution'), but it does not explicitly say when to use fetch_series versus sibling tools such as render_graph or get_metadata. The usage context is mostly implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_metadataB

Get metadata for a plugin, or a single field within it if field is given.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYes
fieldNo
groupYes
pluginYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of disclosing behavior. It clearly implies a read-only operation and explains the optional field-scoping behavior, but it does not describe what metadata is returned, how errors are handled, or how output is structured.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one tightly written sentence with no filler. The primary action is front-loaded, and the optional field behavior is integrated clearly without burrying the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is too sparse for a tool with no output schema, no annotations, and 0% schema description coverage. It omits the meaning of required parameters `group` and `host`, does not describe the return value, and gives no indication of how this relates to sibling tools like list_fields or fetch_series.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains that `field` selects a single field within the plugin and implies `plugin` is the metadata target, but it says nothing about the required `group` and `host` parameters, leaving an agent without enough context to populate them correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: get metadata for a plugin, with a conditional for a single field. It is specific enough to distinguish the main action from siblings like render_graph and fetch_series, though it does not explicitly differentiate itself from list_plugins or list_fields.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to prefer this tool over alternatives. The conditional 'if `field` is given' describes behavior, not selection criteria, and there is no mention of situations where list_fields or list_plugins would be more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_fieldsC

List fields for a given plugin.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYes
groupYes
pluginYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden of behavioral disclosure. 'List' implies a read-only operation, but the description does not clarify whether group/host are used for scoping or authentication, whether results are limited, or whether the operation has any side effects. This is minimal transparency beyond the operation name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler or repetition. It is concise and to the point, though its brevity contributes to the lack of contextual detail elsewhere.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with three required parameters, no schema descriptions, and no annotations, this description is too sparse to be complete. The output schema may cover return values, but the roles of host/group, the selection conditions, and behavioral expectations are all missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate for the undocumented parameters. It adds meaning only to 'plugin' by identifying it as the thing whose fields are being listed; 'host' and 'group' remain semantically unexplained. This does not adequately compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The phrase 'List fields for a given plugin' names a specific operation and resource, and it is reasonably distinguishable from sibling tools like list_plugins and list_hosts. However, it does not explain why 'group' and 'host' are also required, leaving the exact scope of the tool partially underspecified.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance about when to use this tool instead of siblings such as render_graph, get_metadata, or fetch_series. No prerequisites, exclusions, or selection conditions are provided, so the agent is left to infer usage from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_hostsA

List all (group, host) pairs discovered from the Munin datafile.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden. 'List all' signals a read-only, exhaustive enumeration, and 'discovered from the Munin datafile' clarifies the data source. It does not mention caveats like missing datafiles or performance, but the read-only nature is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no redundant wording. Every word adds information: the operation, the output shape, and the data source.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple parameterless enumeration tool with an output schema available. The description names the exact result and source, which is sufficient for an agent to select and invoke it correctly. No additional prerequisites or alternatives are necessary for this straightforward operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema is empty, so there is no parameter detail for the description to add. The description appropriately focuses on what the tool returns rather than arguments.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the action ('List'), the resource ('(group, host) pairs'), and the data source ('Munin datafile'). It differentiates from siblings like list_plugins and list_fields by naming the specific pair type, though it does not explicitly call out the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage context is implied: use this tool when you need all discovered group-host pairs from the Munin datafile. However, it provides no explicit guidance about when not to use it or which sibling tool to prefer for other listing needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pluginsB

List plugins for a given host.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYes
groupYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'List' signals a read-only operation, which is transparent, but there is no detail about side effects, permissions, failure behavior, or how the host/group scope is interpreted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler words. It efficiently states the core operation and scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple and has an output schema, so return details are covered elsewhere. However, the description omits the role of the required 'group' parameter and gives no usage routing guidance, leaving moderate gaps for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It clarifies that host is the target of the listing, but says nothing about 'group' or how host and group relate, leaving a required parameter semantically unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List'), a resource ('plugins'), and a scope ('for a given host'). It distinguishes itself from siblings like list_hosts and list_fields, though what 'plugins' means precisely is left vague.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus alternatives such as render_graph, list_hosts, or fetch_series. The description implies a use case but provides no explicit context, exclusion, or selection condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_graphC

Render a PNG graph overlaying the given fields of a plugin.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYes
hostYes
groupYes
startYes
widthNo
fieldsYes
heightNo
pluginYes

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the output is a PNG graph but does not mention side effects, required permissions, behavior with invalid fields, time-range handling, or whether the operation is read-only. The description lacks the added context needed to understand the tool's runtime behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It states the action, output format, and data source efficiently. Every part earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter, 6-required tool with no annotations and no output schema, a single-sentence description is insufficient. It doesn't explain what 'start' and 'end' refer to, what values 'group' and 'host' expect, or how fields are specified. An agent would need to guess at most of the required inputs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It identifies 'fields' and 'plugin' as the data to plot, but says nothing about 'group', 'host', 'start', 'end', 'width', or 'height'. The description adds minimal meaning beyond the schema's parameter names and leaves several parameters ambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Render') and a concrete resource ('PNG graph'), and mentions the data source ('given fields of a plugin'). This makes the tool's role clear and differentiates it from sibling listing/fetch tools, though it doesn't explicitly name a sibling. It stops short of a 5 because it does not draw an explicit contrast with related tools like fetch_series.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to use this tool versus alternatives such as fetch_series or list_fields. No prerequisites, constraints, or exclusions are stated. The only usage signal is the inherent purpose implied by the verb, which is not enough to qualify as explicit guidelines.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedfetch_series
    • First observedget_metadata
    • First observedlist_fields
    • First observedlist_hosts
    • First observedlist_plugins
    • First observedrender_graph

TDQS

A3.7/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct level or aspect of the data hierarchy: hosts, plugins, fields, metadata, series data, and rendered graphs. There is no meaningful overlap between tools, and descriptions make the boundaries clear.

Naming Consistency5/5

All tool names follow the same snake_case verb_noun pattern, with list_* for enumeration, get_/fetch_ for retrieval, and render_ for graph generation. The naming is predictable and consistent across the whole set.

Tool Count5/5

With 6 tools, the set is well-scoped for a read-only RRD/Munin data access server. Each tool covers an essential operation without unnecessary redundancy or bloat.

Completeness5/5

The tool set covers the full exploration and retrieval workflow: discover hosts, list plugins, list fields, fetch metadata, fetch time series data, and render graphs. There are no significant dead ends or missing operations for the apparent purpose of reading monitoring data.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with Datadog's observability platform via natural language, covering metrics, logs, APM, monitors, dashboards, incidents, and infrastructure.
    1,127 npm
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides read-only access to TacticalRMM remote monitoring and management instances via the MCP protocol. It enables querying agents, clients, alerts, checks, and other RMM data through natural language.
    22
    10 npm
    AGPL 3.0