Skip to main content
Glama
Plawn

victoriametrics-mcp

by Plawn
README.md
# victoriametrics-mcp

An [MCP](https://modelcontextprotocol.io) server that lets an LLM agent query
**VictoriaMetrics** (PromQL/MetricsQL) and **VictoriaLogs** (LogsQL) over stdio.

Because it speaks the Prometheus HTTP API, it also works against Prometheus
itself for the `vm_*` metric tools.

Built with [Bun](https://bun.sh) and TypeScript; compiles to a single
self-contained binary with no runtime dependency.

## Why another exporter-ish tool

Raw Prometheus JSON is a poor fit for a model's context window: a single range
query easily returns tens of thousands of tokens of repeated label sets and
float noise. Every tool here returns **compact text** instead:

- series are rendered as `metric{label="value"}`, sorted and deduplicated;
- values are rounded to 4 significant digits;
- timestamps are second-precision UTC (`2026-08-13T10:30:00Z`);
- range results are summarised (`min/max/avg/last`) and evenly subsampled;
- results are bounded by explicit `limit` / `max_series` / `max_points` args,
  and truncation is always announced so the model knows to raise the limit;
- log lines drop ANSI colour codes and Docker/Vector bookkeeping fields.

## Install

```bash
bun install          # never npm
bun run build        # -> dist/victoriametrics-mcp
```

Or with [`just`](https://github.com/casey/just): `just build`.

## Configuration

Everything is read from the environment, so one binary serves any deployment.

| Variable | Default | Meaning |
|---|---|---|
| `VM_URL` | `http://127.0.0.1:8428` | VictoriaMetrics (or Prometheus) base URL |
| `VL_URL` | `http://127.0.0.1:9428` | VictoriaLogs base URL |
| `VM_TIMEOUT_MS` | `30000` | Per-request timeout, both backends |
| `VM_BEARER_TOKEN` / `VL_BEARER_TOKEN` | — | Sent as `Authorization: Bearer …` |
| `VM_USER` + `VM_PASSWORD` | — | HTTP basic auth (same for `VL_*`) |

If a bearer token is set it takes precedence over basic auth.

## Registering with a client

Claude Code, user scope:

```bash
claude mcp add --scope user victoriametrics -- /path/to/dist/victoriametrics-mcp
```

Any other MCP client, via `mcpServers` config:

```json
{
  "mcpServers": {
    "victoriametrics": {
      "command": "/path/to/dist/victoriametrics-mcp",
      "env": { "VM_URL": "http://127.0.0.1:8428" }
    }
  }
}
```

## Tools

### Metrics — VictoriaMetrics

| Tool | Purpose | Key arguments |
|---|---|---|
| `vm_query` | Instant PromQL query — the current value per series | `query`, `time`, `limit` |
| `vm_query_range` | Range query — how a metric evolved | `query`, `start`, `end`, `step`, `max_series`, `max_points` |
| `vm_series` | Discover which series exist | `match[]`, `start`, `end`, `limit` |
| `vm_label_values` | List values of a label (`__name__` lists metric names) | `label`, `match[]`, `start`, `end`, `limit` |
| `vm_targets` | Scrape target health — job, instance, health, last error | `only_unhealthy` |

### Logs — VictoriaLogs

| Tool | Purpose | Key arguments |
|---|---|---|
| `vl_query` | Run a LogsQL query | `query`, `limit`, `max_message_chars` |

### Time arguments

Every `time` / `start` / `end` argument accepts:

- `now` (or empty),
- a relative offset: `-12h`, `-30m`, `-7d`, `-2w`,
- an epoch in seconds: `1786609796`,
- an RFC3339 timestamp: `2026-08-13T10:30:00Z`.

`step` accepts a duration (`30s`, `1m`, `1h`) or bare seconds. When omitted,
`vm_query_range` picks a step yielding roughly 60 points over the range.

## Example output

`vm_query` with `query=up`:

```
10 series at 2026-08-13T08:33:49Z
up{cluster="mini-box",instance="traefik:8082",job="traefik"} = 1
up{cluster="mini-box",instance="localhost:8428",job="victoriametrics"} = 1
…
```

`vm_query_range` with `query=sum(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)`:

```
range -2h → now, step 120s

2 series

{instance="mini-box"}
  min=11.01 max=11.64 avg=11.56 last=11.34 (5 of 61 points shown)
  2026-08-13T06:34:00Z  11.64
  …
  2026-08-13T08:34:00Z  11.34
```

`vm_targets`:

```
10 targets, 1 not up
DOWN    postgres-exporter / arcle_postgres-exporter:9187
UP      traefik / traefik:8082
…
```

## Development

```bash
just dev          # run from source over stdio
just typecheck    # tsc --noEmit
just test         # unit tests (bun test)
just smoke        # build, then drive the binary with real MCP JSON-RPC
```

`just smoke` performs a genuine end-to-end check: it starts the compiled binary,
sends `initialize`, `notifications/initialized`, `tools/list` and two
`tools/call` requests on stdin, and prints the JSON-RPC replies. It needs a
reachable `VM_URL`.

## License

MIT