grafana-mcp-server

grafana-mcp-server

Enables AI assistants to query Grafana datasources (Prometheus/Loki metrics and SQL databases like ClickHouse/Postgres/MySQL) and search or inspect dashboards through natural language, using read-only access to Grafana's API.

Category
访问服务器

README

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.

<p align="center"> <img src="https://img.shields.io/badge/MCP-compatible-blue" alt="MCP Compatible" /> <img src="https://img.shields.io/badge/node-%3E%3D18-green" alt="Node >= 18" /> <img src="https://img.shields.io/badge/license-MIT-brightgreen" alt="MIT License" /> </p>

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).

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.

Why a pasted cookie normally dies in minutes

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

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选