mcp-video-analyzer 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +245 -0
  3. package/dist/adapters/adapter.interface.d.ts +15 -0
  4. package/dist/adapters/adapter.interface.js +17 -0
  5. package/dist/adapters/adapter.interface.js.map +1 -0
  6. package/dist/adapters/direct.adapter.d.ts +13 -0
  7. package/dist/adapters/direct.adapter.js +67 -0
  8. package/dist/adapters/direct.adapter.js.map +1 -0
  9. package/dist/adapters/loom.adapter.d.ts +13 -0
  10. package/dist/adapters/loom.adapter.js +183 -0
  11. package/dist/adapters/loom.adapter.js.map +1 -0
  12. package/dist/config/detail-levels.d.ts +18 -0
  13. package/dist/config/detail-levels.js +30 -0
  14. package/dist/config/detail-levels.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +5 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/processors/annotated-timeline.d.ts +25 -0
  19. package/dist/processors/annotated-timeline.js +83 -0
  20. package/dist/processors/annotated-timeline.js.map +1 -0
  21. package/dist/processors/audio-transcriber.d.ts +16 -0
  22. package/dist/processors/audio-transcriber.js +191 -0
  23. package/dist/processors/audio-transcriber.js.map +1 -0
  24. package/dist/processors/browser-frame-extractor.d.ts +27 -0
  25. package/dist/processors/browser-frame-extractor.js +132 -0
  26. package/dist/processors/browser-frame-extractor.js.map +1 -0
  27. package/dist/processors/frame-dedup.d.ts +23 -0
  28. package/dist/processors/frame-dedup.js +76 -0
  29. package/dist/processors/frame-dedup.js.map +1 -0
  30. package/dist/processors/frame-extractor.d.ts +19 -0
  31. package/dist/processors/frame-extractor.js +201 -0
  32. package/dist/processors/frame-extractor.js.map +1 -0
  33. package/dist/processors/frame-ocr.d.ts +13 -0
  34. package/dist/processors/frame-ocr.js +45 -0
  35. package/dist/processors/frame-ocr.js.map +1 -0
  36. package/dist/processors/image-optimizer.d.ts +7 -0
  37. package/dist/processors/image-optimizer.js +21 -0
  38. package/dist/processors/image-optimizer.js.map +1 -0
  39. package/dist/server.d.ts +2 -0
  40. package/dist/server.js +67 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/tools/analyze-moment.d.ts +2 -0
  43. package/dist/tools/analyze-moment.js +145 -0
  44. package/dist/tools/analyze-moment.js.map +1 -0
  45. package/dist/tools/analyze-video.d.ts +2 -0
  46. package/dist/tools/analyze-video.js +320 -0
  47. package/dist/tools/analyze-video.js.map +1 -0
  48. package/dist/tools/get-frame-at.d.ts +2 -0
  49. package/dist/tools/get-frame-at.js +88 -0
  50. package/dist/tools/get-frame-at.js.map +1 -0
  51. package/dist/tools/get-frame-burst.d.ts +2 -0
  52. package/dist/tools/get-frame-burst.js +106 -0
  53. package/dist/tools/get-frame-burst.js.map +1 -0
  54. package/dist/tools/get-frames.d.ts +2 -0
  55. package/dist/tools/get-frames.js +143 -0
  56. package/dist/tools/get-frames.js.map +1 -0
  57. package/dist/tools/get-metadata.d.ts +2 -0
  58. package/dist/tools/get-metadata.js +65 -0
  59. package/dist/tools/get-metadata.js.map +1 -0
  60. package/dist/tools/get-transcript.d.ts +2 -0
  61. package/dist/tools/get-transcript.js +82 -0
  62. package/dist/tools/get-transcript.js.map +1 -0
  63. package/dist/types.d.ts +62 -0
  64. package/dist/types.js +2 -0
  65. package/dist/types.js.map +1 -0
  66. package/dist/utils/cache.d.ts +31 -0
  67. package/dist/utils/cache.js +87 -0
  68. package/dist/utils/cache.js.map +1 -0
  69. package/dist/utils/field-filter.d.ts +10 -0
  70. package/dist/utils/field-filter.js +32 -0
  71. package/dist/utils/field-filter.js.map +1 -0
  72. package/dist/utils/temp-files.d.ts +3 -0
  73. package/dist/utils/temp-files.js +28 -0
  74. package/dist/utils/temp-files.js.map +1 -0
  75. package/dist/utils/url-detector.d.ts +4 -0
  76. package/dist/utils/url-detector.js +33 -0
  77. package/dist/utils/url-detector.js.map +1 -0
  78. package/dist/utils/vtt-parser.d.ts +2 -0
  79. package/dist/utils/vtt-parser.js +85 -0
  80. package/dist/utils/vtt-parser.js.map +1 -0
  81. package/package.json +78 -0
@@ -0,0 +1,85 @@
1
+ const TIMESTAMP_LINE = /^(\d{2}:\d{2}:\d{2}\.\d{3})\s*-->\s*(\d{2}:\d{2}:\d{2}\.\d{3})/;
2
+ const SPEAKER_TAG = /^<v\s+([^>]+)>(.*)<\/v>$/s;
3
+ const HTML_TAGS = /<[^>]+>/g;
4
+ const SEQUENCE_NUMBER = /^\d+$/;
5
+ export function parseVtt(vttContent) {
6
+ const lines = vttContent.split(/\r?\n/);
7
+ const entries = [];
8
+ let currentStart = null;
9
+ let currentEnd = null;
10
+ let currentTextLines = [];
11
+ for (const line of lines) {
12
+ const trimmed = line.trim();
13
+ if (trimmed === 'WEBVTT' || trimmed.startsWith('WEBVTT ')) {
14
+ continue;
15
+ }
16
+ if (trimmed.startsWith('NOTE')) {
17
+ continue;
18
+ }
19
+ if (SEQUENCE_NUMBER.test(trimmed)) {
20
+ continue;
21
+ }
22
+ const timestampMatch = trimmed.match(TIMESTAMP_LINE);
23
+ if (timestampMatch) {
24
+ if (currentStart && currentTextLines.length > 0) {
25
+ entries.push(buildEntry(currentStart, currentEnd, currentTextLines));
26
+ }
27
+ currentStart = timestampMatch[1];
28
+ currentEnd = timestampMatch[2];
29
+ currentTextLines = [];
30
+ continue;
31
+ }
32
+ if (trimmed === '') {
33
+ if (currentStart && currentTextLines.length > 0) {
34
+ entries.push(buildEntry(currentStart, currentEnd, currentTextLines));
35
+ currentStart = null;
36
+ currentEnd = null;
37
+ currentTextLines = [];
38
+ }
39
+ continue;
40
+ }
41
+ if (currentStart !== null) {
42
+ currentTextLines.push(trimmed);
43
+ }
44
+ }
45
+ if (currentStart && currentTextLines.length > 0) {
46
+ entries.push(buildEntry(currentStart, currentEnd, currentTextLines));
47
+ }
48
+ return entries;
49
+ }
50
+ function buildEntry(startTimestamp, endTimestamp, textLines) {
51
+ const joinedText = textLines.join(' ');
52
+ let speaker;
53
+ let text;
54
+ const speakerMatch = joinedText.match(SPEAKER_TAG);
55
+ if (speakerMatch) {
56
+ speaker = speakerMatch[1].trim();
57
+ text = speakerMatch[2].trim();
58
+ }
59
+ else {
60
+ text = joinedText;
61
+ }
62
+ text = text.replace(HTML_TAGS, '').trim();
63
+ const entry = {
64
+ time: formatTimestamp(startTimestamp),
65
+ text,
66
+ };
67
+ if (endTimestamp) {
68
+ entry.endTime = formatTimestamp(endTimestamp);
69
+ }
70
+ if (speaker) {
71
+ entry.speaker = speaker;
72
+ }
73
+ return entry;
74
+ }
75
+ function formatTimestamp(vttTimestamp) {
76
+ const parts = vttTimestamp.split(':');
77
+ const hours = parseInt(parts[0], 10);
78
+ const minutes = parseInt(parts[1], 10);
79
+ const seconds = Math.floor(parseFloat(parts[2]));
80
+ if (hours > 0) {
81
+ return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
82
+ }
83
+ return `${minutes}:${String(seconds).padStart(2, '0')}`;
84
+ }
85
+ //# sourceMappingURL=vtt-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vtt-parser.js","sourceRoot":"","sources":["../../src/utils/vtt-parser.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "mcp-video-analyzer",
3
+ "version": "0.2.0",
4
+ "description": "MCP server for video analysis — extracts transcripts, key frames, OCR text, and metadata from video URLs. Supports Loom and direct video files.",
5
+ "author": "guimatheus92",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/guimatheus92/mcp-video-analyzer#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/guimatheus92/mcp-video-analyzer.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/guimatheus92/mcp-video-analyzer/issues"
14
+ },
15
+ "bin": {
16
+ "mcp-video-analyzer": "./dist/index.js"
17
+ },
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "type": "module",
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "prepare": "npm run build",
27
+ "dev": "npx fastmcp dev src/index.ts",
28
+ "inspect": "npx fastmcp inspect src/index.ts",
29
+ "lint": "eslint src/",
30
+ "lint:fix": "eslint src/ --fix",
31
+ "format": "prettier --write \"src/**/*.ts\" \"*.config.*\" \"*.json\"",
32
+ "format:check": "prettier --check \"src/**/*.ts\" \"*.config.*\"",
33
+ "typecheck": "tsc --noEmit",
34
+ "knip": "knip",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest",
37
+ "test:coverage": "vitest run --coverage",
38
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
39
+ "check": "npm run format:check && npm run lint && npm run typecheck && npm run knip && npm run test",
40
+ "prepublishOnly": "npm run check && npm run build"
41
+ },
42
+ "keywords": [
43
+ "mcp",
44
+ "model-context-protocol",
45
+ "video",
46
+ "video-analysis",
47
+ "loom",
48
+ "transcript",
49
+ "frames",
50
+ "ocr",
51
+ "screen-recording",
52
+ "claude",
53
+ "ai"
54
+ ],
55
+ "engines": {
56
+ "node": ">=18"
57
+ },
58
+ "dependencies": {
59
+ "cheerio": "^1.0.0",
60
+ "fastmcp": "^1.0.0",
61
+ "ffmpeg-static": "^5.2.0",
62
+ "puppeteer-core": "^24.38.0",
63
+ "sharp": "^0.33.0",
64
+ "tesseract.js": "^7.0.0",
65
+ "zod": "^3.23.8"
66
+ },
67
+ "devDependencies": {
68
+ "@eslint/js": "^10.0.1",
69
+ "@types/node": "^22.10.0",
70
+ "@vitest/coverage-v8": "^4.0.18",
71
+ "eslint": "^10.0.3",
72
+ "knip": "^5.86.0",
73
+ "prettier": "^3.8.1",
74
+ "typescript": "^5.7.2",
75
+ "typescript-eslint": "^8.56.1",
76
+ "vitest": "^4.0.18"
77
+ }
78
+ }