Create, modify, validate, publish, and visually review Grafana dashboards. Use when building dashboards, editing panels/variables/links, finding dashboard examples, using gcx, or taking Playwright screenshots of Grafana dashboards.
72
88%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Build Grafana dashboards as diagnostic tools, not metric inventories. Use gcx for API/resource work and Python Playwright for UI screenshots.
There are two independent auth layers:
A gcx context can be online but still fail writes with 403. A browser profile can be logged out even when gcx works.
Classify API failures:
gcx config check fails, token expired, login requiredBefore saving/updating:
gcx config current-context
gcx config check
gcx config list-contextsTry an explicitly appropriate context if available. Report the context used.
context → symptom → culprit/entity → subsystem path → resources/efficiency.gcx.Local repo examples are optional and only allowed when project instructions permit broad scans:
find . -iname '*dashboard*' -o -iname '*grafana*' | head -100
rg -n 'gridPos|templating|panels|dashboard|grafana-foundation-sdk' .Live Grafana examples are often better for datasource variables and folder conventions:
gcx dashboards search '<keyword>' -o wide
gcx dashboards get <uid> -o jsonFallback when gcx dashboards resource API/RBAC fails:
gcx api '/api/search?query=<keyword>' -o json
gcx api /api/dashboards/uid/<uid> -o jsonExtract useful patterns:
jq -r '.. | objects | select(.expr?) | .expr' dashboard.json | sort -u
jq '.dashboard.templating.list[]? | {name,type,query,current}' dashboard.json
jq '.dashboard.panels[]? | {id,title,type,gridPos}' dashboard.jsonIf multiple Prometheus/Loki/Tempo datasources exist, infer from existing dashboards in the same folder/team. If still ambiguous, ask one concise datasource question.
Examples:
gcx metrics query 'up' -o json
gcx datasources prometheus query -d <prom_uid> 'count by (__name__) ({__name__=~".*query.*"})' --since 5m -o json
gcx datasources loki query -d <loki_uid> '{namespace="example"} | logfmt' --since 1h -o raw
gcx traces labels -d <tempo_uid> -o jsonCheck metric existence, labels, units, histogram buckets, status/route/op labels, and parsed log fields.
Rows should tell a story. Keep only the triage row open unless the dashboard is explicitly a drilldown.
Common row flow:
Triage + context
User outcome
Tenant/entity evidence
Frontend/gateway scheduling
Worker/backend execution
Storage/cache path
Resource pressure
Efficiency / before-after tuningEach row should have a decision-gate description.
Row JSON example:
{
"id": 10,
"type": "row",
"title": "Query-frontend → queriers: scheduling",
"description": "Move here when latency rises with queueing or throttles. Check batch weight, connected clients, and frontend cache health.",
"collapsed": true,
"gridPos": {"x": 0, "y": 12, "w": 24, "h": 1},
"panels": []
}Panel conventions:
topk() for high-cardinality tenants/podsFetch:
gcx api /api/dashboards/uid/<uid> -o json > /tmp/dashboard.jsonPush payload shape:
{"dashboard": {...}, "folderUid": "<folderUid>", "message": "Explain change", "overwrite": true}Push:
gcx api /api/dashboards/db -d @/tmp/payload.json -o jsonNo dry-run exists for this endpoint. Fetch back and verify:
gcx api /api/dashboards/uid/<uid> -o json \
| jq '{uid:.dashboard.uid,title:.dashboard.title,version:.dashboard.version,folder:.meta.folderUid,panels:(.dashboard.panels|length),vars:[.dashboard.templating.list[]?.name]}'For resource-managed dashboards prefer:
gcx resources pull dashboards/<uid> -p ./resources
gcx resources validate -p ./resources
gcx resources push -p ./resources --dry-run
gcx resources push -p ./resourcesUse absolute dashboard paths for internal links to avoid app-relative redirects:
/d/<uid>/<slug>?${__url_time_range}&${varname:queryparam}&var-tenant=${__field.labels.tenant}For trace links, provide both exact trace and log-correlation fallback:
{cluster=~"$cluster", namespace=~"$namespace"} |= "$traceID"Long table-row URLs can be brittle. Provide a manual fallback in panel descriptions/prompts.
Install once per machine:
python3 -m venv ~/.cache/grafana-dashboard-screenshot/venv
~/.cache/grafana-dashboard-screenshot/venv/bin/python -m pip install --upgrade pip
~/.cache/grafana-dashboard-screenshot/venv/bin/python -m pip install -r /path/to/skill/requirements.txt
~/.cache/grafana-dashboard-screenshot/venv/bin/python -m playwright install chromiumHelper:
scripts/grafana_dashboard_screenshot.pyList profiles before declaring browser auth missing:
~/.cache/grafana-dashboard-screenshot/venv/bin/python /path/to/skill/scripts/grafana_dashboard_screenshot.py profiles
ls -1 ~/.cache/grafana-dashboard-screenshot/ 2>/dev/null || trueIf a host-matching profile exists, retry capture with --profile-name or --profile-dir.
Start a non-blocking headed login browser:
~/.cache/grafana-dashboard-screenshot/venv/bin/python /path/to/skill/scripts/grafana_dashboard_screenshot.py login-start \
--url 'https://grafana.example.com' \
--profile-name grafana-exampleTell the user exactly:
Log in in the opened browser, then say continue.When the user says continue:
~/.cache/grafana-dashboard-screenshot/venv/bin/python /path/to/skill/scripts/grafana_dashboard_screenshot.py login-finish \
--url 'https://grafana.example.com' \
--profile-name grafana-exampleBlocking human mode also exists: login.
~/.cache/grafana-dashboard-screenshot/venv/bin/python /path/to/skill/scripts/grafana_dashboard_screenshot.py capture \
--url 'https://grafana.example.com/d/<uid>/<slug>?from=now-1h&to=now' \
--profile-name grafana-example \
--output './screenshots/dashboard.png' \
--viewport 1800x1400 \
--wait-ms 8000Useful options:
--profile-dir <path>
--selector 'body'
--full-page / --no-full-page
--headed
--wait-for-text '<dashboard title>'
--allow-login-pageFor layout review, use a wide viewport. If the left nav wastes space, use a larger viewport, collapse nav in the profile, or use kiosk/embedded/solo-style URL options when appropriate.
Review checklist:
Include:
144f0eb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.