byok-observability-mcp

byok-observability-mcp

Query your observability stack from Claude Code, Codex, or any MCP client and no data leaves your machine.

[![npm version](https://img.shields.io/npm/v/byok-observability-mcp)](https://www.npmjs.com/package/byok-observability-mcp) [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE) [![Awesome MCP Servers](https://img.shields.io/badge/Awesome-MCP_Servers-brightgreen)](https://github.com/punkpeye/awesome-mcp-servers) [![Node ≥18](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org) [![alimuratkuslu/byok-observability-mcp MCP server](https://glama.ai/mcp/servers/alimuratkuslu/byok-observability-mcp/badges/score.svg?v=0.5.1)](https://glama.ai/mcp/servers/alimuratkuslu/byok-observability-mcp)

Grafana Prometheus Kafka UI Datadog

--- **Bring Your Own Keys** — credentials stay in env vars on your machine. No clone, no build, runs via `npx`. **Partial setup** — configure only the backends you use. Tools for unconfigured backends are never exposed.

Quick Start · Tools · Credentials · Configuration · Scheduled Reports · Examples · Security · Development

--- ## How it works
     🤖 Claude Code / Codex CLI      
                 │                   
                 ▼                   
     ⚡ byok-observability-mcp       
        (Local npx process)          
                 │                   
  🔒 env vars never leave your machine 
                 │                   
                 ▼                   
 ┌─────────────────────────────────┐ 
 │  📊 Grafana     🔥 Prometheus   │ 
 │  🛶 Kafka UI    🐶 Datadog      │ 
 └─────────────────────────────────┘ 
--- ## ⚡ Quick Start ### Option A — Interactive wizard (recommended) Run once, answer a few questions, get a ready-made `.mcp.json`: ```bash npx byok-observability-mcp --init ``` The wizard will: - Let you pick which backends to configure - Ask for credentials per service - Test connectivity with your real endpoints before writing anything - Write `.mcp.json` to your project root or `~/.claude/` — your choice Then just start Claude Code: ```bash claude ``` > [!TIP] > **That's it.** No clone, no build, no env file. Works in under 60 seconds. --- ### Option B — Manual `.mcp.json` Create `.mcp.json` in your project root. Include **only** the backends you need. ```json { "mcpServers": { "observability-mcp": { "command": "npx", "args": ["-y", "byok-observability-mcp"], "env": { "GRAFANA_URL": "https://grafana.mycompany.internal", "GRAFANA_TOKEN": "glsa_...", "PROMETHEUS_URL": "https://prometheus.mycompany.internal", "KAFKA_UI_URL": "https://kafka-ui.mycompany.internal", "DD_API_KEY": "your-datadog-api-key", "DD_APP_KEY": "your-datadog-app-key" } } } } ``` > **Credentials in git?** Use the `${VAR}` approach instead — see [Configuration → Method B](#method-b--keep-credentials-out-of-git). Start Claude Code: ```bash claude ``` Claude Code reads `.mcp.json` automatically. No `claude mcp add`, no build step. Verify by asking Claude: ``` What observability tools do you have available? ``` --- ## 🧩 Supported clients | Client | Configuration | |--------|--------------| | **Claude Code** | `.mcp.json` in project root (recommended) or `claude mcp add` CLI | | **OpenAI Codex CLI** | `.mcp.json` in project root — same format as Claude Code | Both clients read `.mcp.json` automatically. The Quick Start above works for either.
Codex CLI example ```bash # Same .mcp.json as above works out of the box codex ``` Or add via CLI: ```bash codex mcp add --transport stdio observability-mcp -- npx -y byok-observability-mcp ```
--- ## 🔧 Available tools
🛰️ System — 1 tool > Always available. Checks connectivity across all configured backends. | Tool | Description | |------|-------------| | `obs_health_check` | **Unified Health Check.** Runs a parallel check on all backends and returns a status table. |
Grafana  7 tools > Enabled when `GRAFANA_URL` + `GRAFANA_TOKEN` are set. | Tool | Description | |------|-------------| | `grafana_health` | Check connectivity, version, and database status | | `grafana_list_datasources` | List all datasources (name, type, UID) | | `grafana_query_metrics` | Run a PromQL expression via a Grafana datasource | | `grafana_list_dashboards` | Search and list dashboards by name or tag | | `grafana_get_dashboard` | Get panels and metadata for a dashboard by UID | | `grafana_list_alerts` | List active alerts from Alertmanager (firing/pending) | | `grafana_get_alert_rules` | List all configured alert rules across all folders |
Prometheus  5 tools > Enabled when `PROMETHEUS_URL` is set. | Tool | Description | |------|-------------| | `prometheus_health` | Check connectivity | | `prometheus_query` | Instant PromQL query — current value of a metric | | `prometheus_query_range` | Range PromQL query — metric values over time | | `prometheus_list_metrics` | List all available metric names | | `prometheus_metric_metadata` | Get help text and type for a specific metric |
Kafka UI  6 tools > Enabled when `KAFKA_UI_URL` is set. | Tool | Description | |------|-------------| | `kafka_list_clusters` | List configured Kafka clusters and their status | | `kafka_list_topics` | List topics in a cluster | | `kafka_describe_topic` | Get partition count, replication factor, and config | | `kafka_list_consumer_groups` | List consumer groups and their state | | `kafka_consumer_group_lag` | Get per-partition lag for a consumer group | | `kafka_broker_health` | Broker count and disk usage per broker |
Datadog  proxied via official server > Enabled when both `DD_API_KEY` and `DD_APP_KEY` are set. Proxies the [official Datadog MCP server](https://docs.datadoghq.com/developers/mcp/). Default toolsets: `core`, `apm`, `alerting`. Set `DD_TOOLSETS=all` to load everything. | Toolset | Covers | |---------|--------| | `core` | Metrics, dashboards, monitors, infrastructure | | `apm` | APM services, traces, service map | | `alerting` | Monitors, downtimes, alerts | | `logs` | Log search and analytics | | `incidents` | Incident management | | `ddsql` | SQL-style metric queries | | `security` | Cloud security posture | | `synthetics` | Synthetic test results | | `networks` | Network performance monitoring | | `dbm` | Database monitoring | | `software-delivery` | CI/CD pipelines | | `llm-obs` | LLM observability | | `cases` | Case management | | `feature-flags` | Feature flag tracking |
--- ## 🔑 Getting credentials
Grafana  Service account token 1. Open Grafana → **Administration** → **Users and access** → **Service accounts** 2. Click **Add service account** → set Role to `Viewer` → **Create** 3. On the service account page → **Add service account token** → **Generate token** 4. Copy the token (starts with `glsa_`) — you won't see it again ``` GRAFANA_URL=https://grafana.mycompany.internal GRAFANA_TOKEN=glsa_xxxxxxxxxxxxxxxx ``` If your Grafana uses a self-signed certificate: ``` GRAFANA_VERIFY_SSL=false ```
Prometheus  URL (+ optional basic auth) If Prometheus has no authentication: ``` PROMETHEUS_URL=https://prometheus.mycompany.internal ``` If Prometheus uses basic auth: ``` PROMETHEUS_URL=https://prometheus.mycompany.internal PROMETHEUS_USERNAME=your-username PROMETHEUS_PASSWORD=your-password ```
Kafka UI  URL (+ optional login) If Kafka UI has no authentication: ``` KAFKA_UI_URL=https://kafka-ui.mycompany.internal ``` If Kafka UI requires a login: ``` KAFKA_UI_URL=https://kafka-ui.mycompany.internal KAFKA_UI_USERNAME=admin KAFKA_UI_PASSWORD=your-password ```
Datadog  API key + Application key **API key:** Datadog → **Organization Settings** → **API Keys** → New Key **Application key:** Datadog → **Organization Settings** → **Application Keys** → New Key **DD_SITE** — match your Datadog login URL: | Login URL | DD_SITE | |-----------|---------| | `app.datadoghq.com` | `datadoghq.com` (default) | | `app.us3.datadoghq.com` | `us3.datadoghq.com` | | `app.us5.datadoghq.com` | `us5.datadoghq.com` | | `app.datadoghq.eu` | `datadoghq.eu` | | `app.ap1.datadoghq.com` | `ap1.datadoghq.com` | ``` DD_API_KEY=your-api-key DD_APP_KEY=your-application-key DD_SITE=datadoghq.com DD_TOOLSETS=core,apm,alerting ```
--- ## ⚙️ Configuration ### Method A — Values directly in `.mcp.json` (simplest) Put credentials directly in `.mcp.json`. Works everywhere, no extra steps. Add `.mcp.json` to your `.gitignore` if the repo is shared.
Method B — Keep credentials out of git Use `${VAR}` placeholders in `.mcp.json` and put real values in `.env`. **`.mcp.json`** (safe to commit — contains no secrets): ```json { "mcpServers": { "observability-mcp": { "command": "npx", "args": ["-y", "byok-observability-mcp"], "env": { "GRAFANA_URL": "${GRAFANA_URL}", "GRAFANA_TOKEN": "${GRAFANA_TOKEN}", "PROMETHEUS_URL": "${PROMETHEUS_URL}", "KAFKA_UI_URL": "${KAFKA_UI_URL}", "DD_API_KEY": "${DD_API_KEY}", "DD_APP_KEY": "${DD_APP_KEY}" } } } } ``` **`.env`** (add to `.gitignore`): ``` GRAFANA_URL=https://grafana.mycompany.internal GRAFANA_TOKEN=glsa_... ``` Start Claude with the env loaded: ```bash set -a && source .env && set +a && claude ``` A ready-made helper script is included: ```bash ./scripts/run-claude-with-env.sh ``` A template `.mcp.json` with all variables is available as [`.mcp.json.example`](./.mcp.json.example).
Method C — Global config (available in every project) Add to `~/.claude.json`: ```json { "mcpServers": { "observability-mcp": { "command": "npx", "args": ["-y", "byok-observability-mcp"], "env": { "GRAFANA_URL": "https://grafana.mycompany.internal", "GRAFANA_TOKEN": "glsa_..." } } } } ```
--- ## 📋 Environment variables | Variable | Backend | Required | Description | |----------|---------|:--------:|-------------| | `GRAFANA_URL` | Grafana | ✅ | Base URL of your Grafana instance | | `GRAFANA_TOKEN` | Grafana | ✅ | Service account token (Viewer role) | | `GRAFANA_VERIFY_SSL` | Grafana | | Set to `false` to skip TLS verification | | `PROMETHEUS_URL` | Prometheus | ✅ | Base URL of your Prometheus instance | | `PROMETHEUS_USERNAME` | Prometheus | | Basic auth username | | `PROMETHEUS_PASSWORD` | Prometheus | | Basic auth password | | `KAFKA_UI_URL` | Kafka UI | ✅ | Base URL of your Kafka UI instance | | `KAFKA_UI_USERNAME` | Kafka UI | | Login username | | `KAFKA_UI_PASSWORD` | Kafka UI | | Login password | | `DD_API_KEY` | Datadog | ✅ | Datadog API key | | `DD_APP_KEY` | Datadog | ✅ | Datadog Application key | | `DD_SITE` | Datadog | | Datadog site (default: `datadoghq.com`) | | `DD_TOOLSETS` | Datadog | | Tool groups to load (default: `core,apm,alerting`) | | `SLACK_WEBHOOK_URL` | Reports | ✅* | Slack Incoming Webhook URL for scheduled reports | | `REPORT_BACKENDS` | Reports | | Comma-separated backends to include in reports (default: all configured) | --- ## 📊 Scheduled Reports Send an automated observability digest to Slack on a schedule — no Claude or Codex instance needs to be running. ### How it works ``` cron / launchd │ fires every N minutes ▼ npx byok-observability-mcp --report │ │ reads env vars, connects directly to backends ▼ Grafana · Prometheus · Kafka UI │ │ categorizes findings → P0 / P1 / P2 / P3 ▼ Slack Incoming Webhook → #your-channel ``` The command collects data, categorizes every finding by severity, formats a Slack message, sends it, and exits. It is completely stateless. ### Severity levels | Level | Meaning | Examples | |-------|---------|---------| | 🔴 **P0 — KRİTİK** | Service down or unreachable | Grafana alert firing (critical), Kafka cluster offline, backend unreachable | | 🟠 **P1 — YÜKSEK** | Degraded, action needed soon | Grafana alert firing (non-critical), Kafka consumer lag > 10 000 | | 🟡 **P2 — ORTA** | Warning, monitor closely | Grafana alert pending, Kafka consumer lag > 1 000 | | 🟢 **P3 — BİLGİ** | Informational, all normal | Healthy backends, silenced alerts | ### Setup **Step 1 — Get a Slack Incoming Webhook URL** 1. Go to [api.slack.com/apps](https://api.slack.com/apps) → **Create New App** → **From scratch** 2. **Incoming Webhooks** → toggle on → **Add New Webhook to Workspace** 3. Pick a channel → **Allow** → copy the Webhook URL **Step 2 — Set environment variables** ```bash export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXX/YYY/ZZZ # Optional: restrict which backends are included (default: all configured) export REPORT_BACKENDS=grafana,prometheus,kafka ``` **Step 3 — Run a one-off report to verify** ```bash npx byok-observability-mcp --report ``` You should see a message in your Slack channel within seconds. **Step 4 — Schedule with cron** Open your crontab: ```bash crontab -e ``` Add a line. Examples: ```cron # Every hour at minute 0 0 * * * * SLACK_WEBHOOK_URL=https://hooks.slack.com/... GRAFANA_URL=... GRAFANA_TOKEN=... npx byok-observability-mcp --report >> /tmp/obs-report.log 2>&1 # Every 30 minutes */30 * * * * SLACK_WEBHOOK_URL=https://hooks.slack.com/... npx byok-observability-mcp --report >> /tmp/obs-report.log 2>&1 ``` > [!TIP] > Put all env vars in a `.env` file and source it inside the cron command to keep the crontab clean: > ```cron > 0 * * * * bash -c 'source /path/to/.env && npx byok-observability-mcp --report' >> /tmp/obs-report.log 2>&1 > ``` **Alternative: macOS launchd (runs on login, survives reboots)** Create `~/Library/LaunchAgents/com.observability-mcp.report.plist`: ```xml Label com.observability-mcp.report ProgramArguments /usr/local/bin/npx byok-observability-mcp --report EnvironmentVariables SLACK_WEBHOOK_URL https://hooks.slack.com/services/XXX/YYY/ZZZ GRAFANA_URL https://grafana.mycompany.internal GRAFANA_TOKEN glsa_... StartInterval 3600 StandardOutPath /tmp/obs-report.log StandardErrorPath /tmp/obs-report.log ``` Load it: ```bash launchctl load ~/Library/LaunchAgents/com.observability-mcp.report.plist ``` To stop: `launchctl unload ~/Library/LaunchAgents/com.observability-mcp.report.plist` --- ## 💬 Example prompts ### Single-backend queries | Backend | Try asking Claude... | |---------|---------------------| | Grafana | *"List all datasources and tell me which ones are Prometheus type."* | | Grafana | *"Search for dashboards related to 'kubernetes' — list names and UIDs."* | | Grafana | *"Query `http_requests_total` rate over the last hour via the default Prometheus datasource."* | | Prometheus | *"What is the current value of the `up` metric? Which targets are down?"* | | Prometheus | *"Show CPU usage (`node_cpu_seconds_total` rate) over the past hour, by instance."* | | Prometheus | *"List all available metrics that start with `http_`."* | | Kafka UI | *"List all Kafka clusters. Are there any with offline brokers?"* | | Kafka UI | *"Describe the topic 'orders' in cluster 'production' — partitions and replication factor?"* | | Kafka UI | *"Check consumer lag for group 'order-processor'. Which partitions have the highest lag?"* | | Datadog | *"List all Datadog monitors currently in Alert state."* | | Datadog | *"Show APM service performance for the past hour. Which services have the highest error rate?"* | | Datadog | *"Query `aws.ec2.cpuutilization` for the last 30 minutes. Which hosts are above 80%?"* | ### 🛠️ Incident Response (v0.2.0+) | Goal | Try asking Claude... | |------|---------------------| | Health | *"Run a health check on all systems."* | | Alerts | *"Are there any firing alerts in Grafana right now?"* | | Triage | *"Show me the alert rules for the 'Production' folder."* | ### Cross-backend queries ``` Check the health of all configured observability backends and give me a summary. ``` ``` I'm seeing high error rates. Check Prometheus for http_requests_total with status=500, then look for related Datadog monitors that might be alerting. ``` --- ## 🔒 Security > [!NOTE] > All tools are **read-only**. No write operations are performed on any backend. > [!IMPORTANT] > Credentials are read from environment variables and **never logged or sent to Anthropic**. Tokens are redacted in all error messages. - TLS certificate verification is enabled by default - The MCP process runs locally — your infrastructure URLs only reach Claude's context window if you type them into the chat **Least-privilege recommendations:** | Backend | Recommended role | |---------|-----------------| | Grafana | Service account with **Viewer** role | | Prometheus | Network-level read-only access | | Kafka UI | Read-only UI user | | Datadog | API key + Application key with read scopes | --- ## 🛠 Development ```bash git clone https://github.com/alimuratkuslu/byok-observability-mcp cd byok-observability-mcp npm install npm run dev # run with tsx (no build step) npm run build # compile to dist/ npm run typecheck # TypeScript check without emitting ``` ### Tested versions | Backend | Tested version | |---------|---------------| | Grafana | v9.x, v10.x, v11.x | | Prometheus | v2.x | | Kafka UI | `provectus/kafka-ui:v0.7.2` | --- ## License MIT