Skip to main content
Glama
lawriec
by lawriec
README.md
# mcp-video-reader

An MCP server that gives Claude full access to ffmpeg — extract frames, convert formats, trim and join clips, manipulate audio, apply filters, and handle subtitles. No external API key required.

## Prerequisites

**ffmpeg** must be installed and available on your PATH.

- **Windows:** `winget install ffmpeg` or `choco install ffmpeg`
- **macOS:** `brew install ffmpeg`
- **Ubuntu/Debian:** `sudo apt install ffmpeg`

## Installation

### npx (no install)

```bash
npx mcp-video-reader
```

### npm global

```bash
npm install -g mcp-video-reader
```

### From GitHub directly

```bash
npx github:lawriec/mcp-video-reader
```

### Local dev

```bash
git clone https://github.com/lawriec/mcp-video-reader.git
cd mcp-video-reader
npm install
npm run build
```

## Configuration

### Claude Desktop

Add to your Claude Desktop config (`claude_desktop_config.json`):

**Via npx (recommended):**

```json
{
  "mcpServers": {
    "video-reader": {
      "command": "npx",
      "args": ["-y", "mcp-video-reader"]
    }
  }
}
```

**Via GitHub (before npm publish):**

```json
{
  "mcpServers": {
    "video-reader": {
      "command": "npx",
      "args": ["-y", "github:lawriec/mcp-video-reader"]
    }
  }
}
```

**Local build:**

```json
{
  "mcpServers": {
    "video-reader": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-video-reader/build/index.js"]
    }
  }
}
```

### Claude Code

```bash
claude mcp add video-reader -- npx -y mcp-video-reader
```

## Tools

### Inspection

#### `get_video_info`

Get metadata about a video file.

**Input:**
- `file_path` (string, required) — Absolute path to the video file

**Output:** Text with duration, resolution, fps, codecs, bitrate, file size.

---

#### `extract_frames`

Extract evenly-spaced frames from a video file as JPEG images.

**Input:**
- `file_path` (string, required) — Absolute path to the video file
- `num_frames` (number, optional) — Number of frames to extract, 1–20 (default: 10)
- `start_time` (number, optional) — Start time in seconds (default: beginning)
- `end_time` (number, optional) — End time in seconds (default: end of video)

**Output:** Text summary + base64 JPEG images of each frame.

---

#### `extract_frame_at_timestamp`

Extract a single frame at a specific timestamp.

**Input:**
- `file_path` (string, required) — Absolute path to the video file
- `timestamp` (number, required) — Timestamp in seconds

**Output:** Text label + single base64 JPEG image.

---

### Convert

#### `convert_video`

Convert a video to a different container format and/or codec. Audio is copied without re-encoding unless the container requires otherwise.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `output_format` (string, required) — Container format: `mp4`, `mkv`, `webm`, `avi`, or `mov`
- `codec` (string, optional) — Video codec: `h264`, `h265`, `vp9`, `av1`, or `copy` (re-container without re-encode)
- `crf` (number, optional) — Constant Rate Factor for quality (0–63; lower = better). Typical: 18–28 for h264/h265, 28–40 for vp9
- `bitrate` (string, optional) — Target video bitrate, e.g. `2000k` or `5M`. Cannot be combined with `crf`
- `output_path` (string, optional) — Defaults to same directory as input with `_converted` suffix

**Output:** Text confirming the output file path.

---

### Trim / Edit

#### `trim_video`

Cut a clip from a video by start and end time. Re-muxes without re-encoding (lossless, fast).

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `start_time` (number, required) — Start time in seconds
- `end_time` (number, required) — End time in seconds
- `output_path` (string, optional) — Defaults to same directory with `_trimmed` suffix

**Output:** Text confirming the output file path.

---

#### `concat_videos`

Join multiple video files into one in the order provided, without re-encoding (lossless, fast). All inputs must share the same codec and resolution.

**Input:**
- `file_paths` (array of strings, required) — Ordered list of absolute paths (minimum 2)
- `output_path` (string, optional) — Defaults to same directory as the first file with `_concat` suffix
- `output_format` (string, optional) — `mp4`, `mkv`, `webm`, `avi`, or `mov`. Defaults to the format of the first input file

**Output:** Text confirming the output file path.

---

#### `split_video`

Split a video into equal-duration segments without re-encoding. Output files are named `<basename>_part_000.<ext>`, `<basename>_part_001.<ext>`, etc.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `segment_duration` (number, required) — Duration of each segment in seconds
- `output_dir` (string, optional) — Directory to write segments to. Defaults to same directory as input
- `output_format` (string, optional) — `mp4`, `mkv`, `webm`, `avi`, or `mov`. Defaults to same format as input

**Output:** Text listing all created segment file paths.

---

### Audio

#### `extract_audio`

Extract the audio track from a video and save it as a standalone audio file.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `output_format` (string, optional) — Audio format: `mp3`, `aac`, `flac`, `wav`, or `ogg` (default: `mp3`)
- `output_path` (string, optional) — Defaults to same directory with `_audio` suffix

**Output:** Text confirming the output file path.

---

#### `strip_audio`

Remove the audio track from a video, producing a silent video. The video stream is copied without re-encoding.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `output_path` (string, optional) — Defaults to same directory with `_noaudio` suffix

**Output:** Text confirming the output file path.

---

#### `adjust_volume`

Change the audio volume of a video. The video stream is copied without re-encoding.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `volume` (number, required) — Volume multiplier: `1.0` = original, `2.0` = double, `0.5` = half. Must be ≥ 0
- `output_path` (string, optional) — Defaults to same directory with `_volume` suffix

**Output:** Text confirming the output file path.

---

### Filters

#### `resize_video`

Resize a video to new dimensions. Omit one dimension to scale proportionally and preserve aspect ratio.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `width` (number, optional) — Output width in pixels
- `height` (number, optional) — Output height in pixels
- `output_path` (string, optional) — Defaults to same directory with `_resized` suffix

At least one of `width` or `height` must be provided.

**Output:** Text confirming the output file path.

---

#### `crop_video`

Crop a video to a rectangular region.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `width` (number, required) — Width of the crop region in pixels
- `height` (number, required) — Height of the crop region in pixels
- `x` (number, optional) — X offset of the top-left corner (default: 0)
- `y` (number, optional) — Y offset of the top-left corner (default: 0)
- `output_path` (string, optional) — Defaults to same directory with `_cropped` suffix

**Output:** Text confirming the output file path.

---

#### `rotate_video`

Rotate a video 90, 180, or 270 degrees clockwise.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `rotation` (number, required) — Degrees clockwise: `90`, `180`, or `270`
- `output_path` (string, optional) — Defaults to same directory with `_rotatedN` suffix

**Output:** Text confirming the output file path.

---

#### `adjust_video`

Adjust brightness, contrast, and/or saturation using the ffmpeg `eq` filter.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `brightness` (number, optional) — Range: `-1.0` to `1.0`. Default: `0` (no change)
- `contrast` (number, optional) — Range: `-1000` to `1000`. Default: `1` (no change)
- `saturation` (number, optional) — Range: `0` (grayscale) to `3.0`. Default: `1` (no change)
- `output_path` (string, optional) — Defaults to same directory with `_adjusted` suffix

**Output:** Text confirming the output file path.

---

#### `add_text_overlay`

Burn a text string onto every frame of a video using the ffmpeg `drawtext` filter.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `text` (string, required) — Text to overlay (max 500 characters)
- `x` (number, optional) — X position in pixels from the left edge (default: 10)
- `y` (number, optional) — Y position in pixels from the top edge (default: 10)
- `font_size` (number, optional) — Font size in pixels (default: 24)
- `color` (string, optional) — Color name (e.g. `white`, `red`) or hex (e.g. `#FF0000`). Default: `white`
- `output_path` (string, optional) — Defaults to same directory with `_text` suffix

**Output:** Text confirming the output file path.

---

#### `change_speed`

Speed up or slow down a video. Both video and audio are adjusted. Values above `1.0` speed up; values below `1.0` slow down.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `speed` (number, required) — Speed multiplier, range `0.01`–`100`. E.g. `2.0` = twice as fast, `0.5` = half speed
- `output_path` (string, optional) — Defaults to same directory with `_Nx` suffix

**Output:** Text confirming the output file path.

---

#### `generate_thumbnail_grid`

Generate a contact-sheet JPEG with evenly-spaced thumbnail frames arranged in a grid. Useful for quickly skimming a video's content.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `columns` (number, optional) — Number of columns in the grid, 1–20 (default: 4)
- `rows` (number, optional) — Number of rows in the grid, 1–20 (default: 3)
- `output_path` (string, optional) — Defaults to same directory with `_grid.jpg` suffix

**Output:** Text confirming the path of the generated JPEG contact sheet.

---

### Subtitles

#### `extract_subtitles`

Extract a subtitle track from a video file and save it as a standalone subtitle file.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `stream_index` (number, optional) — Zero-based index of the subtitle stream to extract (default: `0`)
- `output_format` (string, optional) — Subtitle format: `srt`, `vtt`, or `ass` (default: `srt`)
- `output_path` (string, optional) — Defaults to same directory with `_subtitles` suffix

**Output:** Text confirming the output file path.

---

#### `embed_subtitles`

Embed a subtitle file as a soft (selectable) subtitle track inside the video container. The subtitles are not burned into the video frames. Supports `mp4`, `mkv`, and `mov` output.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `subtitle_path` (string, required) — Absolute path to the subtitle file (`.srt`, `.vtt`, or `.ass`)
- `output_path` (string, optional) — Defaults to same directory with `_subtitled` suffix
- `output_format` (string, optional) — `mp4`, `mkv`, or `mov`. Defaults to same format as input

**Output:** Text confirming the output file path.

---

#### `burn_subtitles`

Permanently burn (hard-code) subtitles into the video frames. Subtitles will always be visible regardless of player settings. Requires re-encoding the video stream.

**Input:**
- `file_path` (string, required) — Absolute path to the input video file
- `subtitle_path` (string, required) — Absolute path to the subtitle file (`.srt`, `.vtt`, or `.ass`)
- `output_path` (string, optional) — Defaults to same directory with `_burned` suffix

**Output:** Text confirming the output file path.

---

## Environment Variables

- `FFMPEG_PATH` — Override path to the ffmpeg executable
- `FFPROBE_PATH` — Override path to the ffprobe executable

## License

MIT

TDQS

A3.9/5.0

Scored across 20 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: extraction, conversion, editing, filtering, and subtitles are all separated. Even similar-sounding tools like extract_audio and strip_audio are unambiguous due to their specific descriptions.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern in snake_case, e.g., extract_audio, trim_video, adjust_volume. Compound names like generate_thumbnail_grid and extract_frame_at_timestamp maintain the pattern without deviation.

Tool Count4/5

20 tools is on the higher end but appropriate for a comprehensive video processing server. Each tool adds distinct value, though the server name suggests a reader scope, making the editing tools slightly broad.

Completeness4/5

The tool set covers core video operations: metadata, frame/audio/subtitle extraction, conversion, trimming, splitting, concatenation, and various filters. Missing advanced capabilities like audio replacement or stabilization, but no critical dead ends for common workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues