Skip to main content
Glama
ThoTischner

observability-mcp

by ThoTischner

observability-mcp

The unified observability gateway for AI agents.

One MCP server that connects to any observability backend through pluggable connectors, normalizes the data, adds robust anomaly analysis, and provides a web UI for configuration.

One MCP endpoint, every backend — so an agent triaging an incident asks one normalized question instead of juggling N vendor servers and their query languages.

0/10 → 10/10: the same 8B local model goes from hallucinating blast-radius answers to exactly correct ones once it gets this gateway's topology tools — measured, not asserted.

npx @thotischner/observability-mcp                                    # start (UI on :3000)
claude mcp add observability --transport http http://localhost:3000/mcp   # wire into Claude

Twelve read-only tools (readOnlyHint: true on every one) · server-side filter/aggregate so agents get numbers, not haystacks · For-Agents guide

License: Apache 2.0 npm npm downloads GHCR Smoke test GitHub stars MCP SDK Artifact Hub

Helm IT TypeScript Helm chart Provenance Cosign signed SBOM CycloneDX SBOM SPDX SLSA provenance Connector Hub

observability-mcp — guided tour of the web UI


📖 Full documentation site: https://thotischner.github.io/observability-mcp/

🔌 Open in MCP Inspector — one-line interactive explorer:

npx --yes @modelcontextprotocol/inspector \
  --config <(npx --yes @thotischner/observability-mcp inspector-config)

Why it matters — measured, not asserted

On a real Kubernetes-platform-team question ("which other pods share a node with payment-service so we know what else falls over if that node goes down?"), the same local model produces wildly different answers depending on the tools you hand it:

Tools available to the agent (llama3.1:8b, n=10)

Cross-namespace blast-radius accuracy

Generic metric + log + service tools

0 / 10 &nbsp;— hallucinates the wrong entity type (prometheus, loki, kubernetes)

Same model + get_topology + get_blast_radius

10 / 10 &nbsp;— exact correct co-tenant list, every iteration

Raw JSON for both arms, plus three more scenarios (single-service RCA, in-namespace blast radius, scenarios where topology does not help), live in docs/benchmark-astronomy-shop.md. The harness is in scripts/benchmark-rca.mjs; re-run with make benchmark-up && make benchmark-run.

We don't claim universal speedup — the doc spells out exactly where the topology tools help (graph-shaped questions) and where they don't (pure single-metric drill-downs).


Related MCP server: byok-observability-mcp

Try it in 10 seconds

npx @thotischner/observability-mcp
# then open http://localhost:3000

Wire it into Claude Code with one CLI call:

claude mcp add observability --transport http http://localhost:3000/mcp

…or commit it to your repo as .mcp.json (works the same in Claude Desktop / Cursor):

{
  "mcpServers": {
    "observability": {
      "transport": { "type": "http", "url": "http://localhost:3000/mcp" }
    }
  }
}

The server starts with zero sources. Add Prometheus/Loki via the Web UI or PROMETHEUS_URL / LOKI_URL env vars.

If you'd rather have the snippets above printed by a Make target — including custom-host / custom-port substitution — use make connect-claude-code or make connect-cursor. make doctor round-trips a real MCP handshake against a running server, reports the live governance posture (auth mode, redaction, audit-log persistence, per-identity rate cap), and tells you what to fix if it can't.

Multi-user / production? See docs/access-control.md for the opt-in basic-mode login + RBAC + audit log + per-identity rate limit setup. All off by default; the demo above is unchanged.

SSO via OIDC? make demo-oidc boots a Keycloak + an OIDC-flavored mcp-server on port 3001 with three pre-provisioned users (admin / operator / viewer, password = username, DEMO ONLY). See docs/auth-oidc.md for production Keycloak / Authentik / Auth0 / Azure AD setups.

External RBAC via OPA? make demo-opa boots an Open Policy Agent with an example Rego policy + an OPA-backed mcp-server on port 3002. See docs/policy-engines.md for the built-in / file / OPA backend trade-offs and migration paths.

Curated MCP Products? Set OMCP_PRODUCTS_FILE to a YAML catalog (config/products.yaml.example) and ship per-tenant/per-agent tool bundles instead of "everything, all the time". RBAC-gated, audited, hot-editable. Details in docs/products.md.

Want the full chaos-engineering demo (Prometheus + Loki + 3 example services + the autonomous agent)? Clone and run:

make demo   # equivalent to: docker compose --profile demo up --build --wait

Or run the sovereign quickstart — one command, fully on-prem, zero external calls: it starts the stack, injects a real incident, and shows side by side what an agent gets without vs with the analysis layer (a wall of raw numbers vs a scored verdict that pinpoints the culprit). The optional agent reasons over it with a local model (Ollama):

make demo-sovereign

See make help for all canonical workflows.

Why?

Every observability vendor ships its own MCP server — Prometheus, Grafana, Datadog, Elastic, each siloed. An AI agent triaging an incident across systems must juggle N separate servers and learn each query language (PromQL, LogQL, …). There is no unified abstraction layer.

observability-mcp is that layer: one MCP endpoint that normalizes every backend and answers in plain service/metric/log terms, plus an analysis engine that flags anomalies the agent would otherwise have to reconstruct from raw queries itself.

Who it's for: SRE / platform teams running Prometheus + Loki who use an AI agent (Claude, local LLMs, …) for incident triage. The gateway's leverage is largest when the agent is not a frontier model — a smaller or local model that can't reliably hand-write PromQL/LogQL benefits most from normalized tools and pre-computed analysis. A strong frontier model can query raw backends competently on its own; there the value is consistency and the analysis engine, not query convenience. We state this honestly rather than claiming a universal speedup.

Features

  • 🔍 Inspect — see, learn & enforce agent behavior — a live service-mesh-style graph of every MCP tool call, an AppArmor-style learning workflow that derives a behavior profile from real traffic, and an enforce mode that blocks calls outside the accepted baseline. Jump to Inspect ↓

  • Unified gateway — Single MCP endpoint for all your observability backends.

  • Cross-signal analysis — Correlates metrics and logs automatically. Robust anomaly detection (median/MAD baseline, trend detection for slow ramps, warmup + dwell to suppress flapping) and weighted health scoring.

  • Web UI — Sources, services, health monitoring, configuration. Real-time, dark theme.

  • prom-client defaults — Works out of the box with the standard Node.js Prometheus instrumentation. Dynamic label resolution probes job / service / app / service_name so service filtering Just Works.

  • Loki label fallback — Discovers services through service_name / service / job / app / container, including Docker-shipped streams with leading slashes.

  • Pluggable connectors — One interface, any query language (PromQL, LogQL, Flux, KQL...). See docs/connectors.md.

  • Auth & TLS — Basic, Bearer, custom CA, mTLS. See docs/auth-and-tls.md.

  • Multi-backend — Multiple instances of the same type, no problem.

Inspect — see, learn & enforce agent behavior

You handed an agent (or a CI bot, or a leaked credential) a key to your observability backends. Inspect answers the question RBAC can't: is this call normal for this identity, compared to what it has actually been doing?

Inspect — live flow graph of agent tool calls

It borrows AppArmor's learning workflow and a service-mesh traffic view (think Kiali, for agent tool calls):

   OFF  ──▶  OBSERVE  ──▶  DRY-RUN (complain)  ──▶  ENFORCE
              │              │                        │
        record calls    compute what WOULD be     block calls that
        only (zero      blocked, but still allow   fall outside the
        risk, default)  — review before enforcing   accepted profile
  • Flows — a live Identities → Tools → Backends graph. Edge thickness is call volume; colour is allowed / deviation / blocked. Click any node to drill into the real calls, the argument-shape distribution, and turn an observed edge straight into a rule.

  • Profile — the learning loop: hit "Learn from traffic", review the suggested rules (anonymous → query_logs · service ∈ {payment-service} — learned from N calls), and accept / edit / reject each one. Only accepted rules ever gate traffic.

  • Deviations — every call that fell outside the profile: who, which tool, what was unusual — one click to accept into the profile or confirm an anomaly.

Privacy by design: Inspect stores argument shapes, never raw payloads, and runs everything through the gateway's redaction layer first. It makes no outbound calls — the air-gapped guarantee is unchanged.

OSS vs. licensed: observe and dry-run — the live graph, learning a profile, seeing would-block deviations — are free. Active enforce blocking is an entitled control (shown with a 🔒 in the UI). Visibility is free; enforcement is the licensed capability. Full design: docs/inspect.md.

Detection quality

The anomaly engine is backtested against a labelled synthetic suite covering slow ramps (memory-leak-toward-OOM), spikes, step changes, stable noise, transient blips, one-sided recoveries, daily-seasonal patterns, and a deliberately ambiguous low-SNR "hard" tier. Scored as a CI gate (backtest.test.ts) — these numbers are regenerated from that suite, not hand-written:

Cases

Precision

Recall

F1

64

100.0%

87.5%

93.3%

Precision is 100% (no spurious alerts); the recalled misses are by design at the noise floor of the hard tier. The suite is deterministic and a detector regression fails CI. Reproduce locally:

docker run --rm -w /app -v "$(pwd)/mcp-server:/app" node:20-alpine \
  sh -c "npm i --silent && npx tsx --test src/analysis/backtest.test.ts"

Screenshots

Inspect — flow graph

Inspect — learn a profile

Inspect flows

Inspect profile

Dashboard

Service health

Connector hub

Dashboard

Service health

Connector hub

Architecture

graph TB
    Agent["AI Agent<br/><small>Claude, Ollama, etc.</small>"]

    subgraph MCP ["observability-mcp :3000"]
        Tools["12 MCP Tools"]
        Analysis["Analysis Engine<br/><small>Robust stats, Health Scoring, Correlation</small>"]
        UI["Web UI"]
    end

    subgraph Connectors ["Pluggable Connectors"]
        Prom["Prometheus<br/><small>PromQL — metrics</small>"]
        Loki["Loki<br/><small>LogQL — logs</small>"]
        K8s["Kubernetes<br/><small>watch — topology</small>"]
        Next["Your Backend<br/><small>Any query language</small>"]
    end

    Agent <-->|"MCP<br/>Streamable HTTP"| Tools
    Tools --- Analysis
    Tools --- UI
    MCP --> Prom & Loki & K8s & Next

    style MCP fill:#1a1a2e,stroke:#58a6ff,color:#fff
    style Connectors fill:#0d1117,stroke:#3fb950,color:#fff
    style Agent fill:#58a6ff,stroke:#58a6ff,color:#000
    style Next fill:#0d1117,stroke:#3fb950,color:#8b949e,stroke-dasharray: 5 5

Repo layout

mcp-server/   # the product — server, Web UI, analysis engine, built-in plugins
helm/         # ArtifactHub-grade Helm chart
docs/         # configuration, auth, plugin architecture, airgapped deployment, ...
examples/     # demo material — agent, example services, Prometheus+Loki configs

mcp-server/ is what you install. Everything under examples/ is opt-in via docker compose --profile demo — it's how the repo demos chaos detection end-to-end, but production deployments don't need any of it.

Installation

Method

Command

Best for

npm

npx @thotischner/observability-mcp

Local dev, Node toolchains, zero install

Docker (GHCR)

docker run -p 3000:3000 ghcr.io/thotischner/observability-mcp:latest

Production hosts, isolation

Helm

helm repo add observability-mcp https://thotischner.github.io/observability-mcp/helm install observability-mcp observability-mcp/observability-mcp

Kubernetes

From source

git clone … && make demo

Full POC with example services and chaos

CLI (omcp)

npm i -g @thotischner/observability-mcp

Managing connectors, the demo stack & Helm from the terminal — see CLI

GHCR is multi-arch (amd64 + arm64). Available tags: latest, main, X.Y.Z, X.Y, X, sha-<commit>. Note: the leading v is stripped from semver tags.

Helm chart

The chart ships with Deployment, Service, optional Ingress/PVC/HPA, NetworkPolicy, ServiceMonitor (auto-gated on the Prometheus Operator CRD), helm test connection probe, and values.schema.json validation. ArtifactHub-grade annotations. See helm/observability-mcp/ for the full values reference, or the airgapped deployment guide for a hardened production example.

helm repo add observability-mcp https://thotischner.github.io/observability-mcp/
helm repo update
helm install observability-mcp observability-mcp/observability-mcp \
  --set sources.prometheusUrl=http://prometheus.monitoring.svc.cluster.local:9090 \
  --set sources.lokiUrl=http://loki.logging.svc.cluster.local:3100
# docker-compose snippet
services:
  observability-mcp:
    image: ghcr.io/thotischner/observability-mcp:latest
    ports: ["3000:3000"]
    environment:
      PROMETHEUS_URL: http://prometheus:9090
      LOKI_URL: http://loki:3100
    volumes:
      - ./mcp-config:/home/node/.observability-mcp
    restart: unless-stopped

For full configuration — paths, env vars, ${VAR} substitution, complete sources.yaml reference — see docs/configuration.md.

Quick Start

Option A: Standalone (your own backends)

npx @thotischner/observability-mcp

Then open the Web UI at http://localhost:3000, click Sources → + Add Source, point at your Prometheus/Loki URLs. Or skip the UI:

PROMETHEUS_URL=http://localhost:9090 LOKI_URL=http://localhost:3100 \
  npx @thotischner/observability-mcp

Option B: Grafana Cloud

Grafana Cloud uses Basic Auth with your numeric instance ID as username and an API token as password. The instance ID for Prometheus and Loki is different — find both in Connections → Data sources.

# ~/.observability-mcp/sources.yaml
sources:
  - name: grafana-cloud-prom
    type: prometheus
    url: https://prometheus-prod-XX-prod-eu-west-X.grafana.net/api/prom
    enabled: true
    auth:
      type: basic
      username: "${GRAFANA_PROM_USER}"   # numeric instance ID
      password: "${GRAFANA_TOKEN}"
  - name: grafana-cloud-loki
    type: loki
    url: https://logs-prod-XXX.grafana.net
    enabled: true
    auth:
      type: basic
      username: "${GRAFANA_LOKI_USER}"   # different from Prom!
      password: "${GRAFANA_TOKEN}"
GRAFANA_PROM_USER=… GRAFANA_LOKI_USER=… GRAFANA_TOKEN=glc_… \
  npx @thotischner/observability-mcp

Option C: Full demo (Docker Compose with example services)

git clone https://github.com/ThoTischner/observability-mcp.git
cd observability-mcp
docker compose --profile demo up --build

Boots a single-node k3s cluster, builds the three example services and runs them as Kubernetes Deployments inside k3s, plus Prometheus, Loki, Promtail, the MCP server and the agent on the docker-compose side. Open http://localhost:3000.

The same Deployments that Prometheus scrapes and Loki receives logs from are also what the topology graph shows — so the agent can correlate a metric/log anomaly with its underlying host using get_blast_radius. Chaos endpoints stay on localhost:8080/8081/8082 (mapped to the k3s NodePorts) so existing scripts and demo videos keep working unchanged.

Without --profile demo, only mcp-server starts — useful when you already run Prometheus/Loki elsewhere and just want to expose them via MCP.

Option D: Benchmark mode (OpenTelemetry Demo / Astronomy Shop)

For producing credible RCA numbers against a real microservice workload (~23 services, native OTel instrumentation):

make benchmark-up         # clones upstream Astronomy Shop, brings up both stacks
make benchmark-run        # runs the harness baseline vs topology, writes JSON
make benchmark-down       # tears down

make benchmark-up adds Tempo + an OTel collector bridge under our --profile benchmark and orchestrates the upstream stack in a separate compose project, joining their network to ours so Astronomy Shop services push traces into our Tempo. See docs/benchmark-astronomy-shop.md and examples/benchmark/README.md. First-time pull is ~4 GB.

MCP Tools

Tool

Signal

Purpose

list_sources

meta

Discover configured backends and connection status

list_services

meta

Discover monitored services across all backends

query_metrics

metrics

Query metrics with pre-computed summary stats

query_logs

logs

Query logs with error/warning counts and top patterns

get_service_health

unified

Health score combining metrics + logs (0–100)

detect_anomalies

unified

Cross-signal anomaly detection with robust (median/MAD + trend) analysis

get_topology

topology

Return the merged infrastructure graph (resources + edges) from every topology-capable connector, filterable by source/kind/scope

get_blast_radius

topology

Pivot on the universal RUNS_ON relation — "if this resource's host fails, who else fails?". Works for pod→node, vm→hypervisor, container→host

The two topology tools require a topology-capable connector. The bundled Kubernetes connector is the first; future connectors (vCenter, NetBox, …) plug in via the same isTopologyProvider interface and emit kind/relation values from the canonical topology vocabulary.

Using with Claude Code

Connect Claude Code directly — no agent needed.

CLI:

claude mcp add observability --transport http http://localhost:3000/mcp

Or .mcp.json in your project root (commit-friendly):

{
  "mcpServers": {
    "observability": {
      "transport": { "type": "http", "url": "http://localhost:3000/mcp" }
    }
  }
}

Then ask Claude in natural language. For example, after triggering chaos in the demo (curl -X POST http://localhost:8081/chaos/error-spike):

"Are there any anomalies right now?"

Claude calls detect_anomalies and finds:

{
  "anomalies": [
    { "metric": "cpu", "severity": "high", "service": "payment-service",
      "description": "cpu is 3.4σ above baseline (18.36 → 37.31)" },
    { "metric": "request_rate", "severity": "low", "service": "payment-service",
      "description": "request_rate is -1.8σ below baseline (0.08 → 0.04)" }
  ]
}

"Show me the error logs for payment-service."

Claude calls query_logs:

{
  "summary": {
    "total": 11, "errorCount": 11,
    "topPatterns": [
      "Request failed: internal error during POST /payments (6x)",
      "Request failed: internal error during POST /refunds (4x)"
    ]
  }
}

Claude correlates the signals — CPU spike, error logs flooding, request rate halved — and explains the incident in plain language. No PromQL, no LogQL.

Demo: Chaos Engineering

Three example microservices generate traffic and support chaos injection:

curl -X POST http://localhost:8081/chaos/high-cpu        # CPU spike
curl -X POST http://localhost:8081/chaos/error-spike     # CPU + latency + errors
curl -X POST http://localhost:8081/chaos/slow-responses  # Latency
curl -X POST http://localhost:8081/chaos/memory-leak     # OOM logs
curl -X POST http://localhost:8081/chaos/reset

The agent (docs/agent.md) detects anomalies within 30 seconds and produces an LLM incident analysis if Ollama is running.

CLI (omcp)

A control CLI ships in the same npm package (omcp bin) — manage connectors, the demo stack, and Helm installs.

Install it (or run ad-hoc without installing):

npm i -g @thotischner/observability-mcp   # puts `omcp` on your PATH
omcp --help

# or, no install:
npx -p @thotischner/observability-mcp omcp doctor

Then:

omcp doctor                       # check docker / compose / helm / node
omcp demo up                      # full demo stack (auto-picks free host ports)
omcp plugin list                  # browse the connector hub catalog
omcp plugin install tempo@1.2.0 --trust-root key.pem    # download + verify + extract
omcp plugin verify ./plugins/tempo --trust-root key.pem # offline audit
omcp helm upgrade obs -- -n monitoring --set sources.prometheusUrl=http://prom:9090

Plugin install/verify reuse the server's fail-closed signature + integrity checks (offline-capable; --offline-dir for airgapped). Extra helm flags pass through after a literal --.

Docs

  • Configuration — paths, env vars, ${VAR} substitution, full sources.yaml reference

  • Authentication & TLS — Basic, Bearer, custom CA, mTLS

  • Management-plane auth (basic mode) — optional login screen + signed session cookies for the Web UI / /api/* plane

  • Log redaction — PII / secret patterns automatically masked in query_logs output before it reaches the agent; opt-out via OMCP_REDACTION=off

  • Access control overview + runbook — RBAC roles, audit chain, per-identity rate limits, service catalog enrichment, and an investigation runbook for the most common "who / why" questions

  • Prometheus — defaults, label resolution, resolvedSeries, prom-client compatibility

  • Loki — label fallback, Docker container slash, managed Loki

  • Connectors — write your own backend

  • Agent — Ollama setup, loop behavior

  • Troubleshooting — common pitfalls and fixes

  • Security — automation pipeline, vulnerability reporting, built-in protections

  • Airgapped deployment — mirroring images, private plugins, GitOps-friendly config

  • Topology vocabulary — the canonical kind / relation contract every topology-capable connector emits, plus the warn-only validator

  • RCA benchmark — reproducible A/B harness; on a cross-namespace blast-radius question (llama3.1:8b, n=10) the baseline tool set scores 0/10 and hallucinates the wrong entity type, the same model with topology tools scores 10/10 deterministically — see the three-scenarios table for the full honest picture

  • How this compares to adjacent tools — source-cited table vs. Datadog Bits AI, HolmesGPT, Robusta — what each is best at and where this fits

  • Governance access-control gate — optional RBAC / catalog / audit behind a signed entitlement token (off by default)

  • Connector Hub — browse versioned, signed connectors (catalog: hub/)

  • Use cases — five scenarios with the prompts that drive them

Endpoints

Service

URL

MCP Server (Streamable HTTP)

http://localhost:3000/mcp

Web UI

http://localhost:3000

Health API

http://localhost:3000/api/health

In the docker-compose demo: Prometheus on :9090, Loki on :3100. The three example services run as Kubernetes Deployments inside the in-compose k3s and are reachable on the host via the NodePort mapping :8080–:8082 — same URLs as before the k8s migration, so existing chaos commands keep working.

Transports: Streamable HTTP by default (/mcp). For stdio-based clients/catalogs (Claude Desktop, Glama's mcp-proxy, etc.) run with --stdio (or MCP_TRANSPORT=stdio) — one MCP server over stdin/stdout, all logs on stderr so the protocol stream stays clean.

Tech Stack

TypeScript + Node 20, @modelcontextprotocol/sdk (Streamable HTTP), Express, Zod, js-yaml, prom-client (example services), Prometheus, Loki, Promtail, Docker Compose, optional Ollama.

Requirements

  • Standalone: Node 20+ (or just npx)

  • Docker demo: Docker + Compose, 4 GB+ RAM (8 GB+ with Ollama)

  • Optional: Ollama on the host for the agent's LLM analysis

Contributing

  1. Fork the repo and docker-compose up --build.

  2. Pick an issue or open one to discuss your idea.

  3. Submit a PR — all code runs in Docker, no local deps.

Ideas: new connectors (InfluxDB, Elasticsearch, Datadog), additional analysis algorithms, UI improvements.

License

Apache License 2.0 — see also NOTICE.

Releases up to and including the last MIT-licensed version remain available under MIT; subsequent releases are Apache-2.0. Contributions require a Contributor License Agreement.


If you find this useful, consider giving it a star — it helps others discover the project.

Available Tools

12 tools
detect_anomaliesA
Read-onlyIdempotent

Scan one or all monitored services for abnormal behavior and return the findings ranked by severity. When to use: the entry point for 'is anything wrong anywhere?' triage. Once a service is flagged, follow up with get_service_health for the verdict or query_metrics/query_logs for the raw evidence. Behavior: read-only, no side effects. Applies z-score analysis to metrics, detects log error-rate spikes, and correlates the two. Returns a list of anomalies, each with the affected service, metric/signal, severity, the deviation (e.g. σ and % change), and a short explanation. No anomalies yields an empty list, not an error. Related: get_service_health (single-service verdict), query_metrics (raw series behind a flagged metric).

ParametersJSON Schema
NameRequiredDescriptionDefault
serviceNoOptional. Restrict the scan to one service (exact, case-sensitive name from `list_services`). Default: scan every monitored service.
durationNoOptional. Look-back window analyzed for anomalies, written as <number><unit> with unit s|m|h|d (e.g. '5m', '15m', '1h'). Default: '10m'.
sensitivityNoOptional. Detection threshold: 'low' flags only strong deviations (>3σ), 'medium' is balanced (>2σ), 'high' is most sensitive and noisier (>1.5σ). Default: 'medium'.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already indicate read-only, non-destructive, idempotent. The description adds detailed behavioral traits: no side effects, statistical method (z-score analysis), correlation of metrics and logs, and handling of no anomalies (empty list, not an error). No contradictions.

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 cohesive paragraph that effectively front-loads the purpose. It is reasonably concise, though could be slightly more structured (e.g., bullet points).

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?

Despite lacking an output schema, the description fully explains the return value (list of anomalies with fields like service, severity, deviation, explanation) and edge case (empty list). Given the tool's complexity and sufficient annotations, the description is complete.

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 coverage is 100%, so baseline is 3. The description adds context beyond schema by explaining the statistical method (z-score) and the meaning of sensitivity levels, but the schema already describes each parameter well.

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?

The description clearly states the tool's action ('Scan one or all monitored services for abnormal behavior') and output ('return the findings ranked by severity'), distinguishing it from siblings like get_service_health and query_metrics.

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

Usage Guidelines5/5

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

The description explicitly provides usage context: 'the entry point for 'is anything wrong anywhere?' triage.' It also recommends follow-up actions using get_service_health, query_metrics, and query_logs, and lists related tools.

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

enrich_ipsA
Read-onlyIdempotent

Resolve a batch of IPv4 or IPv6 addresses to geo (country/city), ASN/org, and a hosting/proxy flag. When to use: answering 'where are these visitors from?' or 'which of these IPs are bots / datacenter / VPN exit nodes?' over access logs, without an out-of-band geo-API call per IP. Both IPv4 and IPv6 clients are resolved — don't pre-filter v6 out. Behavior: read-only. By default looks each IP up in a LOCAL offline dataset the operator configured (OMCP_IP_ENRICH_FILE) with NO external network call — safe in air-gapped deployments. Optionally, if the operator enabled OMCP_IP_ENRICH_RDAP, IPs the dataset doesn't cover fall back to an online RDAP query (country/org only) and the result carries via:'rdap'; the offline dataset is always preferred. Returns one row per input IP with found=true/false plus any known fields. If neither is configured it returns a clear notice explaining how to enable them. RDAP rate-limits: a row with found=false AND transient:true (error names the cause, e.g. 'rate_limited') is NOT a confirmed negative — the registry throttled or failed the lookup, so the IP may resolve on a later retry or in a smaller batch. Such rows are counted in summary.transient (separate from summary.unmatched) and a top-level note is added. Don't treat transient rows as 'unknown/suspicious'; retry them (results are cached, so repeats are cheap). Related: pull the IPs from query_logs (use labels/aggregate to find the IPs of interest first).

ParametersJSON Schema
NameRequiredDescriptionDefault
ipsYesRequired. IPv4 or IPv6 address strings to enrich (e.g. ['203.0.113.5','2001:db8::1']). Max 1000 per call; invalid entries are returned with found=false rather than failing the batch.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond annotations (readOnlyHint, destructiveHint, idempotentHint), the description discloses critical behavior: using local offline dataset by default, optional RDAP fallback, handling of invalid entries (return found=false), transient rows due to rate limits, and caching. No contradiction with annotations.

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 somewhat lengthy but well-structured: core function first, then usage, then behavioral details, then special cases. It is front-loaded with the main purpose. Could be slightly trimmed, but every sentence adds value.

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?

With no output schema, the description thoroughly explains the return format (one row per IP, found flag, summary, transient, note). It covers error handling, rate limiting, and configuration dependencies. Complete for a single-parameter tool.

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 input schema fully describes the 'ips' parameter with a note about invalid entries. The description adds contextual value: both IPv4 and IPv6 are supported, invalid entries do not fail the batch, and the default local vs RDAP behavior. Schema coverage is 100%, so baseline 3; the extra context justifies a 4.

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?

The description clearly states it resolves IPs to geo, ASN/org, and hosting/proxy flag. It provides specific use-case scenarios ('where are these visitors from?', 'which of these IPs are bots?') and distinguishes from sibling tools like query_logs by explaining the enrichment purpose.

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

Usage Guidelines5/5

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

Explicitly states when to use (e.g., answering geolocation or bot detection questions) and when not to pre-filter v6. It mentions the local dataset vs RDAP fallback, how to handle transient rows (retry), and the 1000-item limit. Provides meaningful context for decision-making.

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

generate_postmortemA
Read-onlyIdempotent

Stitch the gateway's primitives (anomaly history, blast-radius, traces, log highlights) into a single markdown post-mortem report for one service over a given window. When to use: after an incident, when the operator or LLM wants 'one document the on-call can read in 60 seconds' instead of poking the individual tools. Prerequisites: anomaly history requires OMCP_ANOMALY_HISTORY_REMOTE_WRITE + a Prometheus source. Traces require Tempo / Jaeger. Blast-radius requires a topology provider. Behavior: read-only. Returns markdown by default; pass format='json' for the structured shape. Output capped (timeline 20 rows, blast-radius 30 nodes, 10 traces) — JSON shape carries the full data. Related: get_anomaly_history, query_traces, get_blast_radius for the underlying primitives.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNo'markdown' (default) or 'json'.
serviceYesSuspected root-cause service.
durationNoWindow length, e.g. '1h', '6h'. Default '1h'.

TDQS

A4.8/5.0
Behavior5/5

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

Discloses read-only behavior (consistent with annotations), output capped limits (timeline 20 rows, blast-radius 30 nodes, 10 traces), and that JSON shape carries full data. No contradiction with annotations.

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?

Every sentence contributes: purpose, usage, prerequisites, behavior, output detail, and related tools. No fluff, well-organized in a few lines.

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?

Given no output schema, description explains return format (markdown default, JSON optional), caching, and limitations. Prerequisites and behavior covered. Could specify report structure slightly more but adequate for completeness.

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 covers all three parameters with descriptions. The description adds value by explaining format default ('markdown') and that JSON returns structured shape, plus duration default '1h'. Enhances parameter understanding without redundancy.

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?

The description clearly states the tool stitches gateway primitives into a single markdown post-mortem report for one service over a given window. It distinguishes from siblings by listing the primitives combined (anomaly history, blast-radius, traces, log highlights).

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

Usage Guidelines5/5

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

Explicitly states when to use: after an incident, for a concise document instead of individual tools. Provides prerequisites for each primitive (e.g., anomaly history requires OMCP_ANOMALY_HISTORY_REMOTE_WRITE, traces require Tempo/Jaeger). Also lists related sibling tools.

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

get_anomaly_historyA
Read-onlyIdempotent

Replay historical anomaly scores for a service from the TSDB the gateway writes to (omcp_anomaly_score series). When to use: post-mortem reconstruction, trend analysis on detector noise, or pulling context for the LLM when an incident is reviewed after the fact. Prerequisites: the operator must have OMCP_ANOMALY_HISTORY_REMOTE_WRITE configured AND a Prometheus source pointed at the same TSDB so the round-trip closes. Behavior: read-only. Returns the time-series of scores. Empty result means either no anomalies in the window or history is disabled. Related: detect_anomalies for the live scores; query_metrics if you want to write the PromQL by hand.

ParametersJSON Schema
NameRequiredDescriptionDefault
methodNoFilter by detector method ('mad' / 'seasonality' / 'correlator'). Optional.
serviceYesService name to filter on.
durationNoRolling window, e.g. '1h', '24h'. Default '1h'.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true. The description adds that it returns a time-series of scores and explains meanings of empty results, providing some additional context beyond annotations.

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 concise, front-loads the main purpose, and includes usage, prerequisites, behavior, result, and related tools in a single well-structured paragraph with no wasted words.

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 3 params and no output schema, the description explains the return type ('time-series of scores'), empty result meaning, and prerequisites. It is largely complete, though more details on the exact response format could be beneficial.

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

Parameters3/5

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

Schema description coverage is 100%, so baseline is 3. The description does not add significant detail beyond what the schema provides for each parameter. Each parameter has a brief description in the schema, and the description adds overall context but not per-parameter semantics.

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?

The description explicitly states 'Replay historical anomaly scores for a service from the TSDB', providing a specific verb and resource. It distinguishes itself from sibling tool 'detect_anomalies' by mentioning it is for live scores.

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

Usage Guidelines5/5

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

The description provides explicit usage scenarios ('post-mortem reconstruction, trend analysis') and mentions prerequisites (OMCP_ANOMALY_HISTORY_REMOTE_WRITE and Prometheus source). It also explains the meaning of an empty result and relates to sibling tools for live scores.

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

get_blast_radiusA
Read-onlyIdempotent

Given a resource, return who else fails if its underlying host(s) fail. When to use: cross-cutting RCA — when several services degrade together and you suspect a shared host. Works for any RUNS_ON relationship: pod→node, vm→hypervisor, container→host. Behavior: read-only, no side effects. Resolves resource to a Resource (accepts canonical id, exact name, or unique substring), determines its host(s) via RUNS_ON, then lists every other resource that runs on those hosts, bucketed by ownership root (the terminal OWNED_BY target — e.g. the Deployment, not the ReplicaSet). If the target is itself a host, its tenants are reported. Returns a structured error if the resource is ambiguous or unknown. Related: get_topology for the full graph; get_service_health for the per-service verdict on each co-tenant.

ParametersJSON Schema
NameRequiredDescriptionDefault
resourceYesRequired. Resource to evaluate. Accepts the canonical id (e.g. 'k8s:pod:default/checkout-7f89d'), the exact resource name (e.g. 'checkout-7f89d'), or a unique substring of either.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds: 'Behavior: read-only, no side effects.' It also details resource resolution, host determination via RUNS_ON, bucketing by ownership root, and error handling. This adds substantial context beyond annotations.

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 well-structured paragraph that front-loads the core purpose, then provides details on usage, behavior, and related tools. Every sentence adds value with no redundancy.

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?

Given the tool has one parameter fully described in schema, rich annotations, and the explanation of output structure (bucketed by ownership root), the description is complete for an agent to select and invoke the tool correctly.

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 100% for the single parameter 'resource'. The description adds examples and explains resolution behavior (canonical id, exact name, unique substring). Since the schema already fully describes the parameter, the added value is moderate but significant.

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?

The description clearly states the tool's purpose: given a resource, return who else fails if its underlying host(s) fail. It specifies the verb 'return', the resource context, and the relationship (RUNS_ON). It also distinguishes from siblings by mentioning related tools like get_topology and get_service_health.

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

Usage Guidelines5/5

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

The description includes explicit guidance: 'When to use: cross-cutting RCA — when several services degrade together and you suspect a shared host.' It also explicitly names alternative tools: 'Related: get_topology for the full graph; get_service_health for the per-service verdict on each co-tenant.'

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

get_service_healthA
Read-onlyIdempotent

Produce a single aggregated health verdict for ONE service by combining its metrics and logs. When to use: the fastest way to answer 'is this service healthy right now and why?'. Use query_metrics/query_logs to drill into the underlying numbers, or detect_anomalies to scan many services at once. Prerequisites: get the exact service name from list_services. Behavior: read-only, no side effects. Returns a weighted health score (0–100), a status of healthy | degraded | critical, the key contributing metrics, a log error summary, detected anomalies, and cross-signal correlations explaining the score. A service with no data yields an explanatory result rather than an exception.

ParametersJSON Schema
NameRequiredDescriptionDefault
serviceYesRequired. Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'payment-service').

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, destructiveHint, idempotentHint. Description adds that it's read-only with no side effects, details return fields (score, status, contributing metrics, error summary, anomalies, correlations), and clarifies behavior for services with no data (explanatory result not exception).

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?

Description is concise with no filler. Front-loaded purpose and usage, structured logically. Every sentence adds value.

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?

Tool has 1 parameter, no output schema, but description fully covers purpose, usage, behavior, and return fields. No gaps given the complexity.

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 covers the 'service' parameter with clear description and example. Description reinforces the need for exact case-sensitive name from list_services. Adds useful context beyond schema for one parameter.

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 explicitly states it produces a single aggregated health verdict for one service using metrics and logs. It distinguishes from sibling tools like query_metrics/query_logs and detect_anomalies, making the purpose clear.

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

Usage Guidelines5/5

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

Provides explicit when to use ('fastest way to answer is this service healthy'), when not (alternatives named), and prerequisites (get service name from list_services). Comprehensive guidance.

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

get_topologyA
Read-onlyIdempotent

Return the infrastructure topology graph (Resources and Edges) from every topology-capable connector. When to use: when an agent needs to reason about which workload runs on which host, who owns whom, or which scope (namespace/project/folder) a resource belongs to. Pair with get_blast_radius for shared-host RCA. Behavior: read-only, no side effects. Returns { sources, resources, edges, total, truncated }. Filters compose: source to one connector, kind to one resource type (e.g. 'pod', 'node', 'deployment'), scope to members of a namespace/folder/project. Output is capped by limit (default 500, max 5000) and edges referencing dropped resources are removed. Related: get_blast_radius to evaluate the impact of a host failure; list_sources to discover topology-capable connectors.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoOptional. Restrict to resources of one kind. Common values for Kubernetes: 'pod', 'node', 'deployment', 'replicaset', 'namespace'. Other connectors may emit different kinds (e.g. 'vm', 'hypervisor', 'volume'). Default: all kinds.
limitNoOptional. Maximum resources to return; edges are trimmed to the kept set. Default 500, max 5000.
scopeNoOptional. Restrict to resources contained in a scope (anything pointed to by `IN_NAMESPACE` edges). Pass the scope's resource id (e.g. 'k8s:namespace:default') or its name (e.g. 'default'). Default: no scope filter.
sourceNoOptional. Restrict the graph to one topology connector by source name (see `list_sources`). Default: merge across all connectors.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, destructiveHint, idempotentHint. Description adds output shape, filter composition rules, and limiting behavior, providing useful context beyond annotations.

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?

Single paragraph that packs purpose, usage, behavior, output, filter details, and related tools without wasted words. Front-loaded with main action and outcome.

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?

Covers all parameters and output shape. Lacks explicit return value details, but given no output schema, the description provides sufficient context for typical use. Could mention pagination or total count behavior, but not essential.

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

Parameters5/5

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

Schema coverage is 100%, but description adds significant value: explains filter composition, gives examples of resource kinds (Kubernetes, other connectors), and specifies default and max for limit. Goes well beyond schema alone.

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?

Clearly states 'Return the infrastructure topology graph' with specific verb and resource. Differentiates from siblings by mentioning related tools (get_blast_radius, list_sources) and their distinct purposes.

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

Usage Guidelines5/5

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

Explicitly provides 'When to use' with reasoning about workload relationships and scope belonging. Pairs with get_blast_radius and mentions list_sources for discovery, giving clear alternatives.

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

list_servicesA
Read-onlyIdempotent

Discover the service names that can be queried, aggregated across every connected backend. When to use: call this before query_metrics, query_logs, or get_service_health to obtain the exact, case-sensitive service name those tools require. Behavior: read-only, no side effects. Returns one entry per service with the service name, the source(s) it was discovered in, and which signals are available for it (metrics, logs, or both). Related: list_sources for backend health; get_service_health for a per-service overview.

ParametersJSON Schema
NameRequiredDescriptionDefault
filterNoOptional case-insensitive substring to narrow the result to matching service names (e.g. 'payment'). Omit to list every discovered service.

TDQS

A4.5/5.0
Behavior4/5

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

Declares read-only, no side effects, which matches annotations (readOnlyHint, idempotentHint). Adds detail about return structure (name, sources, available signals). No contradictions.

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?

Front-loaded with purpose, followed by usage, behavior, and output summary. Every sentence adds value; no wasted words.

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?

Tool has one optional parameter, no output schema, but description explains return structure. Annotations cover safety. No gaps for agent decision-making.

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

Parameters3/5

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

Schema coverage is 100%; the description's mention of the filter parameter mirrors the schema's description exactly. No additional semantics beyond what schema already provides.

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?

Clearly states verb 'discover', resource 'service names', and scope 'aggregated across every connected backend'. Distinguishes from siblings by naming alternative tools and their purposes.

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

Usage Guidelines5/5

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

Explicitly says to call before query_metrics, query_logs, and get_service_health to obtain exact case-sensitive names. Also references related tools list_sources and get_service_health, giving clear when-to-use and alternatives.

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

list_sourcesA
Read-onlyIdempotent

List the configured observability backends (Prometheus, Loki, and any connector) and whether each is currently reachable. When to use: call this first to learn which source names exist and are healthy before passing source to other tools, or to debug why a query returns no data. Behavior: read-only, no side effects. Returns one entry per source with its name, type, signal types (metrics/logs), and a live up/down status (the backend URL is intentionally not exposed — it may carry embedded credentials). Never throws for an unreachable backend — the backend is reported as down instead. Related: use list_services to see what is monitored within these sources.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

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

Beyond annotations, adds that it never throws for unreachable backends (reports down), explains that backend URL is intentionally hidden for security, and confirms read-only with no side effects.

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?

Well-structured with clear sections: purpose, when-to-use, behavior, return info, exception handling, related tool. Efficiently covers all needed information.

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?

Complete for a tool with no parameters and no output schema. Covers input, behavior, output, error handling, and security. Points to sibling for further reference.

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?

No parameters, so baseline 4. Description adds value by detailing return fields (name, type, signal types, status) without needing parameter info.

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?

Clearly states it lists configured observability backends and their reachability, with specific verbs and resource. Distinguishes from sibling 'list_services' by noting what each shows.

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

Usage Guidelines5/5

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

Explicitly states when to use: call first to learn source names and health before passing 'source' to other tools, or to debug no data queries. Mentions related tool 'list_services'.

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

query_logsA
Read-onlyIdempotent

Fetch recent log entries for ONE service over a look-back window, with a pre-computed summary (error/warning counts and the most frequent error patterns). When to use: to inspect what a service actually logged, or to investigate an error spike surfaced by detect_anomalies / get_service_health. For numeric metrics use query_metrics instead. Golden rule: filter + aggregate server-side — pass labels to scope and aggregate (count_over_time/sum/topk) to get numbers, not raw rows. A high-volume window returned raw will blow past your context limit. Prerequisites: get the exact service name from list_services (the service must expose a logs signal). Behavior: read-only, no side effects. Returns the matching log entries (newest first, capped by limit) plus a summary with total/error/warn counts and top recurring error patterns. No matches yields an empty result with a zeroed summary; an unreachable backend yields a structured explanatory error, never an exception.

ParametersJSON Schema
NameRequiredDescriptionDefault
levelNoOptional. Return only entries at this severity. Default: all levels.
limitNoOptional. Maximum number of log entries to return (most recent first). Default: 100. Ignored when `aggregate` is set.
queryNoOptional. Filter expression matched against the log message; regular expressions are supported. Omit to return all entries in the window.
labelsNoOptional. Exact-match filters on backend-extracted log fields (e.g. {"method":"GET","status":"200","url":"/","environment":"prod"}). All AND'd together and compiled to LogQL label filters applied after `| json`, so structured JSON fields become first-class selectors — far more reliable than regex on the raw message. Combine with `aggregate` to filter then group. Backends without label extraction ignore it.
serviceNoRequired (unless `raw_query` is set). Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'payment-service').
durationNoOptional. Look-back window ending at 'now', written as <number><unit> with unit s|m|h|d (e.g. '5m', '1h', '24h'). Default: '5m'.
aggregateNoOptional. Server-side aggregation pushed down to LogQL metric queries — returns grouped counts, not raw rows, so you get a number instead of a haystack (and never hit `limit`). Honours `labels`/`query` filters. Example: {"op":"topk","by":["url"],"k":10} for the busiest paths; {"op":"count_over_time","step":"15m"} for a request-count time series.
raw_queryNoOptional escape hatch: a verbatim LogQL log query, run as-is — for selectors/pipelines the curated params can't express. When set, `service`/`labels`/`level`/`query` are ignored and it is mutually exclusive with `aggregate` (express aggregation in the LogQL itself). DISABLED by default; the operator must enable the raw-query capability (OMCP_RAW_QUERY=on) or the call is refused. Redaction still applies to the returned log lines.
bypass_redactionNoOptional. When true, request that PII/secret redaction be skipped for this single call. The server only honours this when the calling identity is authorised to bypass — a credential listed in OMCP_KEY_BYPASS_REDACTION, or the anonymous identity when the operator set OMCP_BYPASS_REDACTION_ANON=true; otherwise the request still gets redacted output. Default: false.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations indicate read-only, no side effects, which the description confirms and adds details like error handling (no matches yields zeroed summary, unreachable backend yields structured error). No contradictions.

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?

Well-structured with clear sections (purpose, usage, golden rule, prerequisites, behavior, returns). Slightly long but every sentence adds value; could be tightened slightly.

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?

Covers return format, error scenarios, redaction behavior, and prerequisites. Given 9 parameters, nested objects, and no output schema, the description provides sufficient context for correct usage.

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 coverage is 100% with detailed descriptions. The description adds high-level guidance (e.g., 'aggregate' to get numbers, context limit warning), but much is already in schema. The added value is marginal but present.

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?

The description clearly states it fetches recent log entries for ONE service with a pre-computed summary. It distinguishes from siblings like query_metrics and query_traces by specifying log-specific behavior.

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

Usage Guidelines5/5

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

Explicitly states when to use (inspect logs, investigate anomalies) and when not to use (metrics use query_metrics). Provides prerequisite (get service name from list_services) and a 'golden rule' for efficient usage.

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

query_metricsA
Read-onlyIdempotent

Fetch the raw time-series for ONE metric of ONE service over a look-back window, returned together with pre-computed summary statistics. When to use: when you need the actual numeric values or the trend of a known metric. For a 'is this service OK?' verdict use get_service_health; to find which services are misbehaving use detect_anomalies. Prerequisites: get the exact service name from list_services and choose a metric from the list at the end of this description. Behavior: read-only, no side effects. Returns an ordered array of {timestamp, value} points plus a summary {current, average, min, max, trend}. When no series matched (e.g. a logs-only service has no such metric), values is empty and summary is null (not all-zeros) with a note — absent data is not a real zero reading. With groupBy set, returns one labelled series per distinct label value under groups instead of a single aggregated series. Units depend on the metric (e.g. CPU as %, latency as ms, rates as per-second). An unknown service/metric or an unreachable backend yields a structured explanatory error, never an exception. Available metrics: No metrics sources configured.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelsNoOptional. Exact-match label filters (e.g. {"status":"500","route":"/checkout"}) AND'd into the metric's series selector — the PromQL equivalent of the query_logs `labels` param. Use this to scope a curated metric to a subset of series (e.g. error_rate for one route/status) instead of the all-series aggregate. Combine with `groupBy` to filter then break down. Label names must be valid Prometheus identifiers.
metricNoRequired (unless `raw_query` is set). Exact metric name to query. One of: .
sourceNoOptional. Restrict the query to a single backend by its source name (see `list_sources`). Default: query and merge all metrics backends.
groupByNoOptional. Metric label to break the result down by, e.g. 'instance', 'pod', 'node'. When set, the response contains one series per distinct label value under `groups`. Default: a single aggregated series.
serviceNoRequired (unless `raw_query` is set). Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'api-gateway', 'payment-service').
durationNoOptional. Look-back window ending at 'now', written as <number><unit> with unit s|m|h|d (e.g. '5m', '90m', '1h', '24h'). Default: '5m'.
raw_queryNoOptional escape hatch: a verbatim PromQL expression, run as-is over the range — for ad-hoc queries the curated `metric` catalog can't express (any series, any function, broken down by any label). When set, `metric`/`service`/`groupBy`/`labels` are ignored. DISABLED by default; the operator must enable the raw-query capability (OMCP_RAW_QUERY=on) or the call is refused. Still tenant-scoped and source-allow-listed.

TDQS

A4.7/5.0
Behavior5/5

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

Adds behavioral details beyond annotations: read-only, no side effects; handling of absent data (null summary, note); groupBy behavior; units; error responses. Annotations already declare readOnlyHint=true, but description enriches with concrete edge cases.

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?

Front-loaded with purpose, then usage guidance, prerequisites, and behavior details. Every sentence adds value; no redundancy. Well-organized and appropriately sized.

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?

Given no output schema and 7 parameters with nested objects, the description covers return format, edge cases, groupBy behavior, error handling, and units. It is comprehensive for the tool's complexity.

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

Parameters3/5

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

Schema coverage is 100%, so baseline is 3. Description adds context about prerequisites and metric list but does not add new semantics beyond the detailed schema descriptions.

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?

The description clearly states the tool fetches raw time-series for one metric of one service, with specific verb and resource. It distinguishes from siblings like get_service_health and detect_anomalies by scope.

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

Usage Guidelines5/5

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

Explicit when-to-use ('when you need actual numeric values or trend'), when-not-to-use (use get_service_health for health verdict, detect_anomalies for misbehaving services), and prerequisites (get service name from list_services, choose metric from list).

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

query_tracesA
Read-onlyIdempotent

Query distributed traces for a service over a given timeframe. Returns ranked trace summaries (duration, span count, error status) with a p50/p95 aggregate across the returned set. When to use: investigate tail-latency outliers, walk call chains across services for a specific time window, or pull traces related to an anomaly that the metric/log tools surfaced first. Prerequisites: get the exact service name from list_services. A traces connector (e.g. Tempo, installable from the connector hub) must be configured — none is bundled by default, so without one this returns a clean 'No trace backends configured' result. Behavior: read-only. filter accepts the backend's native query language (e.g. TraceQL on Tempo). When errorsOnly=true, only traces with at least one error span are returned. Default limit is 50.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoSoft cap on returned trace summaries. Default 50.
filterNoBackend-native filter (TraceQL on Tempo, tag query on Jaeger). Optional.
serviceYesService name (e.g. 'payment-service').
durationNoRolling time window, e.g. '5m', '1h'. Default '15m'.
errorsOnlyNoIf true, only traces with at least one error span.

TDQS

A4.9/5.0
Behavior5/5

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

States 'Behavior: read-only' aligning with annotations (readOnlyHint=true). Adds details about filter language, errorsOnly behavior, default limit, and what happens if no backend is configured. Provides useful behavioral context beyond annotations.

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?

Well-structured with clear sections. Purpose is front-loaded. Every sentence adds value; no repetition or fluff. Appropriate length for the complexity of the tool.

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?

Description covers return value format (ranked summaries with p50/p95), parameter details, prerequisites, and error case. Despite no output schema, the description provides sufficient contextual completeness for correct tool invocation.

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 coverage is 100%, so baseline is 3. The description adds value by explaining that filter accepts native query language (e.g., TraceQL) and mentions default limit, going beyond individual parameter descriptions. However, it could have included more detail on duration format or error status meaning.

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?

Describes specific verb 'Query' and resource 'distributed traces for a service' with output details (ranked summaries, aggregates). Clearly distinguishes from sibling tools like query_logs and query_metrics.

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

Usage Guidelines5/5

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

Explicitly states when to use (tail-latency, call chains, anomaly follow-up), prerequisites (service name from list_services, connector configuration), and a failure mode (no backend configured). Offers clear usage context.

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. Dates show when Glama detected each change.

  1. 1 tool updatev3.7.0
    • Changedenrich_ips1 field changed
      • changedInput schema / properties / ips / description
        Previous value: -"Required. IPv4 address strings to enrich (e.g. ['203.0.113.5','198.51.100.9']). Max 1000 per call; invalid entries are returned with found=false rather than failing the batch."New value: +"Required. IPv4 or IPv6 address strings to enrich (e.g. ['203.0.113.5','2001:db8::1']). Max 1000 per call; invalid entries are returned with found=false rather than failing the batch."
  2. 3 tool updatesv3.3.0
    • Addedenrich_ips
    • Changedquery_logs7 fields changed
      • addedInput schema / properties / aggregate
        Added value: +{
        +  "description": "Optional. Server-side aggregation pushed down to LogQL metric queries — returns grouped counts, not raw rows, so you get a number instead of a haystack (and never hit `limit`). Honours `labels`/`query` filters. Example: {\"op\":\"topk\",\"by\":[\"url\"],\"k\":10} for the busiest paths; {\"op\":\"count_over_time\",\"step\":\"15m\"} for a request-count time series.",
        +  "properties": {
        +    "by": {
        +      "description": "Label names to group by, e.g. [\"url\"] or [\"status\"]. Required for topk.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "k": {
        +      "description": "For topk: how many top groups to return (1-1000).",
        +      "exclusiveMinimum": 0,
        +      "maximum": 9007199254740991,
        +      "type": "integer"
        +    },
        +    "op": {
        +      "description": "count_over_time = time series of counts per `step` bucket; sum = single total per group over the window; topk = the top `k` groups by total.",
        +      "enum": [
        +        "count_over_time",
        +        "sum",
        +        "topk"
        +      ],
        +      "type": "string"
        +    },
        +    "step": {
        +      "description": "For count_over_time: bucket width as <number><unit> m|h|d (e.g. '15m'). Default auto-derived from duration.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "op"
        +  ],
        +  "type": "object"
        +}
      • changedInput schema / properties / bypass_redaction / description
        Previous value: -"Optional. When true, request that PII/secret redaction be skipped for this single call. The server only honours this when the calling credential was explicitly authorised via OMCP_KEY_BYPASS_REDACTION; otherwise the request still gets redacted output. Default: false."New value: +"Optional. When true, request that PII/secret redaction be skipped for this single call. The server only honours this when the calling identity is authorised to bypass — a credential listed in OMCP_KEY_BYPASS_REDACTION, or the anonymous identity when the operator set OMCP_BYPASS_REDACTION_ANON=true; otherwise the request still gets redacted output. Default: false."
      • addedInput schema / properties / labels
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "description": "Optional. Exact-match filters on backend-extracted log fields (e.g. {\"method\":\"GET\",\"status\":\"200\",\"url\":\"/\",\"environment\":\"prod\"}). All AND'd together and compiled to LogQL label filters applied after `| json`, so structured JSON fields become first-class selectors — far more reliable than regex on the raw message. Combine with `aggregate` to filter then group. Backends without label extraction ignore it.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Optional. Maximum number of log entries to return (most recent first). Default: 100."New value: +"Optional. Maximum number of log entries to return (most recent first). Default: 100. Ignored when `aggregate` is set."
      • addedInput schema / properties / raw_query
        Added value: +{
        +  "description": "Optional escape hatch: a verbatim LogQL log query, run as-is — for selectors/pipelines the curated params can't express. When set, `service`/`labels`/`level`/`query` are ignored and it is mutually exclusive with `aggregate` (express aggregation in the LogQL itself). DISABLED by default; the operator must enable the raw-query capability (OMCP_RAW_QUERY=on) or the call is refused. Redaction still applies to the returned log lines.",
        +  "type": "string"
        +}
      • changedInput schema / properties / service / description
        Previous value: -"Required. Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'payment-service')."New value: +"Required (unless `raw_query` is set). Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'payment-service')."
      • removedInput schema / required
        Removed value: -[
        -  "service"
        -]
    • Changedquery_metrics5 fields changed
      • addedInput schema / properties / labels
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "description": "Optional. Exact-match label filters (e.g. {\"status\":\"500\",\"route\":\"/checkout\"}) AND'd into the metric's series selector — the PromQL equivalent of the query_logs `labels` param. Use this to scope a curated metric to a subset of series (e.g. error_rate for one route/status) instead of the all-series aggregate. Combine with `groupBy` to filter then break down. Label names must be valid Prometheus identifiers.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / metric / description
        Previous value: -"Required. Exact metric name to query. One of: ."New value: +"Required (unless `raw_query` is set). Exact metric name to query. One of: ."
      • addedInput schema / properties / raw_query
        Added value: +{
        +  "description": "Optional escape hatch: a verbatim PromQL expression, run as-is over the range — for ad-hoc queries the curated `metric` catalog can't express (any series, any function, broken down by any label). When set, `metric`/`service`/`groupBy`/`labels` are ignored. DISABLED by default; the operator must enable the raw-query capability (OMCP_RAW_QUERY=on) or the call is refused. Still tenant-scoped and source-allow-listed.",
        +  "type": "string"
        +}
      • changedInput schema / properties / service / description
        Previous value: -"Required. Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'api-gateway', 'payment-service')."New value: +"Required (unless `raw_query` is set). Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'api-gateway', 'payment-service')."
      • removedInput schema / required
        Removed value: -[
        -  "service",
        -  "metric"
        -]
  3. 3 tool updatesv3.1.0
    • Addedgenerate_postmortem
    • Addedget_anomaly_history
    • Addedquery_traces
  4. 1 tool updatev1.8.1
    • Changedquery_logs1 field changed
      • addedInput schema / properties / bypass_redaction
        Added value: +{
        +  "description": "Optional. When true, request that PII/secret redaction be skipped for this single call. The server only honours this when the calling credential was explicitly authorised via OMCP_KEY_BYPASS_REDACTION; otherwise the request still gets redacted output. Default: false.",
        +  "type": "boolean"
        +}
  5. 8 tool updatesv1.7.2
    • Addeddetect_anomalies
    • Addedget_blast_radius
    • Addedget_service_health
    • Addedget_topology
    • Addedlist_services
    • Addedlist_sources
    • Addedquery_logs
    • Addedquery_metrics
  6. 6 tool updatesv1.7.1
    • Removeddetect_anomalies
    • Removedget_service_health
    • Removedlist_services
    • Removedlist_sources
    • Removedquery_logs
    • Removedquery_metrics
  7. 5 tool updatesv0.1.1
    • Changeddetect_anomalies3 fields changed
      • changedInput schema / properties / duration / description
        Previous value: -"Time range to analyze (e.g. '5m', '15m', '1h'). Default: '10m'"New value: +"Optional. Look-back window analyzed for anomalies, written as <number><unit> with unit s|m|h|d (e.g. '5m', '15m', '1h'). Default: '10m'."
      • changedInput schema / properties / sensitivity / description
        Previous value: -"Detection sensitivity: low (>3σ), medium (>2σ), high (>1.5σ). Default: 'medium'"New value: +"Optional. Detection threshold: 'low' flags only strong deviations (>3σ), 'medium' is balanced (>2σ), 'high' is most sensitive and noisier (>1.5σ). Default: 'medium'."
      • changedInput schema / properties / service / description
        Previous value: -"Specific service to scan. If omitted, scans all."New value: +"Optional. Restrict the scan to one service (exact, case-sensitive name from `list_services`). Default: scan every monitored service."
    • Changedget_service_health1 field changed
      • changedInput schema / properties / service / description
        Previous value: -"Service name to check health for"New value: +"Required. Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'payment-service')."
    • Changedlist_services1 field changed
      • changedInput schema / properties / filter / description
        Previous value: -"Optional filter to match service names"New value: +"Optional case-insensitive substring to narrow the result to matching service names (e.g. 'payment'). Omit to list every discovered service."
    • Changedquery_logs9 fields changed
      • changedInput schema / properties / duration / description
        Previous value: -"Time range (e.g. '5m', '1h', '24h'). Default: '5m'"New value: +"Optional. Look-back window ending at 'now', written as <number><unit> with unit s|m|h|d (e.g. '5m', '1h', '24h'). Default: '5m'."
      • changedInput schema / properties / level / description
        Previous value: -"Filter by log level: 'error', 'warn', 'info', 'debug'"New value: +"Optional. Return only entries at this severity. Default: all levels."
      • addedInput schema / properties / level / enum
        Added value: +[
        +  "error",
        +  "warn",
        +  "info",
        +  "debug"
        +]
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum log entries to return. Default: 100"New value: +"Optional. Maximum number of log entries to return (most recent first). Default: 100."
      • addedInput schema / properties / limit / exclusiveMinimum
        Added value: +0
      • addedInput schema / properties / limit / maximum
        Added value: +9007199254740991
      • changedInput schema / properties / limit / type
        Previous value: -"number"New value: +"integer"
      • changedInput schema / properties / query / description
        Previous value: -"Optional search query to filter log messages (regex supported)"New value: +"Optional. Filter expression matched against the log message; regular expressions are supported. Omit to return all entries in the window."
      • changedInput schema / properties / service / description
        Previous value: -"Service name (e.g. 'payment-service')"New value: +"Required. Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'payment-service')."
    • Changedquery_metrics5 fields changed
      • changedInput schema / properties / duration / description
        Previous value: -"Time range (e.g. '5m', '1h', '24h'). Default: '5m'"New value: +"Optional. Look-back window ending at 'now', written as <number><unit> with unit s|m|h|d (e.g. '5m', '90m', '1h', '24h'). Default: '5m'."
      • changedInput schema / properties / groupBy / description
        Previous value: -"Label to break the result down by, e.g. 'instance', 'pod', 'node'. Returns one series per distinct value in 'groups'."New value: +"Optional. Metric label to break the result down by, e.g. 'instance', 'pod', 'node'. When set, the response contains one series per distinct label value under `groups`. Default: a single aggregated series."
      • changedInput schema / properties / metric / description
        Previous value: -"Metric name. Available: "New value: +"Required. Exact metric name to query. One of: ."
      • changedInput schema / properties / service / description
        Previous value: -"Service name (e.g. 'api-gateway', 'payment-service')"New value: +"Required. Exact, case-sensitive service name exactly as returned by `list_services` (e.g. 'api-gateway', 'payment-service')."
      • changedInput schema / properties / source / description
        Previous value: -"Specific source name. If omitted, queries all metrics backends."New value: +"Optional. Restrict the query to a single backend by its source name (see `list_sources`). Default: query and merge all metrics backends."
  8. 6 tool updatesv0.1.0
    • First observeddetect_anomalies
    • First observedget_service_health
    • First observedlist_services
    • First observedlist_sources
    • First observedquery_logs
    • First observedquery_metrics

TDQS

A4.7/5.0
Disambiguation5/5

Each tool targets a distinct observability task: anomaly detection (live vs historical), health verdict vs raw queries, topology vs blast-radius, utilities (IP enrichment, postmortem generation), and discovery (services, sources). No two tools have overlapping purposes.

Naming Consistency5/5

All 12 tools follow a consistent verb_noun pattern in snake_case (e.g., detect_anomalies, get_service_health, list_sources). No mixing of styles or ambiguous verbs.

Tool Count5/5

12 tools is well-scoped for an observability server covering health, anomaly detection, raw data queries (metrics/logs/traces), topology, utilities, and postmortem generation. Each tool serves a clear purpose without redundancy.

Completeness4/5

The tool set covers core observability workflows: discovery, health assessment, raw data inspection, anomaly detection, and postmortem. A minor gap is the lack of a tool to list available metric names per service (since query_metrics requires a known metric name), but this is not critical.

Maintenance

ActivityActive
ResponsivenessResponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Seamlessly bring real-time production context—logs, metrics, and traces—into your local environment to auto-fix code faster.
    327
    60
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    A comprehensive Model Context Protocol (MCP) server for Grafana, Prometheus, Kafka UI, and Datadog. Features a secure "Bring Your Own Key" (BYOK) architecture where credentials stay local. Provides tools for metrics querying, dashboard inspection, Kafka lag monitoring, and unified health checks.
    23
    14
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Unified MCP server for observability and monitoring, providing tools to query metrics, logs, and traces through Prometheus, Grafana, Loki, and Jaeger.
    2
    Mozilla Public 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lean MCP server that provides LLM agents with transparent access to multiple Prometheus instances for metrics analysis and SRE operations.
    4
    GPL 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ThoTischner/observability-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server