The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Observability MCP listing page.
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.
Twelve read-only tools (readOnlyHint: true on every one) · server-side filter/aggregate
so agents get numbers, not haystacks · For-Agents guide
📖 Full documentation site: https://thotischner.github.io/observability-mcp/
🔌 Open in MCP Inspector — one-line interactive explorer:
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 — hallucinates the wrong entity type (prometheus, loki, kubernetes) |
Same model + get_topology + get_blast_radius | 10 / 10 — 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).
Wire it into Claude Code with one CLI call:
…or commit it to your repo as .mcp.json (works the same in Claude Desktop / Cursor):
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-codeormake connect-cursor.make doctorround-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-oidcboots 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-opaboots 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_FILEto 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:
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):
See make help for all canonical workflows.
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.
job / service / app / service_name so service filtering Just Works.service_name / service / job / app / container, including Docker-shipped streams with leading slashes.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?
It borrows AppArmor's learning workflow and a service-mesh traffic view (think Kiali, for agent tool calls):
anonymous → query_logs · service ∈ {payment-service} —
learned from N calls), and accept / edit / reject each one. Only accepted
rules ever gate traffic.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.
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:
| Inspect — flow graph | Inspect — learn a profile |
|---|---|
![]() | ![]() |
| Dashboard | Service health | Connector hub |
|---|---|---|
![]() | ![]() | ![]() |
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.
| 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.
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.
For full configuration — paths, env vars, ${VAR} substitution, complete sources.yaml reference — see docs/configuration.md.
Then open the Web UI at http://localhost:3000, click Sources → + Add Source, point at your Prometheus/Loki URLs. Or skip the UI:
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.
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.
For producing credible RCA numbers against a real microservice workload (~23 services, native OTel instrumentation):
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.
| 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.
Connect Claude Code directly — no agent needed.
CLI:
Or .mcp.json in your project root (commit-friendly):
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:
"Show me the error logs for payment-service."
Claude calls query_logs:
Claude correlates the signals — CPU spike, error logs flooding, request rate halved — and explains the incident in plain language. No PromQL, no LogQL.
Three example microservices generate traffic and support chaos injection:
The agent (docs/agent.md) detects anomalies within 30 seconds and produces an LLM incident analysis if Ollama is running.
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):
Then:
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 --.
${VAR} substitution, full sources.yaml reference/api/* planequery_logs output before it reaches the agent; opt-out via OMCP_REDACTION=offresolvedSeries, prom-client compatibilitykind / relation contract every topology-capable connector emits, plus the warn-only validatorhub/)| 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.
TypeScript + Node 20, @modelcontextprotocol/sdk (Streamable HTTP), Express, Zod, js-yaml, prom-client (example services), Prometheus, Loki, Promtail, Docker Compose, optional Ollama.
npx)docker-compose up --build.Ideas: new connectors (InfluxDB, Elasticsearch, Datadog), additional analysis algorithms, UI improvements.
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.