{"id":47240931,"url":"https://github.com/guimatheus92/mcp-video-analyzer","last_synced_at":"2026-03-14T02:42:51.327Z","repository":{"id":343536161,"uuid":"1177112310","full_name":"guimatheus92/mcp-video-analyzer","owner":"guimatheus92","description":"MCP server for video analysis — extracts transcripts, key frames, OCR text, and metadata from video URLs. Supports Loom and direct video files.","archived":false,"fork":false,"pushed_at":"2026-03-10T18:54:41.000Z","size":888,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-11T00:05:41.895Z","etag":null,"topics":["ai","claude","frames","loom","mcp","mcp-server","model-context-protocol","ocr","transcript","video-analysis"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guimatheus92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-09T17:51:43.000Z","updated_at":"2026-03-10T18:52:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/guimatheus92/mcp-video-analyzer","commit_stats":null,"previous_names":["guimatheus92/mcp-video-analyzer"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/guimatheus92/mcp-video-analyzer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guimatheus92%2Fmcp-video-analyzer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guimatheus92%2Fmcp-video-analyzer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guimatheus92%2Fmcp-video-analyzer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guimatheus92%2Fmcp-video-analyzer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guimatheus92","download_url":"https://codeload.github.com/guimatheus92/mcp-video-analyzer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guimatheus92%2Fmcp-video-analyzer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30486396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-14T01:54:10.014Z","status":"online","status_checked_at":"2026-03-14T02:00:06.612Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","claude","frames","loom","mcp","mcp-server","model-context-protocol","ocr","transcript","video-analysis"],"created_at":"2026-03-14T02:42:48.977Z","updated_at":"2026-03-14T02:42:51.313Z","avatar_url":"https://github.com/guimatheus92.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mcp-video-analyzer\n\n\u003ca href=\"https://glama.ai/mcp/servers/guimatheus92/mcp-video-analyzer\"\u003e\n  \u003cimg width=\"380\" height=\"200\" src=\"https://glama.ai/mcp/servers/guimatheus92/mcp-video-analyzer/badge\" alt=\"mcp-video-analyzer MCP server\" /\u003e\n\u003c/a\u003e\n\nFeatured in [awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers#-multimedia-process).\n\nMCP server for video analysis — extracts transcripts, key frames, and metadata from video URLs. Supports Loom, direct video files (.mp4, .webm), and more.\n\nNo existing video MCP combines **transcripts + visual frames + metadata** in one tool. This one does.\n\n## Installation\n\n### Prerequisites\n\n- **Node.js 18+** — required to run the server via `npx`\n- **yt-dlp** (optional) — enables frame extraction via ffmpeg. Install with `pip install yt-dlp`\n- **Chrome/Chromium** (optional) — fallback for frame extraction if yt-dlp is unavailable\n\n\u003e Without yt-dlp or Chrome, the server still works — you'll get transcripts, metadata, and comments, just no frames.\n\n### Claude Code (CLI)\n\n```bash\nclaude mcp add video-analyzer -- npx mcp-video-analyzer@latest\n```\n\nThen restart Claude Code or start a new conversation.\n\n### VS Code / Cursor\n\nAdd to your MCP settings file:\n\n- **VS Code**: `File → Preferences → Settings → search \"MCP\"` or edit `~/.vscode/mcp.json` / `%APPDATA%\\Code\\User\\mcp.json` (Windows)\n- **Cursor**: `Settings → MCP Servers → Add`\n\n```json\n{\n  \"servers\": {\n    \"mcp-video-analyzer\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"mcp-video-analyzer@latest\"]\n    }\n  }\n}\n```\n\nThen reload the window (`Ctrl+Shift+P` → \"Developer: Reload Window\").\n\n### Claude Desktop\n\nAdd to your Claude Desktop config file:\n\n- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`\n- **Windows**: `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"video-analyzer\": {\n      \"command\": \"npx\",\n      \"args\": [\"mcp-video-analyzer@latest\"]\n    }\n  }\n}\n```\n\nThen restart Claude Desktop.\n\n### Verify it works\n\nOnce installed, ask your AI assistant:\n\n```\nAnalyze this video: https://www.loom.com/share/bdebdfe44b294225ac718bad241a94fe\n```\n\nIf the server is connected, it will automatically call the `analyze_video` tool.\n\n## Tools\n\n### `analyze_video` — Full video analysis\n\nExtracts everything from a video URL in one call:\n\n```\n\u003e Analyze this video: https://www.loom.com/share/abc123...\n```\n\nReturns:\n- **Transcript** with timestamps and speakers\n- **Key frames** extracted via scene-change detection (automatically deduplicated)\n- **OCR text** extracted from frames (code, error messages, UI text visible on screen)\n- **Annotated timeline** merging transcript + frames + OCR into a unified \"what happened when\" view\n- **Metadata** (title, duration, platform)\n- **Comments** from viewers\n- **Chapters** and **AI summary** (when available)\n\nThe AI will **automatically** call this tool when it sees a video URL — no need to ask.\n\nOptions:\n- `detail` — analysis depth: `\"brief\"` (metadata + truncated transcript, no frames), `\"standard\"` (default), `\"detailed\"` (dense sampling, more frames)\n- `fields` — array of specific fields to return, e.g. `[\"metadata\", \"transcript\"]`. Available: `metadata`, `transcript`, `frames`, `comments`, `chapters`, `ocrResults`, `timeline`, `aiSummary`\n- `maxFrames` (1-60, default depends on detail level) — cap on extracted frames\n- `threshold` (0.0-1.0, default 0.1) — scene-change sensitivity\n- `forceRefresh` — bypass cache and re-analyze\n- `skipFrames` — skip frame extraction for transcript-only analysis\n\n### `get_transcript` — Transcript only\n\n```\n\u003e Get the transcript from this video\n```\n\nQuick transcript extraction. Falls back to Whisper transcription when no native transcript is available.\n\n### `get_metadata` — Metadata only\n\n```\n\u003e What's this video about?\n```\n\nReturns metadata, comments, chapters, and AI summary without downloading the video.\n\n### `get_frames` — Frames only\n\n```\n\u003e Extract frames from this video with dense sampling\n```\n\nTwo modes:\n- **Scene-change detection** (default) — captures visual transitions\n- **Dense sampling** (`dense: true`) — 1 frame/sec for full coverage\n\n### `analyze_moment` — Deep-dive on a time range\n\n```\n\u003e Analyze what happens between 1:30 and 2:00 in this video\n```\n\nCombines burst frame extraction + filtered transcript + OCR + annotated timeline for a focused segment. Use when you need to understand exactly what happens at a specific moment.\n\n### `get_frame_at` — Single frame at a timestamp\n\n```\n\u003e Show me the frame at 1:23 in this video\n```\n\nThe AI reads the transcript, spots a critical moment, and requests the exact frame to see what's on screen.\n\n### `get_frame_burst` — N frames in a time range\n\n```\n\u003e Show me 10 frames between 0:15 and 0:17 of this video\n```\n\nFor motion, vibration, animations, or fast scrolling — burst mode captures N frames in a narrow window so the AI can see frame-by-frame changes.\n\n## Detail Levels\n\n| Level | Frames | Transcript | OCR | Timeline | Use case |\n|-------|--------|-----------|-----|----------|----------|\n| `brief` | None | First 10 entries | No | No | Quick check — what's this video about? |\n| `standard` | Up to 20 (scene-change) | Full | Yes | Yes | Default — full analysis |\n| `detailed` | Up to 60 (1fps dense) | Full | Yes | Yes | Deep analysis — every second captured |\n\n## Caching\n\nResults are cached in memory for 10 minutes. Subsequent calls with the same URL and options return instantly. Use `forceRefresh: true` to bypass the cache.\n\n## Supported Platforms\n\n| Platform | Transcript | Metadata | Comments | Frames | Auth |\n|----------|:----------:|:--------:|:--------:|:------:|:----:|\n| **Loom** | Yes | Yes | Yes | Yes | None |\n| **Direct URL** (.mp4, .webm) | No | Duration only | No | Yes | None |\n\n### Frame Extraction Strategies\n\nFrame extraction uses a two-strategy fallback chain — no single dependency is required:\n\n| Strategy | How it works | Speed | Requirements |\n|----------|-------------|-------|-------------|\n| **yt-dlp + ffmpeg** (primary) | Downloads video, extracts frames via scene detection | Fast, precise | [yt-dlp](https://github.com/yt-dlp/yt-dlp) (`pip install yt-dlp`) |\n| **Browser** (fallback) | Opens video in headless Chrome, seeks to timestamps, takes screenshots | Slower, no download needed | Chrome or Chromium installed |\n\nThe fallback is automatic — if yt-dlp is not available, the server tries browser-based extraction via `puppeteer-core`. If neither is available, analysis still returns transcript + metadata + comments, just no frames.\n\n### Post-Processing Pipeline\n\nAfter frame extraction, the pipeline automatically applies:\n\n| Step | What it does | Why |\n|------|-------------|-----|\n| **Frame deduplication** | Removes near-identical consecutive frames using perceptual hashing (dHash + Hamming distance) | Screencasts often have long static moments — dedup removes redundant frames, saving tokens |\n| **OCR** | Extracts text visible on screen from each frame (via tesseract.js) | Captures code, error messages, terminal output, UI text that the transcript doesn't cover |\n| **Annotated timeline** | Merges transcript timestamps + frame timestamps + OCR text into a single chronological view | Gives the AI a unified \"what was said, what changed visually, and what text appeared\" at each moment |\n\nThe OCR step requires `tesseract.js` (included as a dependency). If it fails to load, analysis continues without OCR — no frames or transcript are lost.\n\n## Complementary Tools\n\n### Chrome DevTools MCP\n\nFor **live web debugging** alongside video analysis, pair this server with the [Chrome DevTools MCP](https://github.com/anthropics/anthropic-quickstarts/tree/main/mcp-devtools):\n\n```bash\nclaude mcp add chrome-devtools npx @anthropic-ai/mcp-devtools@latest\n```\n\n**When to use each:**\n\n| Scenario | Tool |\n|----------|------|\n| Bug report recorded as a Loom video | `mcp-video-analyzer` — extract transcript, frames, and error text from the recording |\n| Live debugging a web page | Chrome DevTools MCP — inspect DOM, console, network, take screenshots |\n| Video shows UI issue, need to reproduce it | Use both: analyze the video first, then open the page in Chrome DevTools to reproduce |\n\nThe two MCPs complement each other: video analyzer understands **recorded** content, DevTools interacts with **live** pages.\n\n## Example Output\n\nThe [`examples/loom-demo/`](examples/loom-demo/) folder contains **real outputs** from analyzing a public Loom video ([Boost In-App Demo Video](https://www.loom.com/share/bdebdfe44b294225ac718bad241a94fe), 2:55).\n\n| File | What it shows |\n|------|--------------|\n| [`metadata.json`](examples/loom-demo/metadata.json) | Title, duration, platform |\n| [`transcript.json`](examples/loom-demo/transcript.json) | 42 timestamped entries with speaker IDs |\n| [`timeline.json`](examples/loom-demo/timeline.json) | Unified chronological view (transcript + frames merged) |\n| [`moment-transcript-0m30s-0m45s.json`](examples/loom-demo/moment-transcript-0m30s-0m45s.json) | Filtered transcript for `analyze_moment` (0:30–0:45) |\n| [`full-analysis.json`](examples/loom-demo/full-analysis.json) | Complete `analyze_video` output |\n\n**Frame images** (19 total in [`examples/loom-demo/frames/`](examples/loom-demo/frames/)):\n- `scene_*.jpg` — scene-change detection (key visual transitions)\n- `dense_*.jpg` — 1fps dense sampling (every 10th frame saved as sample)\n- `burst_*.jpg` — burst extraction for moment analysis (0:30–0:45)\n\n\u003e **Regenerate after changes:** `npx tsx examples/generate.ts` — requires yt-dlp + network access.\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run all checks (format, lint, typecheck, knip, tests)\nnpm run check\n\n# Build\nnpm run build\n\n# Run E2E tests (requires network)\nnpm run test:e2e\n\n# Open MCP Inspector for manual testing\nnpm run inspect\n```\n\n## Architecture\n\n```\nsrc/\n├── index.ts                    # Entry point (shebang + stdio)\n├── server.ts                   # FastMCP server + tool registration\n├── tools/                      # MCP tool definitions (7 tools)\n│   ├── analyze-video.ts        # Full analysis with detail levels + caching\n│   ├── analyze-moment.ts       # Deep-dive on a time range\n│   ├── get-transcript.ts       # Transcript-only with Whisper fallback\n│   ├── get-metadata.ts         # Metadata + comments + chapters\n│   ├── get-frames.ts           # Frames-only (scene-change or dense)\n│   ├── get-frame-at.ts         # Single frame at timestamp\n│   └── get-frame-burst.ts      # N frames in a time range\n├── adapters/                   # Platform-specific logic\n│   ├── adapter.interface.ts    # IVideoAdapter interface + registry\n│   ├── loom.adapter.ts         # Loom: authless GraphQL\n│   └── direct.adapter.ts       # Direct URL: any mp4/webm link\n├── processors/                 # Shared processing\n│   ├── frame-extractor.ts      # ffmpeg scene detection + dense + burst extraction\n│   ├── browser-frame-extractor.ts # Headless Chrome fallback for frames\n│   ├── audio-transcriber.ts    # Whisper fallback (HF transformers → CLI → OpenAI)\n│   ├── image-optimizer.ts      # sharp resize/compress\n│   ├── frame-dedup.ts          # Perceptual dedup (dHash + Hamming distance)\n│   ├── frame-ocr.ts            # OCR text extraction (tesseract.js)\n│   └── annotated-timeline.ts   # Unified timeline (transcript + frames + OCR)\n├── config/\n│   └── detail-levels.ts        # brief / standard / detailed config\n├── utils/\n│   ├── cache.ts                # In-memory TTL cache with LRU eviction\n│   ├── field-filter.ts         # Selective field filtering for responses\n│   ├── url-detector.ts         # Platform detection from URL\n│   ├── vtt-parser.ts           # WebVTT → transcript entries\n│   └── temp-files.ts           # Temp directory management\n└── types.ts                    # Shared TypeScript interfaces\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguimatheus92%2Fmcp-video-analyzer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguimatheus92%2Fmcp-video-analyzer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguimatheus92%2Fmcp-video-analyzer/lists"}