mcpField
B
bug2context

bug2context

本地服务
github.com/emanueld92开发工具11 周前更新

关于 bug2context

bug2context 将 Bug 录屏整理为带时间戳的 Markdown 时间线,供 AI Agent 阅读,并整合关键帧、OCR、设备日志和语音旁白。它面向排查视频所示问题的开发者,可在本地处理,且各处理阶段均可选。

主要功能

  1. 01生成带时间戳的视频时间线
  2. 02提取并去重关键帧
  3. 03识别屏幕文字
  4. 04对齐 Android logcat 日志
  5. 05可选转录语音旁白

适用场景

  1. 01结合 logcat 检查崩溃录屏
  2. 02查看用户发送的屏幕录制
  3. 03定位相关画面和屏幕错误

MCP 相关

MCP 服务提供分析视频、获取单帧图像和列出已处理数据包的工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"emanueld92-bug2context": {
"command": "uvx",
"args": [
"bug2context"
]
}
}
}
启动命令uvx bug2context

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypibug2context0.1.1

工具

3

收录的工具列表 · 更新于 1 周前

参数类型必填说明
ocrboolean否
workdirstring否
max_framesany否
video_pathstring是
transcribe_audioboolean否

详细介绍

bug2context

将 bug 的屏幕录像转换为结构化的时间顺序上下文,让 AI Agent 能够真正读取。

截图会丢失来龙去脉:bug 转瞬即逝,静态画面没有时间线,日志和旁白也完全在别处。大模型无法处理视频。此工具会将录像提炼为一份 Markdown 时间线——关键帧、屏幕文字、设备日志和语音旁白,全部以同一时钟为准。

  • 无需 SDK。 适用于任何视频,包括别人通过 WhatsApp 发给你的视频。
  • 本地优先。 数据不会离开你的设备。无需账户、API 密钥或云服务。
  • 原生支持 MCP。 Claude Code 会将其作为工具调用;你只需指定文件即可。
uvx bug2context               # guided menu
uvx bug2context process bug.mp4 --out bundle/

不带参数运行时会打开菜单——录制 Android 设备、处理已有视频,或列出之前生成的报告包——并将内容写入 ~/.bug2context/,MCP 服务会在此查找。以下标志可以调用它的所有功能;菜单只是让你不用记住这些标志。

输出内容

- `[00:00]` 🖼 `frames/frame_001_00-00.png` — start of recording
      OCR: Cart 2 items
- `[00:04]` 🖼 `frames/frame_002_00-04.png` — screen changed
      OCR: Applying discount..
- `[00:04]` 📋 W/DiscountEngine: rate field missing
- `[00:06]` 🖼 `frames/frame_003_00-06.png` — screen changed
      OCR: TypeError: cannot read 'rate'
- `[00:06]` 📋 E/RideService: NullPointerException at RideRequest.kt:142
- `[00:06]` 📋 F/AndroidRuntime: FATAL EXCEPTION: main
- `[00:06]` 🎙 "ahí está, explota al aplicar el descuento"

完整运行示例见 examples/report.md。

bundle/
├── report.md    the chronology above
├── frames/      the key frames, named by timestamp
└── meta.json    the same data, structured, for programmatic use

安装

需要将 ffmpeg 添加到 PATH(brew install ffmpeg)。

uvx --from 'bug2context[ocr]' bug2context          # OCR: Apple Vision on macOS, tesseract elsewhere
uvx --from 'bug2context[ocr,audio]' bug2context    # plus spoken narration

也可以从源代码安装:

git clone https://github.com/emanueld92/bug2context
cd bug2context
uv sync --extra ocr --extra audio

每个阶段都是可选的,缺少时会自动降级且不会报错:没有 OCR 后端仍可获取帧,没有音轨仍可生成视觉时间线。

在 Claude Code 中使用

claude mcp add bug2context -- uvx --from 'bug2context[ocr]' bug2context-mcp

如果使用本地克隆:uvx --from /path/to/bug2context bug2context-mcp。

然后直接提出请求:“分析这个 bug 视频:~/Desktop/crash.mp4”。

工具用途
analyze_bug_video视频 → 时间顺序报告(直接返回文本)
get_frame获取一帧图像,供 Agent 查看
list_bundles列出之前处理过的报告包,按时间从新到旧排列

报告包默认保存至 ~/.bug2context/<video>-<timestamp>/。

Android:一条命令同时录屏和采集 logcat

uv run bug2context record --seconds 60 --package com.example.app --out bundle/

录制期间重现 bug。两路数据都从同一个主机时间戳开始——正是这个时间基准,才能让堆栈跟踪与显示崩溃的画面对应起来。

请传入 --package。 在真实手机上,仅按级别筛选并不足够:一次 2 分钟的录制收集到 7,634 条 W/E/F 日志,但没有一条来自被测应用——它们全是 AppOpsControllerImpl、GNSSMGT 等进程的日志。限定到应用进程后,只剩 35 条。无论进程为何,都会保留崩溃标签(AndroidRuntime、DEBUG),因为崩溃报告才是重点。

日志会先不加筛选地采集,再进行范围筛选,因此即使应用崩溃后重启,也会记录其崩溃过程。连续重复的相同条目会合并为一条,并附上 (×N) 计数——框架日志常常会成批出现,每批多达 15 条。

已经有日志文件?可以将它合并到任意视频中:

uv run bug2context process bug.mp4 --logcat logcat.txt --log-tag RideService

支持读取 -v time 和 -v threadtime 两种格式。--log-levels 默认值为 WEF,--log-max-lines 默认值为 80;日志按严重程度排序,因此达到上限时,不会为了保留启动日志而丢掉崩溃日志。若已知进程,可用 --log-pid 限定范围。如果设备时钟与录制器不一致,--log-offset 可将所有日志按 N 秒偏移;如果没有提供 --video-started-at,则以第一条日志为时间基准。

screenrecord 最长录制 3 分钟,因此 record 会拒绝更长的录制,而不是返回被静默截断的视频。按 Ctrl-C 可安全地提前结束录制——会先在设备上完成文件收尾,因为直接终止本地 adb 会留下 ffprobe 无法打开的文件。

超过 10 分钟的视频会被拒绝,并显示用于剪辑视频的 ffmpeg 命令(可通过 --max-duration 0 覆盖此限制)。除时间外,其他开销都不会随视频时长急剧增长,但仍呈线性增长:仅解码一项,速度约为实时的三分之一。

旁白

uv run bug2context process bug.mp4 --transcribe --language es

默认关闭:首次使用时会下载模型,而且这是最慢的阶段;大多数录制也没有语音旁白。如果没有音轨,或音轨音量低于 −50 dB,则会自动跳过——whisper 会在静音中编造听起来很可信的句子,因此这一保护措施是为了保证输出质量,而不仅仅是提速。

如何选择帧

ffmpeg 会生成过多候选帧(场景切换和固定间隔采样,因此不会跳过缓慢变化的屏幕),随后通过感知哈希合并近似重复帧。--max-frames 会限制结果数量,始终保留开场帧,之后保留变化最大的帧。

标志默认值说明
--scene-threshold0.08ffmpeg 判定切换所用的场景分数
--interval-seconds1.0未检测到切换时的强制采样间隔
--max-framesauto每 2 s 一帧,数量介于 20 到 40 之间
--phash-distance4低于此值时,帧视为重复
--ocr-upscale2OCR 前放大;宽度超过 1600 px 时跳过

端到端测得的 OCR 时间:

来源结果用时
合成视频,3 min,1080×192019 帧8.5 s
Android 录屏,2 min,720×1612 @ ~12 fps118 个候选帧 → 20 帧16 s
macOS 录屏,90 s,2880×1864 @ 60 fps97 个候选帧 → 18 帧86 s

识别出的文本会按帧内容缓存在 ~/.cache/bug2context/ 中,因此对同一视频使用不同设置重新运行时,只需处理实际发生变化的部分——在一段 44 s 的视频上测得,冷运行耗时 9.0 s,热运行耗时 3.3 s,输出相同。两次提取同一视频会得到逐字节相同的帧,因此缓存是安全的。删除该目录即可重置缓存。

Retina 桌面录屏是最慢的情况,原因无法规避:成本来自以 60 fps 解码 5.4 megapixel 的画面(26 s),再加上 OCR;Vision 无论图像大小如何,每帧都需约 1.6 s。此类录屏的处理时间大致要按实时计算;手机录屏则远低于此时间。

关于 --ocr-upscale:一帧经重新压缩的 1080×1920 画面中的堆栈跟踪,在 1× 时被识别为 Null PointerSxception Ride Requestkt14,在 3× 时则被正确识别为 NullPointerException Ride Request kt 142。对于重新压缩严重的来源,请调高此值——请对方发送视频文件,而不是 WhatsApp 视频。对于宽度已达 1600 px 或更大的帧,会跳过放大;在这些帧上,放大没有带来可测量的改善,却会为每帧生成 5760×3728 的图像。

OCR 还会过滤掉碎屑而非文本的行,例如 »、.lll (100 4,以及误读的状态栏时钟。在一次真实录屏中,这过滤掉了 210 行报告中的 41 行,且没有误删真实文本。看起来像错误的信息绝不会被过滤。

已知限制

感知哈希比较的是视觉结构。它能识别导航界面、对话框和错误横幅,但无法检测布局相同、仅有少量文本变化的情况——在 1080×1920 画面上测得,无论哈希大小如何,这类差异都处于噪声下限之内,因此没有任何 --phash-distance 值能够将其区分开来。

OCR 无法弥补这一点:它只处理通过去重的帧,因此已经合并的屏幕不会被读取。测得对每个候选帧都进行读取,一段 3 min 的视频要耗时 48–59 s,会占满整个时间预算。如果你的 bug 确实是相同屏幕上的少量文本变化,请录制裁剪后的画面或降低分辨率,让文本占据画面更大的区域。

开发

uv sync --extra ocr
uv run pytest -q

共 183 项测试。设备录制会有意进行模拟——测试套件不应录制任何人的手机。Whisper 通过 BUG2CONTEXT_TEST_WHISPER=1 选择性启用,以确保测试套件保持离线。

许可证

MIT——参见 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。