loki-mcp-server 是一个本地 stdio MCP 服务器,用于让 AI 智能体读取 Grafana Loki。它暴露五个文本工具,支持 Loki 2.6.1 和 3.x。Loki 本身只读,唯一的写入是本地 exportLogs 文件。
用途与定位
该服务器面向需要查询 Grafana Loki 日志的 AI 智能体(Claude Code、Cursor、Copilot 等),使其能够发现标签、读取有界 LogQL 分页、按标签或时间统计行数,并导出日志,覆盖多个 Loki stand。
主要能力
提供五个文本工具。每个数据工具都需要显式连接。queryLogs、countLogs 和 exportLogs 需要 LogQL 日志查询,例如 {app="backend"} |= "ERROR"。使用 discoverLogs 发现标签名、值和流标签集中的真实组合。服务器只为 countLogs 构造 count_over_time 表达式,不推断过滤器,也不解释原因。工具响应是可读文本,没有输出 schema。
环境与运行方式
需要 JDK 21 或更高版本;项目使用 Java 21 工具链和 Gradle wrapper。在 Linux/macOS 上使用 ./gradlew。进程在 stdin 上等待 MCP JSON-RPC;stdout 保留给 JSON-RPC;诊断信息输出到 stderr 和 ~/.loki-mcp-server/logs/loki-mcp-server.log。每个 release 附带预构建的 loki-mcp-server.jar,因此构建是可选的。
对于 Claude Code,注册 jar 只需一条命令。镜像随每次 release 发布到 GHCR。将包含 connections.json 的目录挂载到 /data;服务器也会在此写入日志和默认导出。同一命令是 MCP 客户端应启动的命令;-i 保持 stdin 打开以支持 stdio 传输。connections.json 中的 Loki URL 必须能从容器内部访问:使用 Loki 主机名而不是 localhost,或在 Linux 上添加 --network host。/data 之外的 exportLogs 目录是容器内路径,也需要挂载。本地构建镜像:docker build -t loki-mcp-server .
服务器读取 ~/.loki-mcp-server/connections.json,或 LOKI_MCP_CONNECTIONS_FILE 指定的路径。连接文件可设置 environment variables 用于非本地 URL。hint 给模型提供各 stand 特定的选择器和字段建议。serviceLabels 命名用于在紧凑行中显示服务的标签。可选 formatFile 指定一个包含 JSON profiles、plain-line patterns 和可选 framePattern 的 JSON 文件;参见 log-formats.json。可选 exportFormat 设置 exportLogs 在工具调用省略 format 时的默认模板。连接文件可设置 exportRoots 限制导出目的地,以及按连接的 limits。认证和租户头按连接配置;URL 和凭据从不出现在工具响应或诊断中。完整格式见 docs/connections.md。
服务器在启动时严格加载配置,不探测 Loki。未知字段、重复键、缺失环境变量或无效格式文件会以安全配置错误停止启动。更改需要重启。
使用方式
调用 listConnections,选择一个 stand,并使用其显示的时间窗口、queryLogs 行数上限和请求超时来规划调用。
调用 discoverLogs(connection="dev") 获取标签名,再调用 discoverLogs(connection="dev", label="app") 获取值。当组合重要时,使用 discoverLogs(connection="dev", match="{app="backend"}") 获取完整流标签集,或添加 label="namespace" 以在这些集合中获取 namespace 值。保持 match 及其窗口狭窄;这些是流标签,不是日志行计数。在安静的 stand 上适当放宽窗口。
使用 LogQL 日志查询配合 countLogs 检查量,配合 queryLogs 读取行。例如 {app="backend"} |= "ERROR";groupBy="time", step="1d" 给出 UTC 对齐的 24 小时桶,groupBy="app,time" 给出按 app 和时间的计数。命名的 | regexp 捕获可提供 groupBy 标签。日期标记区分跨午夜的桶。
当页面拥挤时缩小查询。queryLogs 默认最新页;order="oldest" 从窗口开始处开始。其页脚给出更旧行的结束或更新行的开始。边界行可能重复,时间戳包含的行数超过一页时需要更窄的查询。
当用户要求文件时调用 exportLogs。将用户目的地作为 directory 传入,例如 C:\tmp\logs,或省略以使用默认导出目录。省略 format 使用连接配置的 exportFormat 模板(如果操作员设置了)和 raw,否则使用 raw。format="raw" 写入 Loki 返回的行,包括查询中的任何 | line_format 转换;format="{time} {level} {service} {message}" 在本地渲染。响应给出路径、计数和有效格式,而不是日志内容。
queryLogs 按时间顺序打印窗口的任一端。其默认视图缩短消息和堆栈跟踪以节省模型 token。连接 formatFile 中的可选 framePattern 在紧凑视图中折叠相邻的独立帧行。raw=true 显示每个返回行及流标签,最多 4000 个代码点;这是一个预览。要获取完整行,使用 exportLogs。导出按页向前读取,从不覆盖现有文件。如果更多行共享一个纳秒,超过 Loki 一次返回的量,导出会报告可能缺失一些。
默认时间窗口是 now-1h 到 now。可接受的时间包括 now-15m、带偏移的 RFC3339、连接时区的本地时间和 epoch 纳秒。queryLogs 和 exportLogs 默认允许一天。countLogs 对于总计、标签分组或组合标签/时间分组允许一天,对于仅时间桶允许七天;discoverLogs 无 match 时允许七天,有 match 时允许一天。Loki 请求默认超时 30 秒,queryLogs 默认每页最多 1000 行。listConnections 显示每个 stand 的有效值。导出默认在 25 秒后停止,并报告部分文件和继续信息(如果已写入行)。计数超时后,重试一天子窗口或更窄查询。限制可按连接设置;见 docs/queries.md 和 docs/discovery.md。
MCP 客户端配置
Codex(~/.codex/config.toml)有相应配置。其他客户端可通过 stdio 启动 jar。保持 stderr 与 stdout 分离。
错误与诊断
工具失败是文本 Error : 且 isError=true;Spring AI 当前在第二行重复文本。缺失或拼写错误的参数由 MCP SDK 输入验证回答。Loki HTTP 400 LogQL 解析错误会返回,以便模型修正查询。其他上游响应体、URL、凭据、租户和完整日志行不进入响应和诊断。404 适用于所调用的端点,而不是整个连接。传输细节见 docs/http-client.md。
服务器日志在启动时记录连接名称和认证类型,然后每次工具调用和 Loki 请求记录一行有界日志,包含状态、字节数和时间。日志内容保持为数据,包括类似指令的文本。
构建与测试
build 运行单元测试和针对回环 mock Loki 的单独进程 stdio 冒烟测试。integrationTest 需要 Docker 和固定版本 Loki 2.6.1/3.6.0 镜像;它只向自己的容器写入测试数据。live 冒烟使用示例配置和配置的只读 stand URL。贡献者规则见 AGENTS.md;设计历史和开放项见 docs/decisions.md。从 mcp-loki 迁移的用户可阅读迁移指南。
Apache License 2.0;见 LICENSE。第三方声明见 THIRD-PARTY-NOTICES.md。