spoor

Find where the failure started.

Spoor is an open-source MCP server for VictoriaMetrics, VictoriaLogs and VictoriaTraces. Your AI agent asks what changed. Spoor answers in a few hundred tokens, with the cause on top and the echoes labelled.

Version 0.2.1. Apache-2.0. Read-only, no LLM inside, same input gives the same answer.

$ spoor what-changed --since 30m
payment Failures start here, in "POST /charge"
payment New error: "charge failed: card processor…"
payment Error rate up: 0.2% → 40.5%
checkout Error spiking: "call to payment.Charge failed"
originates in payment
coverage metrics ok, logs ok, traces ok

Every caller of a broken service lights up. Spoor tells them apart.

With only raw query tools, an agent has to decide what to query, work out what normal looks like, page through results and guess which red service is the cause. It burns tool calls and often blames the loudest symptom, or an error that was always there.

Spoor does that work in plain, deterministic Go and hands the agent a short ranked answer it can check.

Across all three signals

Request rate, error rate, latency, CPU, memory and consumer lag; new and spiking error logs; slower and failing spans. All for the same window, against the same baseline.

Cause, not echo

Trace trees show where failures start and where latency is added. Callers that only suffer are labelled "originates in payment" and moved down.

Honest about gaps

Errors that were already there are listed as steady, not new. If a backend had no data, the answer says so. "No change" never stands in for "no data".

Measured, not promised.

Claude Code, run headless on six incidents (five faults and one where nothing is wrong), five times each. Once with the official VictoriaMetrics MCP servers alone, once with Spoor added. Claude Haiku, 60 isolated sessions.

Official servers onlyWith Spoor
Correct root cause, fault scenarios19 / 2525 / 25
Correct answer, including "nothing is wrong"23 / 3030 / 30
Median tool calls per investigation2410
Median time55 s23 s
Total cost$0.60$0.19

Synthetic incidents and one small model, so treat it as a first data point. On real production logs, a 466-token answer stood in for about 296,000 tokens of raw evidence. Method, per-scenario results and caveats are in the benchmark write-up.

Set it up in three steps.

  1. Install

    One static binary for macOS, Linux and Windows. No runtime to install.

    OS=$(uname -s | tr A-Z a-z)
    ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
    curl -fsSL "https://github.com/asinha07/spoor/releases/download/v0.2.1/spoor_0.2.1_${OS}_${ARCH}.tar.gz" | tar -xz spoor
    sudo mv spoor /usr/local/bin/
    spoor version
  2. Point it at your backends

    Set the three URLs, then run doctor. It samples each backend, reports what Spoor can and can't see, and suggests a config for logs that don't follow OpenTelemetry naming.

    export SPOOR_METRICS_URL=http://victoriametrics:8428
    export SPOOR_LOGS_URL=http://victorialogs:9428
    export SPOOR_TRACES_URL=http://victoriatraces:10428
    
    spoor doctor --since 15m
    spoor what-changed --since 30m --pretty

    For anything beyond URLs, put a spoor.yaml next to it and pass --config or set SPOOR_CONFIG. Keep passwords and tokens in environment variables such as SPOOR_LOGS_PASSWORD, not in the file. Every option is in the configuration guide.

    No stack to try it on? make it-up && make demo-data in the repo starts empty backends and loads six incidents with known answers.

  3. Connect your agent

    Most clients start Spoor as a subprocess and talk to it over stdio. Use absolute paths: clients don't start servers from your shell.

    claude mcp add -s user spoor \
      -e SPOOR_METRICS_URL=http://localhost:8428 \
      -e SPOOR_LOGS_URL=http://localhost:9428 \
      -e SPOOR_TRACES_URL=http://localhost:10428 \
      -- /usr/local/bin/spoor serve
    
    claude mcp list   # spoor should show as connected

    Then ask: "Checkout errors went up in the last 30 minutes. What changed, and where did it start?"

    Spoor is also listed in the MCP registry as io.github.asinha07/spoor and on Glama.

Four tools. Start with the first.

Every tool takes service, since, until, baseline (previous, 1d or 7d) and budget_tokens, which caps the answer at 200 to 4,000 tokens. All are read-only. The CLI has the same four as commands.

what_changed

Ranked changes across metrics, logs and traces, with cause and echo attribution, for one service or all of them.

new_errors

Error logs that are new or spiking, with counts, first-seen time and one redacted example line.

trace_diff

Span names that got slower or started failing, with each span's share of the added latency and an example trace ID.

list_services

Services seen in the window and which signals have data for each.

Keep your raw query tools connected too. Spoor tells the agent where to look; the raw tools let it look closer. That combination is what the benchmark measures.