{
  "id": "openclaw-grafana-lens",
  "name": "Grafana Lens",
  "description": "Agent-driven Grafana — query, visualize, alert, and deliver to messaging channels",
  "version": "0.5.5",
  "skills": ["./skills"],
  "contracts": {
    "tools": [
      "grafana_create_dashboard",
      "grafana_update_dashboard",
      "grafana_get_dashboard",
      "grafana_share_dashboard",
      "grafana_search",
      "grafana_query",
      "grafana_query_logs",
      "grafana_query_traces",
      "grafana_list_metrics",
      "grafana_explore_datasources",
      "grafana_explain_metric",
      "grafana_create_alert",
      "grafana_check_alerts",
      "grafana_annotate",
      "grafana_push_metrics",
      "grafana_security_check",
      "grafana_investigate",
      "alloy_pipeline"
    ]
  },
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "grafana": {
        "description": "Grafana connection settings — single instance or named instances",
        "oneOf": [
          {
            "type": "object",
            "description": "Single Grafana instance (legacy format)",
            "additionalProperties": false,
            "properties": {
              "url": {
                "type": "string",
                "description": "Grafana instance URL",
                "default": "http://localhost:3000"
              },
              "apiKey": {
                "type": "string",
                "description": "Grafana service account token (glsa_...)"
              },
              "orgId": {
                "type": "number",
                "description": "Grafana organization ID",
                "default": 1
              }
            }
          },
          {
            "type": "object",
            "description": "Multiple named Grafana instances",
            "additionalProperties": false,
            "properties": {
              "instances": {
                "type": "array",
                "description": "Named Grafana instances (first is default unless 'default' is set)",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Instance identifier (e.g., 'dev', 'staging', 'prod')"
                    },
                    "url": {
                      "type": "string",
                      "description": "Grafana instance URL"
                    },
                    "apiKey": {
                      "type": "string",
                      "description": "Grafana service account token (glsa_...)"
                    },
                    "orgId": {
                      "type": "number",
                      "description": "Grafana organization ID",
                      "default": 1
                    }
                  },
                  "required": ["name"]
                }
              },
              "default": {
                "type": "string",
                "description": "Name of the default instance (defaults to first entry)"
              }
            },
            "required": ["instances"]
          }
        ]
      },
      "metrics": {
        "type": "object",
        "description": "Metrics collection toggle",
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "otlp": {
        "type": "object",
        "description": "OTLP push settings for metrics, logs, and traces. Defaults to http://localhost:4318 (LGTM stack collector).",
        "additionalProperties": false,
        "properties": {
          "endpoint": {
            "type": "string",
            "description": "OTLP HTTP endpoint for metrics push",
            "default": "http://localhost:4318/v1/metrics"
          },
          "headers": {
            "type": "object",
            "description": "Additional HTTP headers (e.g., Authorization for Grafana Cloud)",
            "additionalProperties": { "type": "string" }
          },
          "exportIntervalMs": {
            "type": "number",
            "description": "Export interval in milliseconds",
            "default": 15000
          },
          "instanceId": {
            "type": "string",
            "description": "Unique identifier for this agent instance (OTel service.instance.id). Falls back to OTEL_SERVICE_INSTANCE_ID env var, then hostname."
          },
          "logs": {
            "type": "boolean",
            "description": "Enable OTLP log push (structured diagnostic event logs to Loki)",
            "default": true
          },
          "traces": {
            "type": "boolean",
            "description": "Enable OTLP trace push (agent lifecycle and tool call spans to Tempo)",
            "default": true
          },
          "captureContent": {
            "type": "boolean",
            "description": "Include conversation text (prompts, completions, messages) in logs and spans. Disable for cloud/multi-tenant deployments.",
            "default": true
          },
          "contentMaxLength": {
            "type": "number",
            "description": "Maximum character length for captured content fields (truncated beyond this limit)",
            "default": 2000
          },
          "forwardAppLogs": {
            "type": "boolean",
            "description": "Forward openclaw application logs (tslog output) to Loki via OTLP",
            "default": true
          },
          "appLogMinSeverity": {
            "type": "string",
            "description": "Minimum severity for forwarded app logs: trace, debug, info, warn, error, fatal",
            "default": "debug",
            "enum": ["trace", "debug", "info", "warn", "error", "fatal"]
          },
          "redactSecrets": {
            "type": "boolean",
            "description": "Auto-redact API keys, tokens, and PEM blocks before sending to OTLP",
            "default": true
          }
        }
      },
      "proactive": {
        "type": "object",
        "description": "Alert webhook handler — receives Grafana alert notifications and makes them visible to the agent.",
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Enable alert webhook handler to receive Grafana alert notifications",
            "default": false
          },
          "webhookPath": {
            "type": "string",
            "description": "HTTP path for the alert webhook endpoint",
            "default": "/grafana-lens/alerts"
          },
          "costAlertThreshold": {
            "type": "number",
            "description": "Daily cost threshold (USD) that triggers an alert",
            "default": 5.0
          }
        }
      },
      "customMetrics": {
        "type": "object",
        "description": "Custom metrics store — allows the agent to push arbitrary data (calendar, git, fitness, finance) via grafana_push_metrics.",
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Enable custom metrics push via grafana_push_metrics tool",
            "default": true
          },
          "maxMetrics": {
            "type": "number",
            "description": "Maximum number of custom metric definitions",
            "default": 100
          },
          "maxLabelsPerMetric": {
            "type": "number",
            "description": "Maximum label keys per metric",
            "default": 5
          },
          "maxLabelValues": {
            "type": "number",
            "description": "Maximum unique label-value combinations per metric",
            "default": 50
          },
          "defaultTtlDays": {
            "type": "number",
            "description": "Default TTL in days for custom metrics (omit for no expiry)"
          }
        }
      },
      "alloy": {
        "type": "object",
        "description": "Grafana Alloy pipeline management — create and manage data collection pipelines via the alloy_pipeline tool.",
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Enable Alloy pipeline management",
            "default": false
          },
          "url": {
            "type": "string",
            "description": "Alloy HTTP API base URL",
            "default": "http://localhost:12345"
          },
          "configDir": {
            "type": "string",
            "description": "Directory where .alloy config files are written (must be readable by Alloy)"
          },
          "filePrefix": {
            "type": "string",
            "description": "Filename prefix for managed pipeline configs",
            "default": "lens-"
          },
          "maxPipelines": {
            "type": "number",
            "description": "Maximum number of managed pipelines",
            "default": 20
          },
          "lgtm": {
            "type": "object",
            "description": "LGTM backend URLs for generated pipeline configs (use Docker service names if Alloy runs in Docker)",
            "additionalProperties": false,
            "properties": {
              "prometheusRemoteWriteUrl": {
                "type": "string",
                "description": "Prometheus remote_write endpoint",
                "default": "http://localhost:9009/api/prom/push"
              },
              "lokiUrl": {
                "type": "string",
                "description": "Loki push endpoint",
                "default": "http://localhost:3100/loki/api/v1/push"
              },
              "otlpEndpoint": {
                "type": "string",
                "description": "OTLP endpoint for traces/metrics/logs",
                "default": "http://localhost:4318"
              }
            }
          }
        }
      }
    }
  },
  "uiHints": {
    "grafana.apiKey": {
      "label": "API Key",
      "sensitive": true,
      "placeholder": "glsa_xxxxxxxxxxxx"
    },
    "grafana.url": {
      "label": "Grafana URL",
      "placeholder": "http://localhost:3000"
    }
  }
}
