Grafana Dashboard Authoring
SkillMonitoring & opsLets your agent create and manage Grafana dashboards to monitor your systems.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Grafana Dashboard Authoring skill
About this capability
Author Grafana dashboards with MCP-driven metric discovery, visual iteration via the image renderer, and consistent layout conventions extracted from existing dashboards.
What this skill tells your AI
The instructions your AI receives, as published by ionfury/homelab in .claude/skills/grafana-dashboards/SKILL.md and read by ahel’s review.
This skill covers creating and iterating on Grafana dashboards using the MCP-driven workflow. For querying Prometheus directly, see the prometheus skill. For monitoring resources (alerts, ServiceMonitors), see the monitoring-authoring skill.
Prerequisites
- mcp-grafana MCP server configured in
.mcp.json(already set up) - Port-forward to Grafana:
kubectl port-forward svc/grafana 3000:80 -n monitoring & - Image Renderer deployed in-cluster (enabled in Grafana Helm values)
Anonymous auth is enabled at Admin role — no service account token needed.
MCP-Driven Workflow
discover metrics → build JSON → push to Grafana → screenshot → iterate → write ConfigMap
Step 1: Discover Available Metrics
Never guess metric names. Always discover them via MCP first:
MCP tool: list_prometheus_metric_names # Find what exists
MCP tool: list_prometheus_metric_metadata # Type and help text (metric: "up")
MCP tool: list_prometheus_label_values # Filter options (label: "namespace")
MCP tool: query_prometheus # Test a query (expr: "sum(...)")
Step 2: Build Dashboard JSON
Use the conventions in this skill plus the reference files below to construct dashboard JSON.
Step 3: Push to Grafana for Preview
MCP tool: update_dashboard
dashboard: { ...full dashboard JSON... }
overwrite: true
Grafana has persistence.enabled: false — dashboards pushed via API are ephemeral (survive until pod restart). Safe to experiment freely.
Step 4: Visual Review with Screenshots
MCP tool: get_panel_image
dashboardUid: "my-dashboard"
panelId: 1 # omit for full dashboard
width: 800
height: 400
theme: "dark"
Step 5: Iterate
Repeat steps 2-4 until satisfied.
Step 6: Write ConfigMap for Git
---
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-dashboard-<slug>
namespace: monitoring
labels:
grafana_dashboard: "true" # REQUIRED for sidecar discovery
annotations:
grafana_folder: "<FolderName>" # Controls Grafana UI folder
data:
<slug>.json: |-
{ ...dashboard JSON... }
Register in kubernetes/platform/config/monitoring/kustomization.yaml (add alphabetically).
Data key should match the dashboard uid. Use |- for the JSON body.
Dashboard Structure
See [references/dashboard-reference.md] for the full JSON skeleton, field conventions, folder taxonomy, and existing dashboard UIDs to use as reference.
Key rules:
"id": nullalways (Grafana assigns on import)"graphTooltip": 1always (shared crosshair)"datasource": { "type": "prometheus", "uid": "prometheus" }always — never${datasource}"uid"— kebab-case, unique across all dashboards
Grid Layout
The Grafana grid is 24 columns wide. See [references/layout-conventions.md] for width/height tables and layout patterns.
Quick reference:
- Three equal panels:
w:8each,x: 0, 8, 16 - Four stat panels:
w:6each,x: 0, 6, 12, 18 - Six compact stats:
w:4each,x: 0, 4, 8, 12, 16, 20 - Rows: always
h:1, w:24, x:0; panels start aty: row_y + 1
Panel Types
See [references/panel-reference.md] for complete JSON examples for stat, timeseries, gauge, table, and bar gauge panels.
Every panel must have a "description" field that:
- States what the metric measures
- Names the alert that fires when the threshold is crossed (if applicable)
- Indicates which direction is bad
Example: "Active DB connections as % of max_connections. Above 80% triggers CNPGClusterHighConnections."
PromQL, Colors, and Units
See [references/promql-patterns.md] for:
- Common PromQL patterns (rate, ratio, histogram quantile, boolean, time-based)
- Unit reference table
- Color/threshold conventions (more-is-worse, less-is-worse, binary)
- Domain-specific threshold values (DB, cache, storage, temperature, backup)
Anti-Patterns
| Mistake | Impact | Fix |
|---|---|---|
| Guessing metric names | Blank panels | Use MCP list_prometheus_metric_names first |
Using ${datasource} variable | Breaks on import | Always { "type": "prometheus", "uid": "prometheus" } |
| Hardcoding domains in panel links | Breaks across clusters | Use ${internal_domain} substitution |
Overlapping gridPos coordinates | Panels stack incorrectly | Calculate y offsets carefully |
Missing grafana_dashboard: "true" label | Sidecar ignores ConfigMap | Always include the label |
Including pluginVersion field | Churn on Grafana upgrades | Omit from new dashboards |
Setting "id" to a specific number | Conflicts on import | Always use null |
Keywords
Grafana, dashboard, JSON, ConfigMap, sidecar, panel, timeseries, stat, gauge, table, bar gauge, gridPos, layout, PromQL, metrics, visualization, image renderer, screenshot, mcp-grafana, dashboard authoring
Signals
- GitHub stars
- 25
- Forks
- 3
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
grafana-dashboards- Source
- github.com/ionfury/homelab