Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Description from the maker (original English)
Turn bug screen recordings into chronological context for AI agents: frames, OCR, logcat, voice.
These three are never merged into one score: opinions, measurements and popularity are different things.
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
Pick the AI app you use, then copy the settings.
You need
Which app do you use?
Pick your app above. We remember it, so next time the button says “Install in …”.
Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json
{
"mcpServers": {
"bug2context": {
"command": "uvx",
"args": [
"bug2context",
"mcp"
]
}
}
}Run this in your terminal
claude mcp add bug2context -- uvx bug2context mcpPaste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json
{
"mcpServers": {
"bug2context": {
"command": "uvx",
"args": [
"bug2context",
"mcp"
]
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
Paste into .vscode/mcp.json in your project
{
"servers": {
"bug2context": {
"type": "stdio",
"command": "uvx",
"args": [
"bug2context",
"mcp"
]
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.
Your choice stays on this device in a cookie; no account needed.
These settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
Runs on your computer; the tool list appears in your AI app after you install it.
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 6, 2026
The registry name was verified with the GitHub account emanueld92, which owns the repo
We have not read this repo from GitHub yet
We have not read this repo from GitHub yet
This one runs on your computer; there is no internet endpoint
Runs on your computer and uses local settings instead
Runs on your computer; we can only read tool lists from internet endpoints
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
The registry does not list a required key, though some servers ask you to sign in on first use.
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
The GitHub repo last changed –, and the latest version (0.1.1) reached the registry 15 days ago.
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Python (uv) on your computer.
In the same category: Spec Driven Development, Remote Desktop Commander, LickityClick
Servers in the same category from other makers, sorted by stars.
Reading a card:★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Create, edit and track LickityClick short links, campaigns and click stats from your AI assistant.
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
Turns a screen recording of a bug into structured, chronological context an AI agent can actually read.
Screenshots lose the story: bugs happen fast, a still frame has no timeline, and the logs and the narration live somewhere else entirely. LLMs don't take video. This distills a recording into one markdown chronology — key frames, the text on screen, device logs and spoken narration, all on the same clock.
uvx bug2context # guided menu
uvx bug2context process bug.mp4 --out bundle/
Running it with no arguments opens a menu — record an Android device, process a video you already have, or list previous bundles — and writes to ~/.bug2context/, which is where the MCP server looks. Everything it does is reachable through the flags below; it just stops you having to remember them.
- `[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"
A full run is in 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
Requires ffmpeg on 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
Or from source:
git clone https://github.com/emanueld92/bug2context
cd bug2context uv sync --extra ocr --extra audio
Every stage is optional and degrades quietly: no OCR backend still gives you frames, no audio track still gives you the visual timeline.
claude mcp add bug2context -- uvx --from 'bug2context[ocr]' bug2context-mcp
Working from a local clone instead: uvx --from /path/to/bug2context bug2context-mcp.
Then just ask: *"analiza este video del bug: ~/Desktop/crash.mp4"*.
| Tool | Purpose |
|---|---|
analyze_bug_video | Video → chronological report (returns the text itself) |
get_frame | Fetch one frame as an image so the agent can look at it |
list_bundles | Previously processed bundles, newest first |
Bundles default to ~/.bug2context/ - /.
uv run bug2context record --seconds 60 --package com.example.app --out bundle/
Reproduce the bug while it records. Both streams start from a single host timestamp — that anchor is what makes a stack trace land next to the frame showing the crash.
Pass `--package`. Level filtering alone is not enough on a real phone: a 2 min capture held 7,634 W/E/F lines and *none* came from the app under test — they were all AppOpsControllerImpl, GNSSMGT and friends. Scoping to the app's process left 35. Crash tags (AndroidRuntime, DEBUG) are kept regardless of process, since a crash report is the whole point.
Logs are captured unfiltered and scoped afterwards, so an app that crashes and restarts still has its death recorded. Consecutive identical entries fold into one with a (×N) count — framework chatter arrives in bursts of fifteen.
Already have a log file? Merge it into any video:
uv run bug2context process bug.mp4 --logcat logcat.txt --log-tag RideService
Reads both -v time and -v threadtime. --log-levels defaults to WEF and --log-max-lines to 80, ranked by severity so a cap never trades the crash for boot chatter. --log-pid scopes to a process when you already know it. If the device clock and the recorder disagree, --log-offset shifts everything by N seconds; with no --video-started-at, the first log entry becomes the anchor.
screenrecord caps at 3 minutes, so record refuses longer rather than handing back a silently truncated video. Ctrl-C cuts a recording short safely — the file is finalised on the device first, because killing the local adb leaves one ffprobe cannot open.
Videos over 10 minutes are refused with the ffmpeg command to trim them (--max-duration 0 overrides). Nothing scales badly with length except time, but it scales linearly: decoding alone runs at about a third of real time.
uv run bug2context process bug.mp4 --transcribe --language es
Off by default: it downloads a model on first use and is the slowest stage, while most recordings have no voice-over. Skipped automatically when there is no audio track, or the track is quieter than −50 dB — whisper invents confident sentences out of silence, so that guard is about output quality, not just speed.
ffmpeg over-produces candidates (scene cuts and a fixed interval, so slowly changing screens are not skipped), then perceptual hashing collapses the near-duplicates. --max-frames caps the result, always keeping the opening frame and then whichever changed most.
| Flag | Default | Notes |
|---|---|---|
--scene-threshold | 0.08 | ffmpeg scene score for a cut |
--interval-seconds | 1.0 | forced sample when no cut fires |
--max-frames | auto | one frame per 2 s, between 20 and 40 |
--phash-distance | 4 | below this, frames count as duplicates |
--ocr-upscale | 2 | enlarge before OCR; skipped above 1600 px wide |
Measured end to end, OCR on:
| Source | Result | Time |
|---|---|---|
| synthetic 3 min, 1080×1920 | 19 frames | 8.5 s |
| Android capture, 2 min, 720×1612 @ ~12 fps | 118 candidates → 20 frames | 16 s |
| macOS capture, 90 s, 2880×1864 @ 60 fps | 97 candidates → 18 frames | 86 s |
Recognised text is cached by frame content in ~/.cache/bug2context/, so re-running a video with different settings only pays for what actually changed — measured 9.0 s cold against 3.3 s warm on a 44 s clip, identical output. Extracting the same video twice yields byte-identical frames, which is what makes the cache safe. Delete the directory to reset it.
Retina desktop recordings are the slow case and there is no trick to remove: the cost is decoding 60 fps at 5.4 megapixels (26 s) plus OCR, which Vision charges at ~1.6 s per frame regardless of size. Budget roughly real time for those; phone captures stay far under it.
On --ocr-upscale: a stack trace on a recompressed 1080×1920 frame read as Null PointerSxception Ride Requestkt14 at 1× and correctly as NullPointerException Ride Request kt 142 at 3×. Raise it for badly recompressed sources — ask for the video as a file, not as a WhatsApp video. It is skipped on frames already 1600 px or wider, where it changed nothing measurable while building a 5760×3728 image per frame.
OCR also drops lines that are debris rather than text — », .lll (100 4, a misread status-bar clock. On a real capture that removed 41 of 210 report lines and no real text. A line that looks like a failure is never dropped.
Perceptual hashing compares visual *structure*. It sees navigation, dialogs and error banners, but it cannot detect a small text-only change on an otherwise identical layout — measured on 1080×1920 those differences fall inside the noise floor at every hash size, so no --phash-distance value separates them.
OCR does not rescue this: it runs on frames that survive deduplication, so a screen already collapsed is never read. Reading every candidate instead measured 48–59 s for a 3 min video, over the entire time budget. If your bug *is* a small text change on an identical screen, record cropped or at lower resolution so the text occupies more of the frame.
uv sync --extra ocr
uv run pytest -q
183 tests. Device recording is mocked on purpose — a test suite should not record anyone's phone. Whisper is opt-in via BUG2CONTEXT_TEST_WHISPER=1 so the suite stays offline.
MIT — see LICENSE.