grafana-log-mcp
v1.0.3
Published
Generic Grafana/Loki log-querying MCP server (stdio, read-only). Returns raw logs with aggregated views (slow queries, errors, volume trends); root-cause analysis is done by AI IDE + business code/skills.
Maintainers
Readme
grafana-log-mcp
grafana-log-mcp is a generic, reusable log-querying layer for Grafana/Loki, exposed as a read-only stdio MCP server. It talks to Grafana's API and returns raw logs plus aggregated views — slow queries, error fingerprints, and volume trends — filtered by time window, project, keyword, or duration threshold.
It deliberately ships no business-specific logic or heuristics. Once the logs are in hand, correlating them with source code and explaining why something happened is left to your AI IDE and the skills/rules of the business project being debugged — the server just makes the data available.
中文定位:这是一个通用的日志查询层(仅做取数、聚合、返回日志,跨业务复用),不内置任何业务分析与根因归因;具体原因分析由调用方的 AI 结合业务项目源码及项目自身的 skill/经验完成。
安装
# 方式一:npm 全局安装(推荐)
npm install -g grafana-log-mcp全局安装后提供两个命令:grafana-log-mcp(启动 MCP Server)、grafana-log-mcp-login(交互登录)。
也可不安装、用 npx 一次性运行:npx -y grafana-log-mcp / npx -y grafana-log-mcp-login。
快速开始
npm 已安装(消费方)
# 1. 登录(交互输入 Grafana 地址与用户名密码,写入 ~/.grafana-log-mcp/credentials.json,0600)
grafana-log-mcp-login
# 2. 校验凭证(排查"MCP 突然查不了")
grafana-log-mcp-login --check
# 3. 启动 MCP Server(stdio)
grafana-log-mcp源码开发(clone 仓库后)
# 1. 安装依赖(node >= 18)
npm install
# 2. 登录
node bin/login.js
# 3. 校验凭证
node bin/login.js --check
# 4. 启动 MCP Server(stdio)
npm start # 即 node src/index.js接入 AI IDE(Trae/Claude 等)
在 MCP 配置中添加(按各 IDE 的配置格式):
{
"mcpServers": {
"grafana-log": {
"command": "npx",
"args": ["-y", "grafana-log-mcp"],
"env": { "GRAFANA_URL": "https://your-grafana.example.com" }
}
}
}推荐全局启用:排障时打开的是业务项目源码仓库,把 MCP 配置加为全局,即可在任意仓库直接"提问 → 查日志 → 读代码 → 给原因"。
工具(16 个)
| 层 | 工具 | 用途 |
|---|---|---|
| 发现 | list_datasources / list_projects | 数据源枚举(含名字解析出的业务/环境)+ 项目发现;list_projects 可传 datasourceUid 按需探测单库服务清单(≤2 请求) |
| 反查 | locate_datasource | 只给「客户号/服务名」(标签取值)时跨库反查:返回候选数据源 + 可直接查询的 labels + 扫描覆盖度;首次 10~25s,同关键词二次 2s(1h 缓存) |
| 元数据 | list_labels / list_label_values | 标签与取值 |
| 查询 | query_logs | 原始日志(优先 requestId + 窄时间窗控制数据量) |
| 查询 | get_full_line | 取回单条日志完整原文(单行 500 截断时,按该行 time 作 timestamp 查询) |
| 查询 | query_slow_logs | 按耗时阈值抓慢日志(如 >30s 的慢 SQL),自动配对回捞 SQL 语句原文;命中超 30 条(循环任务)时自动按操作聚合 |
| 有报错 | summarize_errors / logs_volume / trace_context | 错误归并分级、量级突增、单请求链路 |
| 无报错 | compare_baseline / inspect_fields / trace_flow | 消失的日志模板、空值字段、流程断点 |
| 编排 | diagnose_issue | 排障首选:一次调用出诊断报告 + codeHints |
| 辅助 | build_explore_url | 生成 Grafana Explore 深链供人工核对:窗口自动收窄到 30m 内(GRAFANA_EXPLORE_MAX_SPAN 可调)、用绝对时刻(epoch 毫秒)锚定,避免宽窗导致页面拉数超时 |
数据量三道硬上限:limit ≤ 1000、单行 500 字符、响应 25k 字符(超出保头尾省中段并标注)。单行被截断时可用 get_full_line 按该行 time 取回完整内容。
项目登记(projects.json)
登记文件按以下优先级定位(list_projects 返回的 summary.configFile 会显示当前实际生效位置):
GRAFANA_CONFIG_PATH环境变量指定的文件- 包内
config/projects.json(源码仓库内) ~/.grafana-log-mcp/projects.json(与凭证同目录,npm 安装后的默认位置)
参考格式见 config/projects.example.json,每项含 key / datasourceUid / labels{app,group} / aliases(中文别名) / repoPath。repoPath 仅供 AI IDE 定位代码用,MCP 自身不读源码。故障知识库在 config/failure-patterns.json,遇到新故障类型追加条目即可。
数据源定位(业务名 + 环境)
数据源名里的环境信息往往不规范(测试/预发/生产/压测/备用/老的,或括号注释),MCP 内置名字解析器自动提取 业务(biz)/环境(env)/部署形态(form)/基础设施(infra)/注释(note):
list_datasources/list_projects返回每个数据源的解析视图(零请求成本,首次调用不因死库拖慢)- 查询工具的
project参数可直接传「业务名 + 环境」(如acme test、示例应用 生产):未登记时自动按名字解析匹配数据源;唯一命中即查,多命中返回候选表,零命中按业务分组列出全部库 - 成对库启发式:
acme-service/acme-test-service同时存在时,acme 生产自动命中无环境后缀的库 - 标签体系自适应:自动探测数据源主标签是
app还是appName,未传 labels 时兜底 selector 用{<主标签>=~".+"},不会对 appName 库静默查空 - 只给
datasourceUid(不带 labels)时:查询类工具用该库主标签正则覆盖其全部服务;元数据类工具(list_labels/list_label_values)仅用它定位库(不要求该库有 app/appName 主标签) - 主标签探测结果缓存 1h;个别库限制查询窗长(400 exceeds the limit)时自动降级 1d→2h→1h
需要某库的服务清单(登记用)时按需探测单个数据源:
{ "datasourceUid": "xxx", "range": "24h" }返回 { keyLabel, status: ok|unreachable|broken|no-app-label|no-data, services: [...] }。后端不可达、配置损坏、无应用标签的库不纳入登记范围。
批量生成登记草稿(人工校对后合入 projects.json,不会自动写入):
npm run gen:registry # 输出到 stdout
npm run gen:registry -- --out draft.json按标签取值反查(客户号 / 服务名)
用户只说「客户号」或「服务名」时(如"查下 acme,order-task 5 分钟内的数据"),这两个词是标签取值(group / app),不在任何数据源名里——list_datasources 与 project 匹配都找不到,需用 locate_datasource:
{ "keywords": ["acme", "order-task"], "range": "1h" }- 一级关键词按客户维度扫全库(
group > customer > tenant > account > channel > region),零命中自动回退服务维度(app > appName) - 其余关键词作为二级过滤,在候选库的取值清单上收敛(不额外全库扫描)
- 返回候选按生产优先排序:
test_/_test/_dev等测试形态与名字解析出env为 test/staging/stress 的库降权但保留(测试形态判定词可用config/name-words.json的labelValue扩展) labels可直接作为query_logs的参数(配合datasourceUid);summary如实上报扫描覆盖度(不可达 / 配置损坏 / 无该维度标签等分别计数)- 成本:首次 10~25s(并发扫全库,单请求 5s 超时),同参数(关键词 +
range)二次 2s(标签名/取值清单缓存 1h);注意range是取值扫描窗口(默认 1h),不是日志查询窗口;已知数据源名或环境时优先用list_datasources(零请求)
环境变量(可选)
GRAFANA_URL= # Grafana 地址:作为 grafana-log-mcp-login 的默认地址,并覆盖凭证文件中的地址
GRAFANA_TOKEN= # 可选:服务账号 token 直供凭证(免落盘明文),必须与 GRAFANA_URL 同时设置,优先于凭证文件
GRAFANA_ORG_ID=1 # 可选:仅影响 build_explore_url 生成的 Explore 深链的 orgId 参数(默认 1);不参与实际日志查询
GRAFANA_EXPLORE_MAX_SPAN=30m # 可选:Explore 深链窗口上限(默认 30m);超出则保留最近一段并在返回里标注 narrowed
GRAFANA_CREDENTIALS_PATH= # 自定义凭证文件位置
GRAFANA_CONFIG_PATH= # 自定义项目登记文件(projects.json)位置
GRAFANA_MOCK=1 # 本地 mock 模式:不连真实 Grafana、无需登录(2500 条合成日志,验证翻页/截断/慢日志)说明:MCP 不内置任何 Grafana 默认地址与项目配置(通用化),地址来自登录时输入(凭证文件)或 GRAFANA_URL 环境变量;实例相关配置(项目登记、数据源 uid)在 projects.json 维护(见上节定位规则)。
测试
node test/unit.mjs # 纯逻辑单测(合成数据,无网络依赖):含数据源名解析/匹配/主标签探测/翻页 deadline/429 重试/配置热更新
node test/integration.mjs # 编排器端到端(mock client + 独立 fixture 配置)
node test/smoke.mjs # MCP 冒烟:mock 模式启动真实 server,验证握手/tools/list/工具调用