# dsh-grafana-query [English](README.md) | [繁體中文](README.zh-TW.md) | 简体中文 | [日本語](README.ja.md) `dsh-grafana-query` 是一个免费开源、**只读**的 DeepSeek Harness Grafana 插件。 它让 agent 通过 Grafana 的 datasource proxy 执行 PromQL,并读取 Grafana unified alerting 的当前状态,全程不改动 Grafana 的任何数据。 请勿与 npm 上的 `dsh-grafana` 混淆——那是一个**写入型的 dashboard 编辑器**,会把 dashboard JSON 推回 Grafana。本插件做的是相反的事:只读的指标查询与告警状态。dashboard 与 panel JSON 明确不在范围内。 ## Tools | 工具 | 用途 | | --- | --- | | `grafana_health` | 确认实例可连接并返回版本。 | | `grafana_list_datasources` | 列出 datasource 的 uid、type 与 access 模式。请先调用这个。 | | `grafana_query` | 通过 datasource proxy 执行 instant PromQL 查询。 | | `grafana_query_range` | 执行区间 PromQL 查询,强制套用 step 与点数上限。 | | `grafana_alert_state` | 读取 unified alerting 规则的当前状态。 | | `grafana_list_alert_rules` | 列出已配置的告警规则定义。 | 所有工具均为只读。v0.1 不会在 Grafana 创建、修改、删除、silence、ack 或暂停任何东西。 ## 硬性上限 以下上限均由插件本身强制,与 Grafana 无关。任何一处被截断时,`meta.truncated` 与截断前的总数都会标示出来。 | 项目 | 值 | | --- | --- | | 每条 series 的点数(`max_points`) | 默认 200、上限 500。Prometheus 两端都会返回,因此 `n` 秒的区间搭配 step `s` 会得到 `floor(n / s) + 1` 个点 | | 区间长度(`grafana_query_range`) | 31 天 | | 单次区间查询的总点数 | 20000;超出的 series 会被整条丢弃,不会砍成半截 | | 单次查询的 series 数 | `maxSeries`,默认 100 | | 告警规则条数(`grafana_alert_state`、`grafana_list_alert_rules`) | 匹配条件的前 500 条;其余无法通过翻页获取,请用筛选参数 | | 每条规则的告警 instance | 默认 10、上限 50 | | 每页条数 | 默认 20、上限 100 | | 上游错误文本 | 200 字符,且仅 HTTP 400 才透出 | `grafana_alert_state` 默认只返回 `firing`、`pending` 与 `unknown` 的规则——**`inactive` 规则默认不会出现**, 需要时请用 `state` 明确指定。 ## Requirements - 具备兼容 `@deepseek-ai/dsh-tools` API 的 DeepSeek Harness - Node.js 22.19 以上(22.x 系列)或 Node.js 24 以上 - **Grafana 9.0 以上**——只支持 uid 版 datasource proxy(`/api/datasources/proxy/uid/:uid/*`), 不支持已 deprecated 的数字 id 路径 ## Configuration ```sh export GRAFANA_URL='https://grafana.example.com' export GRAFANA_TOKEN='glsa_your_service_account_token' ``` | 字段 | 环境变量 | 默认 | 范围 | | --- | --- | --- | --- | | `baseUrl` | `GRAFANA_URL` | 必填 | http(s) URL,不可内嵌账号密码、不可带 query 或 fragment;可含 sub-path | | `token` | `GRAFANA_TOKEN` | 必填 | 不可为空 | | `locale` | — | `en` | `en`、`zh-TW`、`zh-CN`、`ja` | | `requestTimeoutMs` | — | `30000` | 1 – 300000 | | `maxResponseBytes` | — | `5242880` | 1 – 52428800 | | `maxSeries` | — | `100` | 1 – 1000 | plugin 配置的优先级高于环境变量。 ## Permissions Grafana service account token(推荐)与旧版 API key 都可以用——两者都走同一个 `Authorization: Bearer` header。Grafana Cloud 的 Access Policy token(`glc_`)是给 Cloud 数据端点用的,**不适用**于这个 API。 ### 实际在 Grafana 上怎么设 下表的 scope 名称是 Grafana 内部检查用的,**UI 上并不是这样勾**。创建 service account 时可行的组合是: 1. basic role 选 **Viewer**——涵盖 `datasources:read` 与 `datasources:query`。 2. 再加 fixed role **Alerting → Full read-only access**——涵盖 `alert.rules:read` 与 `alert.provisioning:read`。 已于 2026-08-27 在 Grafana Cloud 用这个组合实测,六个工具全部可用。 详见[验证记录](docs/superpowers/specs/2026-08-26-dsh-grafana-verification.md)。 **用最小权限的 token 不会让工具变难用**:Grafana 对 `GET /api/datasources` 是**返回过滤后的列表**, 而不是返回 403。因此只被授予单一 datasource **Query** 权限的 token,`grafana_list_datasources` 就只会列出那一个——2026-08-27 实测:Viewer token 拿到 26 条,受限 token 拿到 1 条。你不会看到一堆 查下去就 403 的条目。(datasource 层级的 Query 权限也隐含允许读该 datasource 的 metadata, 因此不存在“查得动但读不到”的状态。) ### Scope 对照 | 工具 | 所需权限 | | --- | --- | | `grafana_health` | 无——`/api/health` 不需要认证,因此本工具无法判断 token 是否有效;要验证 token 请用 `grafana_list_datasources`。 | | `grafana_list_datasources` | `datasources:read` | | `grafana_query`、`grafana_query_range` | `datasources:query`(另有 `datasources:read` 才能做前置类型检查) | | `grafana_alert_state` | `alert.rules:read` | | `grafana_list_alert_rules` | `alert.provisioning:read` | ## Grafana Cloud `baseUrl` 指向 stack 本身,并使用在该 stack 创建的 service account token: ```sh export GRAFANA_URL='https://your-stack.grafana.net' export GRAFANA_TOKEN='glsa_your_service_account_token' ``` 这里不要用 `glc_` 开头的 Access Policy token。Cloud stack 内置大量 datasource, 请善用 `grafana_list_datasources` 的 `type` 与 `name_contains` 筛选以缩短列表。 ## Install ```sh bun add dsh-grafana-query ``` 包内含 `cordis.patch.yml`,并通过 `package.json` 的 `dsh.bundle.patch` 声明, 让 DeepSeek Harness registry 能以默认配置加载本插件。 ## Examples 1. `grafana_list_datasources` 带 `{"type": "prometheus"}` 获取 uid。 2. `grafana_query` 带 `{"datasource_uid": "prom-1", "query": "up"}` 查当前值。 3. `grafana_query_range` 带 `{"datasource_uid": "prom-1", "query": "rate(node_cpu_seconds_total[5m])", "start": "...", "end": "..."}` 查趋势。省略 `step` 时插件会自动挑一个,使每条 series 的点数不超过 `max_points`。 4. `grafana_alert_state` 不带参数,看现在有什么在告警。 ## Internationalization 把 `locale` 设为 `en`、`zh-TW`、`zh-CN` 或 `ja`,可切换模型看到的工具与参数描述。 工具名称一律保持英文,错误信息也一律是英文。 ## Security and error behavior - 每个工具都是只读。 - 错误永远不会夹带 token、`Authorization` header 或原始 response body。 - 唯一的例外:当 Prometheus 以 HTTP 400 拒绝查询时,会把结构化的 `error` 字段透出, 让 agent 能修正自己的 PromQL。上限 200 字符,且事前会先跑一次敏感信息过滤。 其他状态码一律返回静态信息。 - 响应大小受 `maxResponseBytes`、`maxSeries` 以及每条 series 的点数上限三重限制。 任何裁剪都会在 `meta.truncated` 与裁剪前的总数留下记录。 ## Development ```sh bun install bun run lint bun run typecheck bun run test bun run build ``` ## License MIT