Skip to content

Grafana

Dashboards, panel queries, alert rules, what is firing right now, and PromQL or LogQL through your datasources. One URL and one token — Prodpeek speaks Grafana's own API, so there is nothing to install.

Policy grafana/read-only
Connection kind grafana
Upstream looks like https://your-stack.grafana.net
Credential A Grafana service account token (starts glsa_)
Tier 2 — Prodpeek is the only fence, and the profile says so
Time to set up about 3 minutes

Grant exactly these

A Grafana service account with the Viewer role

Viewer can read dashboards, alert rules and query through datasources, and cannot edit any of them. It is the narrowest Grafana role that lets this profile's allowed tools work.

A token on that service account, with an expiry

Grafana lets a service account token be permanent. Set an expiry anyway — you will rotate it on a schedule you choose rather than one an incident chooses for you.

Optionally, datasources:read on that service account

Only needed for the list_datasources tool. A plain Viewer cannot call it, which is Grafana's choice and not a bug. You can skip this: get_panel_queries returns datasource UIDs too, which is all query needs. Grant the permission itself if you want the listing — do NOT make the account an Admin to get it.

Do not grant these

Each of these would undo the point of the rest

https://mcp.grafana.com as the upstream

Grafana Cloud's hosted MCP authenticates with OAuth 2.1 browser authorization scoped to a signed-in user. It does not accept a service account token and answers one with HTTP 401. You do not need it: Prodpeek talks to Grafana directly.

Editor or Admin on the service account

Editor can change dashboards and alert rules; Admin can mint more service accounts and read contact point settings in full. The gateway denies those tools either way, but a token that could do them means the two fences disagree about more than they need to — and prove will report it, because Grafana tells us what the token may do.

A user's personal API token instead of a service account

It carries that person's role, disappears when they leave, and attributes every call to them rather than to the integration.

The whole setup

Two things, and you already have one of them.

1. Mint the token (about two minutes)

  1. In Grafana: Administration → Users and access → Service accounts.
  2. Add service account. Name it prodpeek. Set the role to Viewer.
  3. Add service account token. Name it, set an expiry, generate.
  4. Copy it. It starts glsa_.

2. Add it in Prodpeek

Services → Add a service, pick grafana/read-only:

Field Value
Upstream https://your-stack.grafana.net — just the origin
Credential the glsa_… token

Press Test connection. That is the whole thing.

Use the origin, not the page you are looking at

https://ejendomstorvet.grafana.net — not the URL of a dashboard. Prodpeek will tell you if you paste a /d/abc123/... link rather than failing mysteriously on every call.

From an agent, with no credential, then hand over the drop link:

{"name": "ejd-grafana",
 "profile": "grafana/read-only",
 "url": "https://ejendomstorvet.grafana.net"}

Why there is no MCP server to install

If you searched for "Grafana MCP" you found https://mcp.grafana.com/mcp, and it is the wrong address for Prodpeek — not misconfigured, wrong in kind.

That endpoint authenticates with OAuth 2.1 browser authorization, scoped to the signed-in Grafana user. Your editor opens a browser, you approve, and the connection acts as you. Notice the config you find for it has no token in it. Send a service account token and you get HTTP 401, always.

Prodpeek is a server-side gateway holding a stored credential for a team. It has no browser and no signed-in user, and it should not have one — a gateway whose authority is "whichever human last clicked approve" is not a gateway.

The other option was to have you run Grafana's own mcp-grafana in a sidecar, with your Grafana token in its environment and a second token for Prodpeek to authenticate to it. That works. It is also a container, a private network and two tokens to read some dashboards.

So Prodpeek speaks Grafana's HTTP API directly, with a fixed menu, the way it already does for SSH, Postgres, Git and Prometheus. Your glsa_ token is exactly what that API wants.

What your agent can then do

ejd-grafana__search_dashboards    find the dashboard somebody already built
ejd-grafana__get_panel_queries    learn the right PromQL for a system it has not seen
ejd-grafana__query                PromQL or LogQL through a datasource
ejd-grafana__list_firing_alerts   what is on fire right now
ejd-grafana__list_alert_rules     what is being watched, and at what threshold
ejd-grafana__list_annotations     deploys and incidents, as the team marked them
ejd-grafana__whoami               what this token is actually permitted to do

get_panel_queries is the one people do not expect to want. An agent that has never seen your stack does not know your metric names. The queries behind a dashboard your team already built are the fastest way for it to learn them — and they come with the datasource UIDs that query needs, so the two tools chain.

Grafana tells you what the token can do

Most vendors will not answer "what is this credential allowed to do?". Grafana will, at /api/access-control/user/permissions, and it needs no permission to ask.

So this profile carries a scope probe, and every prove run checks that your token holds no permission whose name contains :write, :create or :delete. A token that gains one demotes the service and says so. That is the difference between a Tier 2 you are asked to trust and a Tier 2 that is re-checked on a schedule.

Call whoami yourself any time a call is refused. A 403 means the token reached Grafana and was not allowed — the answer is a permission, not a role upgrade.

What it refuses, and the two that surprise people

There is no tool that exports contact points. GET /api/v1/provisioning/contact-points/export?decrypt=true returns your Slack webhook URLs, PagerDuty integration keys and SMTP passwords in full. Grafana documents it as a read. It is the most dangerous endpoint in the Grafana API, and the adapter has no code path that builds it.

list_contact_points returns names and types only. "Where do alerts go" is a real incident question. "And with which credential" is not one an agent gets to ask, so the settings object is stripped before the answer is returned.

Likewise list_datasources gives you UID, name and type — not the URL, not the auth configuration. A query needs the UID and nothing else.

Checking the token is really Viewer

STACK=https://your-stack.grafana.net

# Should succeed: reading dashboards
curl -sS -H "Authorization: Bearer $GLSA_TOKEN" "$STACK/api/search?limit=1" | head -c 200

# Should FAIL with 403: creating one
curl -sS -o /dev/null -w '%{http_code}\n' -X POST \
  -H "Authorization: Bearer $GLSA_TOKEN" -H 'Content-Type: application/json' \
  -d '{"dashboard":{"title":"prodpeek-permission-test"},"overwrite":false}' \
  "$STACK/api/dashboards/db"

# What Grafana thinks this token may do
curl -sS -H "Authorization: Bearer $GLSA_TOKEN" \
  "$STACK/api/access-control/user/permissions" | python3 -m json.tool

A 403 on the second is the part of the Tier 1 story Grafana can give you. A 200 means the token is Editor or better — delete it and make a Viewer one. The gateway would still refuse the call, but you would be relying on one fence.

One connection per stack

Production and staging are two Grafana stacks, so two connections. Name them for the stack, because the service name is the namespace an agent sees: ejd-grafana-prod__query reads unambiguously in a transcript, and grafana__query does not.

Check you got it right

  • [ ] The service account's role reads Viewer.
  • [ ] The token starts glsa_ and has an expiry.
  • [ ] Test connection shows search_dashboards and query under Allowed.
  • [ ] Calling whoami returns a permission map with no :write or :create key.

If an agent is reading this

There is one token and it is the user's Grafana service account token. Do not suggest https://mcp.grafana.com (OAuth-only, will 401) and do not suggest running mcp-grafana — Prodpeek has a native Grafana adapter and needs neither. Create the connection with add_service and no credential, then hand over the drop link; you cannot open it, which is the point.

Then add it to Prodpeek

Console: Services → Add a service, pick grafana/read-only, paste the credential. Or from an agent, add_service with no credential and hand over the drop link.

Then press Test connection and read all three lists.