Back in January, during that snowstorm, I wrote about using Claude Code and Codex to crawl a Thanos API and hand-build Grafana dashboard JSON. It worked, but it was duct tape: the LLM was reasoning about an API it could only see through curl calls, and I was the one copy-pasting JSON into the Grafana import dialog and eyeballing the result.

Six months later, Grafana shipped the thing that makes that whole workflow feel prehistoric: gcx, a CLI for Grafana that is explicitly designed for AI agents. Not “AI-compatible” in the marketing sense, but actually built so that an LLM is the expected caller. I’ve been using it with Claude Code for a few weeks now, and dashboard creation has gone from a craft project to a conversation.

What gcx Actually Is

gcx is a single CLI that gives you (and your coding agent) structured access to a Grafana instance: dashboards, folders, data sources, alert rules, SLOs, metrics, logs, traces. It works with Grafana Cloud and OSS/Enterprise v12+. Install is one line:

brew install grafana/grafana/gcx

The design choices are all agent-first. Every command emits JSON or YAML via --output with field names that stay stable across versions. Exit codes are documented and consistent. It even auto-detects when it’s being run by Claude Code or Cursor and strips out the human-friendly UI noise so the agent isn’t burning tokens on spinners and box-drawing characters. The agent calls gcx the way it already calls git or kubectl: run the command, read the output, move on.

Browsing Data Sources on the Fly

This is the part that killed my old workflow. In January, “understand what metrics are available” meant the LLM writing raw HTTP requests against the Thanos API and me pasting responses back. With gcx, the agent just asks:

gcx metrics query 'rate(http_requests_total[5m])' --since 1h
gcx logs query '{app="nginx"} |= "error"' --since 1h

There’s a bundled explore-datasources skill that teaches the agent to discover what data sources exist (Prometheus, Elasticsearch, Loki, whatever your instance has wired up) and then enumerate the metrics, labels, and log streams inside them. So instead of guessing at metric names (LLMs love to hallucinate a plausible-sounding node_cpu_usage_percent that doesn’t exist), the agent verifies every query against real data before it ever lands in a panel.

Watching Claude do this is genuinely fun. It lists the data sources, pokes at label values, runs a few test queries to see what the data actually looks like, and then decides that a rate should be a time series and a saturation metric should be a gauge. Same reasoning I praised in January, but now grounded in live data instead of my copy-paste relay.

The Killer Feature: It Looks at Its Own Work

Here’s the tidbit that made me want to write this post. Anyone who’s had an LLM generate dashboard JSON knows the failure mode: the JSON is valid, the queries are fine, and the dashboard looks like a ransom note. Panels overlapping, a legend eating half a graph, a y-axis in scientific notation.

gcx solves this with snapshots. The create-dashboard skill has the agent render the dashboard to an actual PNG:

gcx dashboards snapshot

Then, and this is the good part, the agent inspects the image. Claude looks at the rendered graph the way you would, notices that the layout is cramped or a query returned a flat line, and iterates on the panels before pushing anything. It’s a visual feedback loop: generate, render, look, fix, repeat. The dashboard that finally gets published has been seen by the thing that built it. In my experience this catches the embarrassing stuff, like empty panels from a bad label filter or units that render as raw seconds instead of milliseconds, on the second or third iteration, without me in the loop at all.

GitOps, Because Dashboards Are Code Now

The other quality-of-life win: dashboards round-trip to disk with full fidelity.

gcx resources pull dashboards -p ./resources -o yaml
gcx resources push -p ./resources

Pull your dashboards into a repo, let the agent edit them as YAML, review the diff like any other code change, push them back. There are kubectl-style named contexts, so promoting a dashboard from a dev stack to prod is a context switch, not a JSON export-import ritual. And the commands are all non-interactive, so this drops straight into CI.

Other Cool Tidbits

A few more things worth knowing:

  • 22 bundled skills. gcx agent skills install --all drops portable agent skills for alert investigation, root-cause analysis, SLO management, synthetic checks, and observability setup. They follow the .agents convention, so they work across harnesses, not just Claude Code.
  • A proper Claude Code plugin. /plugin marketplace add grafana/gcx and your agent knows the whole tool. It even ships a grafana-debugger agent that autonomously correlates Prometheus metrics and Loki logs for root-cause analysis.
  • Raw API escape hatch. gcx api is a passthrough for any endpoint the CLI doesn’t wrap yet.
  • Dashboards-as-real-code. gcx dev scaffolds a Go project using the grafana-foundation-sdk, if YAML isn’t code-y enough for you.

The Bottom Line

In January, the interesting question was whether an LLM could reason well enough about observability data to build a useful dashboard. The answer was yes, but the plumbing was all on me. gcx is that plumbing, shipped as a product: the agent discovers the data, writes the queries, renders the result, checks its own work visually, and commits the dashboard to git. What used to be an afternoon of copy-paste is now “build me a dashboard for the nginx ingress tier” and a coffee refill.

If you’re running Grafana and using a coding agent, this is the easiest observability win available right now. Start with the announcement post and the docs.

Naturally, my next question was whether Kibana has an answer to gcx. The short version: not a CLI, but Elastic is attacking the same problem from the other direction with Agent Builder and its built-in MCP server: host the tools server-side, let any agent connect over MCP, and it’ll even generate Kibana dashboards from a prompt with ES|QL grounded in your actual indices. Different philosophy, same destination. I hope to play with these options next, so expect a follow-up post comparing the two approaches.


And now for the part of the blog where I vent about sports, because some traditions must be maintained.

It’s mid-July, which means we’re days away from Giants training camp, and I’m allowing myself the most dangerous emotion in sports: optimism. New coaching staff, a full offseason to install the system. This is the part of the year where every fanbase is undefeated, and I intend to enjoy it before reality shows up in September.

In other news, Spain just beat France in the World Cup. I’m not a soccer fan, but I know an upset when I see one: everyone on the planet had pegged France to win it all, and Spain didn’t get the memo. There’s something deeply satisfying about a bracket full of experts being wrong together.