npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

trace-log-mcp

v1.0.9

Published

Standalone MCP service for trace and log tools

Readme

trace-log-mcp

从 log-trace-agent 提取的独立 MCP 服务,提供链路追踪与日志查询工具。

功能特性

  • 8 个 MCP 工具:trace.get、trace.search、trace.get_span、trace.aggregate、trace.service_logs、log.get、log.search、log.parse_scope
  • 多环境支持:online/offline 环境切换
  • SQLite 存储:本地缓存,支持 FTS5 全文检索
  • Stdio 传输:与 Claude Desktop 无缝集成
  • 灵活配置:分层默认值 + 环境变量覆盖

安装

本地源码环境

npm install
npm run build

构建后,如果只是想在当前仓库里调用 CLI,直接用:

npm run cli -- --help
npm run cli -- trace get --input-json '{"trace_id":"<trace-id>","trace_env":"online"}'

如果你希望在源码仓库里也能直接敲 trace-log-cli,则在仓库根目录执行一次:

npm link
trace-log-cli --help

发布包使用方式

发布到 npm 后,统一使用包名 trace-log-mcp 分发 MCP 和 CLI:

npx trace-log-mcp
npm install -g trace-log-mcp
trace-log-cli --help

安装后的命令映射:

  • trace-log-mcp:MCP 服务入口
  • trace-log-cli:AI 优先 CLI 入口

配置

快速开始(最小配置)

.env.example 复制为 .env,配置 3 个必填变量:

cp .env.example .env

编辑 .env

LOG_TRACE_ONLINE_JAEGER_BASE_URL=https://your-jaeger.com
LOG_TRACE_ONLINE_LOKI_BASE_URL=https://your-loki.com
IPS=your-ips-value-here

配置层次

服务采用分层配置策略

  1. 硬编码常量 — 几乎不变的值
  2. 合理默认值 — 可能需要调整的值
  3. 环境变量 — 用户自定义

核心配置(必填 3-4 个变量):

  • LOG_TRACE_ONLINE_JAEGER_BASE_URL — Jaeger API 地址
  • LOG_TRACE_ONLINE_LOKI_BASE_URL — Loki API 地址
  • IPS — IPS 值(自动拼接 ZYBIPSCAS= 前缀作为 Grafana Cookie,online/offline 共用)
  • (可选)Offline 环境对应的同名变量

存储配置(可选,有默认值):

  • LOG_TRACE_STORAGE_SQLITE_PATH — 默认:~/.trace-log-mcp/data.sqlite
  • LOG_TRACE_STORAGE_TTL_HOURS — 默认:72(3 天)
  • LOG_TRACE_STORAGE_ENABLE_FTS5 — 默认:true

高级配置(约 20 个变量,可选):

  • Loki 查询参数(datasource 路径、方向、条数、步长)
  • Jaeger 配置(API 路径模板、额外请求头)
  • HTTP 超时(连接、读取、重试次数)
  • 查询设置(cluster 标签操作符、后置管道、过滤命令)
  • Span Tags(白名单、最大字符数、最大 key 数量)

完整配置说明见 docs/environment-variables.md

使用方式

本地开发

npm run dev

本地真实调试

可以在本地直接调用日志工具,并复用 MCP 服务相同的环境变量配置,对 online/offline 环境做真实调试。

先构建:

npm run build

把 Grafana Explore URL 解析成 log.search 骨架:

npm run debug:log-tool -- \
  --tool log.parse_scope \
  --grafana-url 'https://log-search-docker.zuoyebang.cc/explore?...'

直接从 Grafana URL 执行 log.search,并附带本地覆盖项:

npm run debug:log-tool -- \
  --grafana-url 'https://log-search-docker.zuoyebang.cc/explore?...' \
  --limit 10 \
  --order time_desc

使用显式 JSON 参数调用工具:

npm run debug:log-tool -- \
  --tool log.get \
  --args-json '{"log_hash":"<sha256>","trace_env":"online"}'

如果要复现浏览器上下文,可以额外注入请求头,例如 Cookie / Referer:

npm run debug:log-tool -- \
  --grafana-url 'https://log-search-docker.zuoyebang.cc/explore?...' \
  --headers-file ./debug-headers.json

debug-headers.json 需要是一个扁平 JSON 对象,例如:

{
  "cookie": "k=v; foo=bar",
  "referer": "https://log-search-docker.zuoyebang.cc/explore?orgId=4"
}

AI 优先 CLI

执行 npm run build 后,使用仓库内 CLI 入口:

npm run cli -- --help
npm run cli -- trace get --input-json '{"trace_id":"<trace-id>","trace_env":"online"}'
node dist/cli/index.js --help
node dist/cli/index.js trace get --input-json '{"trace_id":"<trace-id>","trace_env":"online"}'

npm run cli 是源码仓库里最直接的 CLI 入口。dist/index.js 是 MCP 服务入口。发布包场景下,可以直接用 npx trace-log-mcp 启动 MCP;如果执行 npm install -g trace-log-mcp,则可通过 trace-log-cli ... 调用 CLI。若希望在源码仓库里直接使用 trace-log-cli 命令,请先执行一次 npm link

生产启动

npm start

集成到 Claude Desktop

claude_desktop_config.json 中添加:

{
  "mcpServers": {
    "trace-log": {
      "command": "node",
      "args": ["/absolute/path/to/trace-log-mcp/dist/index.js"],
      "env": {
        "LOG_TRACE_ONLINE_JAEGER_BASE_URL": "https://jaeger.example.com",
        "LOG_TRACE_ONLINE_LOKI_BASE_URL": "https://loki.example.com",
        "IPS": "your-ips-value"
      }
    }
  }
}

工具说明

trace.get

从 Jaeger 拉取 trace 并返回结构化摘要,包含 servicesservices_with_request_idsrootserrorstop_slow_spanshigh_call_counttime_range_ns,结果会缓存到 SQLite。

参数:

  • trace_id(必填):Jaeger trace ID
  • trace_env(必填):指定环境(onlineoffline

trace.search

在本地 SQLite 缓存中查询 trace 的 spans,支持按服务、操作、父 span、错误状态、耗时过滤,以及游标分页。返回结果会尽量带上 request_id

参数:

  • trace_id(必填):Trace ID
  • service_nameoperation_nameparent_span_id(可选):过滤条件
  • error_only(可选):仅返回错误 spans
  • min_duration_msmax_duration_ms(可选):耗时过滤
  • sort_by(可选):start_nsduration_desc
  • cursor_start_nscursor_span_id(可选):分页游标
  • limit(可选):返回条数上限(默认 20,最大 100)
  • trace_env(必填):指定环境(onlineoffline

trace.get_span

获取单个 span 的详细信息(含 tags),并返回可识别出的 request_id

参数:

  • trace_id(必填):Trace ID
  • span_id(必填):Span ID
  • trace_env(必填):指定环境(onlineoffline

trace.aggregate

对本地缓存 spans 做聚合统计(count/avg/p95/max),支持按 service_nameoperation_nameerror_flag 分组。

参数:

  • trace_id(必填):Trace ID
  • group_by(必填):service_nameoperation_nameerror_flag
  • 过滤:service_nameoperation_nameerror_flagmin_duration_msmax_duration_ms
  • limit(可选):返回条数上限(默认 50,最大 200)
  • trace_env(必填):指定环境(onlineoffline

trace.service_logs

按服务维度查看 trace。支持对 service_name 做模糊匹配,返回该服务相关 spans、日志摘要(总数+分级计数)和上下游服务关系。日志优先通过 span 上的 request_id 进行关联。具体日志内容请用 log.search

参数:

  • trace_id(必填):Trace ID
  • service_name(必填):要匹配的服务名
  • limit(可选):spans 返回条数上限(默认 50,最大 100)
  • trace_env(必填):指定环境(onlineoffline

log.get

通过 log_hash 从本地 SQLite 取回完整日志行。传入 field_paths 和/或 regex_extractors 时,只返回提取结果,不返回 raw_text

参数:

  • log_hash(必填):日志行的 SHA256 hash
  • max_chars(可选):最大返回字符数(默认 2000)
  • field_paths(可选):从 JSON raw_text 中按点路径提取多个字段的数组,例如 ["params","params.user_id"]。也支持 Loki 文件前缀格式,如 /path/app.log:{...}。传入后响应中不再返回 raw_text
  • regex_extractors(可选):用于非 JSON 或混合文本日志的提取器数组,形如 [{ "name": "request_id", "pattern": "request_id=([^\\s]+)" }]。每个 pattern 都必须是带捕获组的 JavaScript 正则源码字符串,响应会把首个命中的第 1 个捕获组写入 regex_values[name]
  • trace_env(必填):指定环境(onlineoffline

返回重点:

  • total_chars:原始日志总字符数,便于决定是否增大 max_chars
  • raw_text:日志内容,按 max_chars 截断后返回;仅在未传 field_paths 且未传 regex_extractors 时返回
  • truncated:是否发生截断;仅在未传 field_paths 且未传 regex_extractors 时返回
  • field_values:仅在传入 field_paths 时返回;每个 key 对应一个请求路径。若路径不存在或 raw_text 不是可解析 JSON,则该项为 null
  • regex_values:仅在传入 regex_extractors 时返回;每个 key 对应一个 extractor 的 name。若正则未命中,则该项为 null

log.search

统一日志调查入口。它接收 log.parse_scope 产出的结构化 scope,在缓存不足时自动补拉,并只返回可供后续 log.get 使用的日志元数据(通过 hits[].log_hash 下钻查看完整日志)。

参数:

  • scope(必填):主查询范围对象。 scope.query:直接日志查询分支。已知 requestID 时优先填写 requestID;否则必须同时提供 appclusterns 以及 scope.start_msscope.end_mstptimestamp 仅用于进一步收窄范围;与 scope.trace 互斥。 scope.trace:trace 解析分支,需要同时提供 servicetrace_id,先解析 spans / request IDs / selectors 再查日志;与 scope.query 互斥。 scope.value:Grafana 原始过滤片段,例如 grep -P '."level":"WARN"'。只用于远端补拉,不参与本地缓存二次过滤。 scope.start_msscope.end_ms:绝对毫秒时间戳。query 模式且未提供 requestID 时必填;空字符串表示未设置。
  • filter(可选):仅用于本地缓存二次精筛,不会缩小远端 query-scope。 text:原始日志文本包含指定子串。 all_terms:所有词都必须命中。 any_terms:任意一个词命中即可。 exclude_terms:这些词不能出现。 level:按解析后的日志级别过滤,如 WARNERROR
  • group_by(可选):nonelevelrequest_idapp;空字符串按 none 处理。
  • order(可选):time_asctime_desc;也兼容 asc / desc 别名。空字符串按 time_asc 处理。
  • cursor(可选):分页游标;空字符串表示从头开始。
  • limit(可选):返回条数上限;空字符串按默认 50 处理。
  • trace_env(必填):指定环境(onlineoffline

返回重点:

  • hits[]:日志元数据列表,包含 log_hashts_nsappnsclusterpodlevelrequest_id
  • resolved_scope(可选):scope.trace.service 被解析成 request ID / selector 时的解析结果
  • groups(可选):当 group_by != none 时返回聚合计数
  • next_cursor(可选):下一页游标

log.parse_scope

解析 Grafana/LogSearch 的 Explore 页面 URL,并转换成可直接传给 log.search 的完整参数骨架。如果未显式传入 trace_env,工具会将页面 URL 与配置中的 LOG_TRACE_OFFLINE_LOKI_BASE_URL 对比,自动推断 onlineoffline

参数:

  • grafana_url(必填):Grafana/LogSearch Explore 页面 URL

返回重点:

  • trace_env:最终识别出的环境
  • scope.query:解析出的直接查询分支(appclusternsrequestID
  • scope.trace:空的 trace 查询骨架(servicetrace_id),供调用方按需切换到 trace 模式
  • scope.value:解析出的 Grafana 原始过滤片段
  • scope.start_msscope.end_ms:解析出的绝对时间范围;既支持绝对毫秒时间戳,也支持 now-1hnow 这类简单的 Grafana 相对时间表达式

架构

  • 入口src/index.ts — MCP 服务,Stdio 传输
  • 工具src/tools/trace-tools.tssrc/tools/log-tools.ts
  • 共享src/tools/shared.ts — 公共工具函数
  • 客户端src/jaeger-client.tssrc/loki-client.ts
  • 存储src/store.ts — SQLite + FTS5
  • 配置src/config.ts — 分层配置系统
  • 工具库src/utils/ — http、limit、redact 辅助模块

故障排查

服务无法启动

  • 检查 Node.js 版本:node --version(需要 >=22.5.0)
  • 确认依赖已安装:npm install
  • 检查 .env 中的环境变量

工具返回错误

  • 确认 Jaeger/Loki 地址可访问
  • 检查 Grafana Cookie 是否有效
  • 查看 stderr 日志输出

数据库错误

  • 检查 SQLite 路径的文件权限
  • 确认磁盘空间充足
  • 删除后重建:rm ~/.trace-log-mcp/data.sqlite

许可证

MIT