video-transcriber-mcp 0.7.0

High-performance video transcription MCP server using whisper.cpp for faster transcription
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
version: '3'

# Auto-load secrets/config from .env (gitignored) and .env.local (per-machine override).
# Copy .env.example → .env and fill in your keys to get started.
dotenv: ['.env', '.env.local']

vars:
  BINARY: ./target/release/video-transcriber-mcp
  BINARY_DEV: ./target/debug/video-transcriber-mcp
  TEST_VIDEO: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  MODELS_DIR: "{{.HOME}}/.cache/video-transcriber-mcp/models"

tasks:
  # Build tasks
  build:
    desc: Build the project in release mode (optimized)
    cmds:
      - cargo build --release
    sources:
      - src/**/*.rs
      - Cargo.toml
    generates:
      - target/release/video-transcriber-mcp

  build:dev:
    desc: Build the project in dev mode (fast compilation)
    cmds:
      - cargo build

  clean:
    desc: Clean build artifacts
    cmds:
      - cargo clean
      - rm -rf target/

  # Check and lint tasks
  check:
    desc: Check if the project compiles
    cmds:
      - cargo check

  fmt:
    desc: Format code
    cmds:
      - cargo fmt

  lint:
    desc: Run clippy linter
    cmds:
      - cargo clippy -- -D warnings

  fix:
    desc: Auto-fix linting issues
    cmds:
      - cargo clippy --fix --allow-dirty
      - cargo fmt

  # Model management
  download:base:
    desc: Download base Whisper model (recommended)
    cmds:
      - bash scripts/download-models.sh base

  download:all:
    desc: Download all Whisper models
    cmds:
      - bash scripts/download-models.sh all

  download:tiny:
    desc: Download tiny model (fastest)
    cmds:
      - bash scripts/download-models.sh tiny

  download:small:
    desc: Download small model (balanced)
    cmds:
      - bash scripts/download-models.sh small

  download:medium:
    desc: Download medium model (high accuracy)
    cmds:
      - bash scripts/download-models.sh medium

  download:large:
    desc: Download large model (best accuracy)
    cmds:
      - bash scripts/download-models.sh large

  models:status:
    desc: Check which models are downloaded
    cmds:
      - ls -lh {{.MODELS_DIR}}/*.bin 2>/dev/null || echo "No models found. Run 'task download:base' to download."

  # Testing tasks
  test:quick:
    desc: Quick test with a short video (requires base model)
    deps: [build]
    cmds:
      - |
        echo "🎬 Testing with short video..."
        {{.BINARY}} --url "{{.TEST_VIDEO}}" --model base
    preconditions:
      - sh: test -f {{.MODELS_DIR}}/ggml-base.bin
        msg: "Base model not found. Run 'task download:base' first."

  test:local:
    desc: Test with a local video file
    deps: [build]
    cmds:
      - |
        if [ -z "{{.VIDEO_PATH}}" ]; then
          echo "❌ Please provide VIDEO_PATH: task test:local VIDEO_PATH=/path/to/video.mp4"
          exit 1
        fi
        {{.BINARY}} --url "{{.VIDEO_PATH}}" --model base
    vars:
      VIDEO_PATH: '{{.VIDEO_PATH | default ""}}'

  test:url:
    desc: Test with a custom URL
    deps: [build]
    cmds:
      - |
        if [ -z "{{.VIDEO_URL}}" ]; then
          echo "❌ Please provide VIDEO_URL: task test:url VIDEO_URL=https://..."
          exit 1
        fi
        {{.BINARY}} --url "{{.VIDEO_URL}}" --model base
    vars:
      VIDEO_URL: '{{.VIDEO_URL | default ""}}'

  test:all-models:
    desc: Test transcription with all available models
    deps: [build]
    cmds:
      - |
        echo "🎯 Testing all available models..."
        for model in tiny base small medium large; do
          if [ -f "{{.MODELS_DIR}}/ggml-${model}.bin" ]; then
            echo "Testing with ${model} model..."
            time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model ${model}
            echo "---"
          fi
        done

  # Benchmark tasks
  benchmark:
    desc: Run benchmark with timing
    deps: [build]
    cmds:
      - |
        echo "⏱️  Running benchmark..."
        time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model base

  benchmark:compare:
    desc: Compare performance across models
    deps: [build]
    cmds:
      - |
        echo "📊 Benchmarking different models..."
        echo "Video: {{.TEST_VIDEO}}"
        echo ""

        for model in tiny base small; do
          if [ -f "{{.MODELS_DIR}}/ggml-${model}.bin" ]; then
            echo "=== Model: ${model} ==="
            time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model ${model}
            echo ""
          fi
        done

  benchmark:vs-typescript:
    desc: Compare with TypeScript version
    cmds:
      - |
        echo "🏁 Rust vs TypeScript Benchmark"
        echo "================================"
        echo ""

        # Rust version
        echo "🦀 Rust Version (video-transcriber-mcp):"
        cd {{.ROOT_DIR}}
        time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model base

        echo ""
        echo "---"
        echo ""

        # TypeScript version
        echo "📘 TypeScript Version (video-transcriber-mcp):"
        cd ../video-transcriber
        time npm run start -- "{{.TEST_VIDEO}}"

  # Dependencies check
  deps:check:
    desc: Check if all required dependencies are installed
    cmds:
      - |
        echo "🔍 Checking dependencies..."
        echo ""

        # Check Rust
        if command -v rustc &> /dev/null; then
          echo "✅ Rust: $(rustc --version)"
        else
          echo "❌ Rust: NOT INSTALLED"
        fi

        # Check yt-dlp
        if command -v yt-dlp &> /dev/null; then
          echo "✅ yt-dlp: $(yt-dlp --version)"
        else
          echo "❌ yt-dlp: NOT INSTALLED (run: brew install yt-dlp)"
        fi

        # Check ffmpeg
        if command -v ffmpeg &> /dev/null; then
          echo "✅ ffmpeg: $(ffmpeg -version | head -1)"
        else
          echo "❌ ffmpeg: NOT INSTALLED (run: brew install ffmpeg)"
        fi

        echo ""
        echo "📦 Whisper Models:"
        ls -lh {{.MODELS_DIR}}/*.bin 2>/dev/null || echo "  ⚠️  No models found (run: task download:base)"

  deps:install:
    desc: Install all required dependencies (macOS)
    cmds:
      - |
        echo "📥 Installing dependencies..."

        if ! command -v yt-dlp &> /dev/null; then
          echo "Installing yt-dlp..."
          brew install yt-dlp
        fi

        if ! command -v ffmpeg &> /dev/null; then
          echo "Installing ffmpeg..."
          brew install ffmpeg
        fi

        echo "✅ All dependencies installed!"
        task deps:check

  # Development tasks
  dev:
    desc: Run in development mode (for testing changes)
    cmds:
      - cargo run -- --url "{{.TEST_VIDEO}}" --model base

  watch:
    desc: Watch for changes and rebuild
    cmds:
      - cargo watch -x check -x test

  run:
    desc: Run the binary directly
    deps: [build]
    cmds:
      - |
        if [ -z "{{.ARGS}}" ]; then
          echo "Usage: task run ARGS='--url VIDEO_URL --model base'"
          exit 1
        fi
        {{.BINARY}} {{.ARGS}}
    vars:
      ARGS: '{{.ARGS | default ""}}'

  # Setup tasks
  setup:
    desc: Complete project setup (build + download base model)
    cmds:
      - task: build
      - task: download:base
      - task: deps:check
      - |
        echo ""
        echo "🎉 Setup complete! Try: task test:quick"

  setup:full:
    desc: Complete setup with all models
    cmds:
      - task: build
      - task: download:all
      - task: deps:check

  # Utility tasks
  clean:models:
    desc: Delete all downloaded models
    cmds:
      - rm -rf {{.MODELS_DIR}}/*.bin
      - echo "🗑️  All models deleted"

  clean:outputs:
    desc: Delete all transcription outputs
    cmds:
      - rm -rf ~/Downloads/video-transcripts/*
      - echo "🗑️  All transcripts deleted"

  size:
    desc: Show binary size
    deps: [build]
    cmds:
      - |
        echo "📦 Binary Size:"
        ls -lh {{.BINARY}}
        echo ""
        echo "📊 Stripped size: $(du -h {{.BINARY}} | cut -f1)"

  info:
    desc: Show project information
    cmds:
      - |
        echo "🚀 Video Transcriber RS"
        echo "======================"
        echo ""
        echo "📂 Project: {{.ROOT_DIR}}"
        echo "🔨 Binary: {{.BINARY}}"
        echo "📦 Models: {{.MODELS_DIR}}"
        echo "📝 Outputs: ~/Downloads/video-transcripts/"
        echo ""
        task size
        echo ""
        task deps:check

  # Release tasks
  release:build:
    desc: Build optimized release binary
    cmds:
      - cargo build --release --locked
      - strip {{.BINARY}} 2>/dev/null || true
      - |
        echo "✅ Release build complete!"
        task size

  release:check:
    desc: Pre-release checks (fmt, lint, test, build)
    cmds:
      - task: fmt
      - task: lint
      - task: build
      - echo "✅ All checks passed! Ready for release."

  release:tag:
    desc: "Create and push a release tag - usage: task release:tag VERSION=0.1.1"
    cmds:
      - |
        if [ -z "{{.VERSION}}" ]; then
          echo "❌ Please provide VERSION: task release:tag VERSION=0.1.1"
          exit 1
        fi
        echo "🏷️  Creating release tag v{{.VERSION}}..."
        git tag -a v{{.VERSION}} -m "Release v{{.VERSION}}"
        git push origin v{{.VERSION}}
        echo "✅ Tag v{{.VERSION}} pushed! Check GitHub Actions for build progress."
    vars:
      VERSION: '{{.VERSION | default ""}}'

  release:
    desc: "Full release workflow - usage: task release VERSION=0.1.1"
    cmds:
      - |
        if [ -z "{{.VERSION}}" ]; then
          echo "❌ Please provide VERSION: task release VERSION=0.1.1"
          exit 1
        fi
        echo "🚀 Starting release v{{.VERSION}}..."
      - task: release:check
      - |
        echo ""
        echo "📝 Please update version in Cargo.toml and CHANGELOG.md if needed"
        echo "Press Enter to continue or Ctrl+C to abort..."
        read
      - task: "release:tag"
        vars:
          VERSION: '{{.VERSION}}'
    vars:
      VERSION: '{{.VERSION | default ""}}'

  release:delete:
    desc: "Delete a release tag - usage: task release:delete VERSION=0.1.1"
    cmds:
      - |
        if [ -z "{{.VERSION}}" ]; then
          echo "❌ Please provide VERSION: task release:delete VERSION=0.1.1"
          exit 1
        fi
        echo "⚠️  Deleting tag v{{.VERSION}}..."
        git tag -d v{{.VERSION}}
        git push origin :refs/tags/v{{.VERSION}}
        echo "✅ Tag v{{.VERSION}} deleted"
    vars:
      VERSION: '{{.VERSION | default ""}}'
  
  release:cargo:
    desc: "Release to crates.io"
    cmds:
      - cargo publish # --dry-run

  release:arm64:
    desc: "Build macOS ARM64 and upload to release - usage: task release:arm64 VERSION=0.3.0"
    cmds:
      - |
        if [ -z "{{.VERSION}}" ]; then
          echo "❌ Please provide VERSION: task release:arm64 VERSION=0.3.0"
          exit 1
        fi
        echo "🍎 Building macOS ARM64 binary..."
        rustup target add aarch64-apple-darwin
        cargo build --release --target aarch64-apple-darwin

        echo "📦 Packaging binary..."
        cd target/aarch64-apple-darwin/release
        tar czf ../../../video-transcriber-mcp-aarch64-apple-darwin.tar.gz video-transcriber-mcp
        cd ../../..

        echo "📤 Uploading to GitHub release v{{.VERSION}}..."
        gh release upload v{{.VERSION}} video-transcriber-mcp-aarch64-apple-darwin.tar.gz

        echo "✅ ARM64 binary uploaded to release v{{.VERSION}}!"
    vars:
      VERSION: '{{.VERSION | default ""}}'

  # Help and documentation
  help:
    desc: Show available tasks
    cmds:
      - task --list

  readme:
    desc: Open README in default viewer
    cmds:
      - |
        if command -v glow &> /dev/null; then
          glow README.md
        else
          cat README.md
        fi

  # ---------------------------------------------------------------------------
  # MCP Server tasks
  # ---------------------------------------------------------------------------
  mcp:test:
    desc: Test MCP server with stdio
    deps: [build]
    cmds:
      - |
        echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | {{.BINARY}}

  mcp:setup:
    desc: Show MCP setup instructions
    cmds:
      - |
        echo "📝 Add this to ~/.claude/settings.json:"
        echo ""
        echo '{'
        echo '  "mcpServers": {'
        echo '    "video-transcriber-mcp": {'
        echo '      "command": "{{.BINARY}}"'
        echo '    }'
        echo '  }'
        echo '}'
        echo ""
        echo "Then restart Claude Code!"