Skip to main content
Glama
stonoyan04

grafana-mcp-server

by stonoyan04

Grafana MCP Server

A Model Context Protocol (MCP) server that gives AI assistants read-only access to everything your Grafana can already see — Prometheus/Loki metrics, ClickHouse/Postgres/MySQL datasources, and the dashboards your team has already built. Ask questions in natural language and get answers backed by real data.

Works with Claude Code, Claude Desktop, and any MCP-compatible client. Your project can be in any language — this server runs independently.

How It Works

Your project (any language)     grafana-mcp-server            Grafana            Datasources
┌───────────────────┐          ┌──────────────────┐          ┌──────────┐       ┌────────────┐
│  Claude Code or   │  stdio   │  Builds the      │  HTTPS   │ /api/ds/ │──────>│ Prometheus │
│  Claude Desktop   │────MCP──>│  per-plugin      │────────->│  query   │──────>│ ClickHouse │
│                   │<─────────│  query model     │<─────────│          │──────>│ Postgres … │
└───────────────────┘          └──────────────────┘          └──────────┘       └────────────┘

The server talks only to Grafana's HTTP API. Grafana proxies the query to the datasource with its credentials, so the assistant never holds a database password, and whatever the Grafana user can see is exactly what the assistant can see — no more. All requests are read-only (use a Viewer credential to make that a guarantee).

Related MCP server: Grafana MCP Server

Requirements

  • Node.js >= 18 or Docker (only for running this MCP server)

  • A Grafana account you can sign in with — Google / SSO / password, whatever your Grafana uses. No admin rights, no service account, no API token required: grafana-mcp-server login signs you in in a browser and hands the session to the server (see Authentication). A service-account token works too if you have one.

  • Chrome or Edge installed (used only as the sign-in window; your daily browser can be anything). If neither is present, login falls back to a guided cookie copy in your default browser.

Quick Start

Option A: Node.js

1. Clone and build

git clone https://github.com/stonoyan04/grafana-mcp-server.git
cd grafana-mcp-server
npm install
npm run build

This creates the compiled server at dist/main.js.

2. Sign in

GRAFANA_URL=https://grafana.example.com npm run login

If Chrome or Edge is installed (as the default browser, or just present on the machine — that covers almost everyone, whatever their daily browser), login opens a dedicated window of it — its own throwaway profile, not your everyday one — on the Grafana login page. Sign in exactly as you always do. The moment Grafana issues a session, the command stores it, removes it from that profile, verifies it, and prints:

[grafana-mcp-server] ✓ signed in as jane <jane@example.com>

No pasting, no token, nothing secret in a config file. If Grafana is behind Cloudflare Access you sign in to that in the same window, and its cookie is captured too. Don't close the window until you see the ✓. The session is stored at ~/.grafana-mcp/sessions/<host>.json (mode 600).

Playwright can only drive Chrome and Edge (Arc, for one, can't be automated at all), so login uses one of those as the sign-in window regardless of your default browser — your default browser is never touched. Only if neither Chrome nor Edge is installed does login fall back to opening Grafana in your default browser and guiding a one-time grafana_session copy from DevTools.

Why a dedicated window and not my open tab? A browser never hands its cookies to a command-line tool — that isolation is the point of a browser — so login drives an instance it controls, in a separate profile, and takes the session out of it.

Force a specific browser: npm run login -- --browser chrome (or msedge, chromium after npx playwright install chromium, or a path to a Chromium binary). npm run login -- --paste reads a cookie from stdin with no browser opened.

3. Configure

Claude Code — one command, or the equivalent .mcp.json block:

claude mcp add grafana --scope user --env GRAFANA_URL=https://grafana.example.com -- node /home/john/grafana-mcp-server/dist/main.js
{
  "mcpServers": {
    "grafana": {
      "command": "node",
      "args": ["/home/john/grafana-mcp-server/dist/main.js"],
      "env": {
        "GRAFANA_URL": "https://grafana.example.com"
      }
    }
  }
}

Claude Desktop — same block in the config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Note: Replace /home/john/grafana-mcp-server with the actual path where you cloned this repo. The only required setting is GRAFANA_URL — the credential comes from the session login stored. Restart the client after adding the server.

Have a service-account token instead? Add "GRAFANA_TOKEN": "glsa_…" to env and skip login. Or point GRAFANA_CREDENTIAL_FILE at a 0600 file holding it, or inject it from a secret manager at launch (e.g. charter secret exec … --exec -- node dist/main.js).

Option B: Docker

git clone https://github.com/stonoyan04/grafana-mcp-server.git
cd grafana-mcp-server
docker build -t grafana-mcp-server .
{
  "mcpServers": {
    "grafana": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/home/john/.grafana-mcp:/root/.grafana-mcp",
        "-e", "GRAFANA_URL=https://grafana.example.com",
        "grafana-mcp-server"
      ]
    }
  }
}

Run login on the host (GRAFANA_URL=… npm run login from a Node checkout, since the container has no browser) and mount ~/.grafana-mcp read-write as shown — the container needs to write rotated sessions back. Or skip the mount and pass -e GRAFANA_TOKEN=glsa_… if you have a service-account token.

Why -i and no -t? MCP speaks JSON over stdin/stdout. -i keeps stdin open; a TTY (-t) would corrupt the stream.

If Grafana is behind Cloudflare Access, mount your host's token cache read-only — -v /home/john/.cloudflared:/root/.cloudflared:ro — and run cloudflared access login https://grafana.example.com on the host first. The container cannot run cloudflared itself, so it reads the mounted cache (or a CF_ACCESS_TOKEN); when the token expires, re-run the login on the host.

4. Discover your datasources

List the Grafana datasources

Every query tool needs a datasource uid, and the datasource type decides which tool to use — query_sql for ClickHouse/Postgres/MySQL, query_metrics for Prometheus/Loki. list_datasources tells you both.

5. Start asking questions

How many messages per Kafka topic were produced in the last 7 days?   → query_metrics on Prometheus
Which dashboards mention "kafka"?                                     → search_dashboards
Show me the panel queries in that dashboard                           → get_dashboard
Run: SELECT count() FROM events WHERE created > now() - INTERVAL 1 DAY → query_sql on ClickHouse

Tip: get_dashboard returns the raw SQL / PromQL behind each panel. Reusing a query a human already wrote and trusts beats writing one from scratch.

Tools

The server exposes 6 read-only tools:

list_datasources

List datasources with uid, name, type, and which query tool applies. No parameters.

query_sql

Run raw SQL against a SQL-family datasource through Grafana and get rows back.

Parameter

Type

Default

Description

datasourceUid

string

Datasource uid or exact name

sql

string

The SQL to run

from

string

now-6h

Range start (for $__timeFilter-style macros)

to

string

now

Range end

The query object sent to /api/ds/query is built per plugin — grafana-clickhouse-datasource, vertamedia-clickhouse-datasource, and the built-in Postgres/MySQL/MSSQL all want different shapes.

query_metrics

Run a PromQL or LogQL expression. Omit from for an instant query.

Parameter

Type

Default

Description

datasourceUid

string

Datasource uid or exact name

expr

string

PromQL / LogQL expression

from

string

Range start, e.g. now-24h. Omit for an instant query.

to

string

now

Range end / evaluation time

stepSeconds

number

300

Range-query step

maxDataPoints

number

1000

Points per series cap

search_dashboards

Parameter

Type

Default

Description

query

string

Title substring

tag

string

Dashboard tag

limit

number

20

Max results

get_dashboard

Parameter

Type

Description

uid

string

Dashboard uid from search_dashboards

Returns the panels (rows flattened) with each panel's datasource and raw queries, plus the dashboard's template variables and default time range.

health

Checks connectivity and tells the two auth layers apart: failingLayer: "cloudflare" means run cloudflared access login (or login again); failingLayer: "grafana" means the stored session/credential is dead or under-privileged — run grafana-mcp-server login. Reports who the credential authenticates as and how many datasources it can see. No parameters. Call it first whenever another tool fails.

Data frames are flattened into plain rows keyed by field name (Prometheus series are disambiguated by their labels), capped at GRAFANA_MAX_ROWS.

Commands

Command

What it does

grafana-mcp-server (no args)

Run the MCP server on stdio — this is what the MCP client launches

grafana-mcp-server login

Open your default browser (dedicated profile), sign in to Grafana as usual, store the session for the server

grafana-mcp-server login --browser X

Force chrome, msedge, arc, brave, vivaldi, chromium, or a path to a Chromium-based binary

grafana-mcp-server login --paste

Store a grafana_session value read from stdin instead of opening a browser

grafana-mcp-server logout

Delete the stored session

npm run login / npm run logout are shortcuts for the same thing from a checkout.

Configuration

All configuration is via environment variables. With login, only GRAFANA_URL is needed.

Variable

Required

Default

Description

GRAFANA_URL

Yes

Grafana base URL

GRAFANA_TOKEN

No

Service-account token (glsa_…) or legacy API key → Bearer. Overrides the stored session.

GRAFANA_USERNAME / GRAFANA_PASSWORD

No

Basic auth

GRAFANA_SESSION

No

A grafana_session cookie value (rotations can't be persisted from env — prefer login)

GRAFANA_CREDENTIAL_FILE

No

File holding any one of the above; shape inferred, re-read per request, rotated sessions written back

GRAFANA_SESSION_DIR

No

~/.grafana-mcp

Where login keeps sessions (sessions/<host>.json) and its browser profile

GRAFANA_LOGIN_TIMEOUT

No

300000

How long login waits for you to finish signing in (ms)

GRAFANA_CF_ACCESS

No

auto

off to skip Cloudflare Access entirely

CF_ACCESS_TOKEN

No

auto

Cloudflare Access JWT fallback

ALLOWED_DATASOURCES

No

(all)

Comma-separated allowlist of datasource uids or names

GRAFANA_MAX_ROWS

No

500

Rows returned per frame

GRAFANA_REQUEST_TIMEOUT

No

60000

Request timeout in milliseconds

Credential precedence: GRAFANA_TOKENGRAFANA_USERNAME+PASSWORDGRAFANA_SESSIONGRAFANA_CREDENTIAL_FILE → the session stored by login~/.grafana-mcp-token if it exists.

Datasource allowlist

"ALLOWED_DATASOURCES": "OsirT4Bnz,Prometheus"

list_datasources hides everything else and the query tools refuse it.

Authentication

Grafana: sign in with your own account (login)

grafana-mcp-server login gets you signed in and hands the session to the server. It drives Chrome or Edge — whichever is installed, used only as the sign-in window regardless of your default browser — through Playwright in a dedicated profile under ~/.grafana-mcp/browser, opens GRAFANA_URL/login, and waits while you sign in — Google, GitHub, SAML, LDAP, or a plain password; the tool never sees or types your credentials. When Grafana sets its grafana_session cookie the tool:

  1. copies the session (and the CF_Authorization cookie, if Cloudflare Access is in front) into ~/.grafana-mcp/sessions/<host>.json (0600),

  2. deletes Grafana's cookies from that browser profile, so the server is the session's only holder,

  3. calls /api/user through the server's own code path and prints who you are.

Playwright can drive only Chrome and Edge, and Arc can't be automated at all — so the sign-in window is always Chrome/Edge, never your default browser (which is left untouched). Only if neither Chrome nor Edge is installed does login fall back to opening Grafana in your default browser and walking you through copying the grafana_session cookie from DevTools once; that path also asks you to sign out of the tab afterwards so it stops competing for session rotations.

From then on the server keeps the session alive itself: Grafana answers a stale session with 401 session.token.rotate, the server calls POST /api/user/auth-tokens/rotate, persists the new cookie atomically, and retries. The session therefore lasts for Grafana's login lifetime (30 days by default, 7 days idle) — re-run login when health says failingLayer: "grafana".

Why this is the recommended path: it needs no Grafana admin. Everyone who can open Grafana in a browser can use the server, with exactly their own permissions, and revoking access is the same as for any user.

Grafana ≥ 10 rotates a session token every few minutes, and only one client gets the new one. If you copy grafana_session from DevTools while the tab stays open, the browser rotates it first and the copy is dead within minutes — that is the classic "the cookie stopped working" experience. login avoids it by taking the session out of the browser; login --paste works too as long as you then sign out (or clear the cookie) in the tab you copied from, because the server persists its own rotations.

Grafana: other credentials

Credential

Notes

Service-account token (glsa_…)

Never rotates. Needs a Grafana admin to create it (Administration → Service accounts, role Viewer) — scripts/mint-token.sh <admin-session> automates that. Set GRAFANA_TOKEN or drop it in GRAFANA_CREDENTIAL_FILE.

Basic auth

Only if the login form is enabled — instances on Google/GitHub OAuth usually have no password to give.

GRAFANA_SESSION env

A session value straight from env. Works, but rotations cannot be written back, so it dies with the first rotation after a restart. Prefer login.

scripts/verify.sh checks both layers and reports what the credential can see — without ever printing it.

Cloudflare Access (optional)

If Grafana sits behind Cloudflare Zero Trust, every request also needs a cf-access-token header or the edge redirects to its login page before Grafana sees the call. The server handles that automatically:

  1. Read the cached JWT from ~/.cloudflared/<hostname>-<audience>-token (written by cloudflared access login)

  2. If missing or expired, run cloudflared access token --app=<GRAFANA_URL> (non-interactive)

  3. Use the CF_Authorization cookie captured by login (if not expired)

  4. Fall back to CF_ACCESS_TOKEN

  5. On a 302 from the edge, drop the cached token and retry once with a fresh one

The token is resolved lazily, per request — never once at startup — so an expiring token heals itself instead of failing every call until the client restarts. Installing cloudflared is optional but recommended: its token refreshes itself for as long as your Cloudflare login lasts, whereas the cookie captured by login expires with Cloudflare's session policy (typically 24h) and then needs login again.

brew install cloudflared            # macOS; see Cloudflare's docs for Linux
cloudflared access login https://grafana.example.com

Cloudflare does not log you into Grafana. The CF JWT proves you may reach the host; Grafana then wants its own credential. A 302 / HTML response is Cloudflare; a JSON 401 is Grafana. health reports which.

Not behind Cloudflare? Set GRAFANA_CF_ACCESS=off, or just don't install cloudflared — the server skips the layer when no token can be found.

Project Structure

src/
  main.ts                        # Entry point — `login` / `logout` commands, or the stdio MCP server
  login.ts                       # Browser sign-in (Playwright over your default Chromium-based browser) → session store
  default-browser.ts             # Detect the default browser (macOS LaunchServices / xdg) and whether it can be driven
  session-store.ts               # ~/.grafana-mcp/sessions/<host>.json, 0600, atomic writes
  grafana-client.ts              # Grafana HTTP client: two auth layers, CF retry, session rotation, datasource cache
  auth.ts                        # Grafana credential resolution (token / basic / session / file / login store)
  cf-token.ts                    # Cloudflare Access token: cache → cloudflared → login cookie → env, lazy + retry
  query-model.ts                 # Per-plugin /api/ds/query bodies (ClickHouse, SQL, PromQL/LogQL)
  allowed-datasources.ts         # Datasource allowlist
  utils/
    frames.ts                    # Data frames → rows
    format-response.ts           # Truncation, error results
  tools/
    list-datasources.tool.ts     # list_datasources
    query-sql.tool.ts            # query_sql
    query-metrics.tool.ts        # query_metrics
    search-dashboards.tool.ts    # search_dashboards
    get-dashboard.tool.ts        # get_dashboard
    health.tool.ts               # health
scripts/
  verify.sh                      # Check both auth layers; list what the credential can see
  mint-token.sh                  # Turn a fresh admin browser session into a service-account token

License

MIT

Available Tools

6 tools
get_dashboardA

Fetch a dashboard by uid and return its panels with their datasource and raw queries (SQL / PromQL / LogQL) — the fastest way to reuse a query someone already wrote, plus its template variables.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYesDashboard uid from search_dashboards

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the read-only nature implicitly with 'Fetch' and specifies exactly what is returned, including panels, datasource, raw query languages, and template variables, which is sufficient for a simple read operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the core action ('Fetch a dashboard by uid') and then adds valuable details about the return payload and use case. It is efficient with no fluff, though slightly long with the parenthetical and appositive.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and no output schema, the description covers the key aspects: input, output, and purpose. It says what the dashboard fetch returns, and the schema covers the parameter source, making it complete enough for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with 'uid' already described as 'Dashboard uid from search_dashboards'. The description mentions 'by uid' but adds no new meaning beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'Fetch a dashboard by uid' and the resource, then details the output: panels, datasource, raw queries, and template variables. It distinguishes itself from siblings like query_sql and search_dashboards by emphasizing query reuse rather than execution or searching.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'the fastest way to reuse a query someone already wrote' provides clear context for when to use this tool. It implicitly excludes query execution tools, though it does not explicitly name alternatives or state when not to use it, giving clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

healthA

Check Grafana connectivity and authentication: which auth layer (Cloudflare Access vs Grafana credential) is failing if any, who the credential authenticates as, and how many datasources it can see. Call this first whenever another tool fails. failingLayer=grafana means the developer must run grafana-mcp-server login again.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It reveals what the tool inspects (auth layers, credential identity, datasource visibility), the meaning of the failingLayer value, and the remediation step. It does not explicitly state whether the check is read-only, but a health check's non-mutating nature is strongly implied and no contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, all substantive. The main purpose is front-loaded, the diagnostic details are compactly listed, and the remediation instruction is concrete. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter diagnostic tool with no output schema and no annotations, the description is complete: it states what is checked, how results are interpreted, and what action to take on a specific failure mode. It gives the agent enough to decide when to call it and what to do with its output.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the input schema is empty, so there is nothing for the description to clarify about parameters. Per the zero-parameter baseline, a score of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Check Grafana connectivity and authentication.' It enumerates exact diagnostic outputs (failing auth layer, credential identity, visible datasource count), which distinguishes this health-check tool from sibling data-access tools like query_sql and list_datasources.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit trigger: 'Call this first whenever another tool fails.' It also specifies a follow-up action when failingLayer=grafana. It does not spell out when not to use it, but the context makes the tool's diagnostic role clear relative to the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_datasourcesA

List Grafana datasources (uid, name, type). Start here: every query tool needs a datasource uid, and the type decides whether to call query_sql or query_metrics.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It correctly implies a read-only listing operation, but does not explicitly mention pagination, rate limits, or any side effects. For a simple list operation, this is adequate but not thorough; it lacks explicit confirmation of safety or response limitations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences. The first states the core function and return fields; the second immediately provides actionable guidance on next steps. There is no redundancy or filler, and the critical scoping information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters, no output schema, and low complexity, the description fully covers what the agent needs: what it returns, and how to proceed. It is complete and self-sufficient for correct invocation and routing to sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema is inherently complete. The description adds no parameter details because none exist. Per the rubric, a baseline of 4 is appropriate for zero parameters, and the description does not need to explain anything about parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: listing Grafana datasources with specific fields (uid, name, type). It also differentiates from sibling query tools by framing itself as the prerequisite step, so an agent can immediately understand what it does and how it differs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance: it tells the agent to start here whenever querying is needed, explains that a datasource uid is required, and directs the agent to choose between query_sql and query_metrics based on the type. This clearly distinguishes when to use this tool versus the query siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_metricsA

Run a PromQL (Prometheus/Thanos/Mimir) or LogQL (Loki) expression against a datasource through Grafana. Omit from for an instant query; pass from/to for a range query.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoRange end / instant evaluation time, e.g. "now"now
exprYesPromQL or LogQL expression, e.g. sum by (topic) (increase(kafka_topic_partition_current_offset[7d]))
fromNoRange start, e.g. "now-24h". Omit for an instant query evaluated at `to`.
stepSecondsNoRange-query step in seconds (default 300)
datasourceUidYesDatasource uid (or exact name) from list_datasources
maxDataPointsNoCap on points per series (default 1000)

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavioral traits such as read-only status or side effects. It only mentions the instant vs. range query modes, but does not state whether the operation is non-destructive, what it returns, or any datasource implications. This leaves the agent to assume safety on a tool that executes arbitrary expressions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the purpose and then gives a succinct behavioral directive. Every word earns its place, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential query modes and ties to datasources, but omits any mention of return value structure or error handling, which is significant given there is no output schema. The schema documents parameters thoroughly, so the core usage is clear, but the lack of result details leaves a minor gap for such a complex query tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully documents all six parameters with descriptions, so the baseline is 3. The description adds only a rephrased note about omitting `from` for instant queries, which is already present in the schema's `from` field. It adds no new meaning for parameters like `stepSeconds` or `maxDataPoints`.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise action: running a PromQL or LogQL expression against a Grafana datasource. It clearly distinguishes this tool from the SQL-oriented sibling (query_sql) by explicitly naming the expression languages, leaving no ambiguity about which tool to use for metric or log queries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs when to omit or include the `from` parameter to switch between instant and range queries, providing clear context for invocation. Though it doesn't explicitly name query_sql as the SQL alternative, the expression-language distinction effectively routes the agent to the correct tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_sqlA

Run raw SQL against a SQL-family datasource (ClickHouse, Postgres, MySQL, MSSQL) through Grafana and get rows back. Use list_datasources first to get the uid. Read-only by convention — use a Viewer credential.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoRange end, e.g. "now"now
sqlYesThe SQL to run. Use the database column names, e.g. snake_case, not the app-level ones.
fromNoRange start for $__timeFilter-style macros, e.g. "now-30d" or epoch msnow-6h
datasourceUidYesDatasource uid (or exact name) from list_datasources

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It mentions read-only by convention and returning rows, which is helpful, but omits other traits like error handling, rate limits, or potential side effects beyond the stated convention. It adds some value but is not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exactly two sentences with no redundant words. The core purpose is front-loaded, and the usage note follows immediately, making it easy to scan and internalize.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a raw SQL tool with a straightforward purpose, the description covers purpose, prerequisites, and read-only behavior. It does not detail time-range semantics (covered in schema) or return size limits, but given the tool's nature and lack of output schema, it is sufficiently complete for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters. The description does not add new parameter-level detail; it only reinforces the datasourceUid dependency on list_datasources, which is already in the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs raw SQL against SQL-family datasources and returns rows, using specific verbs (run) and resources (SQL datasource). It distinctively positions itself from siblings like query_metrics by emphasizing 'raw SQL' and explicit datasource family names.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear prerequisite ('Use list_datasources first to get the uid') and notes a read-only convention. However, it does not explicitly compare with alternatives such as query_metrics or state when not to use this tool, leaving selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_dashboardsA

Search dashboards by title or tag. Use it to find what is already instrumented before writing a query from scratch, then get_dashboard to read the panel queries.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNoFilter by dashboard tag
limitNoMax results (default 20)
queryNoTitle substring, e.g. "kafka"

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavior. It states the search functionality and implies read-only use ('find what is already instrumented'), but does not mention potential limitations, pagination, or return format. It adds only minimal behavioral detail beyond the tool name and schema, leaving the agent to infer common search semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences. The first sentence gives the core action and criteria, front-loading the most important information. The second sentence adds usage guidance with no fluff. Every word earns its place, achieving conciseness without losing substance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search tool with all optional parameters and no output schema, the description is mostly complete. It explains the tool's purpose and provides a usage workflow, including the next step. It does not explicitly mention the return type (e.g., a list of dashboard references), but the follow-up 'then get_dashboard' implies that the results are dashboard identifiers, making the missing detail a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% (all three parameters have descriptions), so the baseline is 3. The description adds usage context (e.g., 'find what is already instrumented') but does not add new semantic meaning beyond the schema's 'Title substring' and 'Filter by dashboard tag'. It reinforces but doesn't extend the parameter docs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Search'), resource ('dashboards'), and criteria ('by title or tag'), making the tool's purpose immediately clear. It also differentiates from get_dashboard by implying that search_dashboards finds dashboards while get_dashboard reads their content, and from query tools by focusing on discovery rather than data retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly specifies when to use the tool ('before writing a query from scratch') and provides a follow-up action ('then get_dashboard to read the panel queries'). This gives the agent a clear workflow and implies when not to use it (e.g., when querying data directly, use query_sql/query_metrics).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv1.0.0
    • First observedget_dashboard
    • First observedhealth
    • First observedlist_datasources
    • First observedquery_metrics
    • First observedquery_sql
    • First observedsearch_dashboards

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a clearly distinct action: listing datasources, querying SQL, querying metrics/logs, searching dashboards, fetching dashboards, and checking health. The only similar pair, query_sql and query_metrics, is explicitly disambiguated by datasource type in list_datasources.

Naming Consistency4/5

All names use lowercase snake_case and mostly follow a verb_noun pattern: list_datasources, query_sql, query_metrics, search_dashboards, get_dashboard. The single outlier is health, which is a noun rather than a verb_noun name, but it is short and idiomatic enough not to cause confusion.

Tool Count5/5

Six tools is a well-scoped size for a Grafana MCP server focused on querying data and reusing existing dashboards. Each tool has a distinct role, and there is no sense of bloat or an overly thin surface.

Completeness5/5

The set covers the full discovery-to-query workflow: identify datasources, run the appropriate query type, search for existing dashboards, extract panel queries, and diagnose auth/connectivity failures. For a read-oriented Grafana data exploration server, there are no obvious dead ends or missing critical operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    C
    quality
    D
    maintenance
    Enables AI-powered integration with Grafana instances through 52 MCP tools for dashboard management, Prometheus/Loki queries, alerting, and administrative functions. Supports complete Grafana functionality including metrics exploration, log analysis, and incident response through natural language.
    80
    1
    -
  • A
    license
    B
    quality
    B
    maintenance
    Enables AI assistants to interact with Grafana dashboards, datasources, alerts, incidents, and monitoring data through 43 comprehensive tools. Supports querying Prometheus metrics, Loki logs, managing incidents, and dashboard operations with full authentication support.
    43
    391 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to query Prometheus metrics, monitor alerts, and analyze system health through read-only access to your Prometheus server with built-in query safety and optional AI-powered metric analysis.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Query Grafana logs, metrics, and dashboards from Cursor. Enables the AI to call your Grafana instance via tools without leaving the editor.
    6 npm
    4
    Apache 2.0