Skip to main content
Glama
README.md
# Reel

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
![Platform: macOS](https://img.shields.io/badge/platform-macOS%2026%2B-lightgrey.svg)
[![MCP server](https://img.shields.io/badge/MCP-server-orange.svg)](https://modelcontextprotocol.io)

Reel is an MCP server that lets your coding assistant transcribe any video on
your Mac, on-device, through utt.

Point it at any file ffmpeg can read (mp4, mov, mkv, webm, avi and so on). Reel
extracts the sound, splits long videos on silence so no sentence is cut in half,
has utt transcribe each piece on your Mac, and hands one stitched transcript back
to the assistant that asked.

## Part of utt

Reel is an extension for [utt](https://github.com/doublej/utt). It needs utt
installed and running, and it does no speech recognition of its own.

utt is one on-device speech-to-text app for the Mac. It runs Parakeet TDT v3 or
Whisper, and nothing leaves the Mac. Extensions bring that one engine, with the
model, vocabulary, replacements and cleanup you already chose, into the other
tools you use. You install utt once and add an extension for each tool:

| Extension | What it does |
|-----------|--------------|
| **Reel** (this repo) | Your coding assistant transcribes any video on your Mac through utt. |
| [Deckhand](https://github.com/doublej/deckhand) | Talk to Claude Code from your iPhone. utt transcribes on the Mac. |
| [utt-opencode](https://github.com/doublej/utt-opencode) | Dictate into OpenCode's prompt with utt. |
| [Raycast](https://github.com/doublej/utt/tree/main/raycast) | Start dictation, pick utt's microphone and reuse recent transcripts from Raycast. |

Download utt at [utt.jurrejan.com/download](https://utt.jurrejan.com/download).
All extensions are listed at [utt.jurrejan.com/extensions](https://utt.jurrejan.com/extensions).

## Requirements

- macOS 26 or later on Apple silicon
- [utt](https://utt.jurrejan.com/download), running
- [Bun](https://bun.sh/)
- ffmpeg and ffprobe: `brew install ffmpeg`

## Install

Reel is not on npm yet. Clone it and install its dependencies:

```bash
git clone https://github.com/doublej/reel.git
cd reel
bun install
just install-page   # draw Reel's settings page inside utt now
```

The settings page is also drawn the first time an assistant starts the server.
It shows the exact config for your checkout, ready to copy.

### Claude Code

```bash
claude mcp add --scope user reel -- bun /path/to/reel/src/index.ts
```

`just register` runs this command with the path of your checkout filled in.

### OpenCode

Add Reel to the `mcp` block of your `opencode.json`:

```json
{
  "mcp": {
    "reel": {
      "type": "local",
      "command": ["bun", "/path/to/reel/src/index.ts"],
      "enabled": true
    }
  }
}
```

### Other MCP clients

Any client that runs local stdio servers, such as Claude Desktop or Cursor, takes
the usual `mcpServers` entry:

```json
{
  "mcpServers": {
    "reel": {
      "command": "bun",
      "args": ["/path/to/reel/src/index.ts"]
    }
  }
}
```

If the client cannot find `bun` on its `PATH`, use the full path to it
(`which bun`).

## Tools

| Tool | What it does |
|------|--------------|
| `transcribe_video` | Takes `path`, and optionally `hints`, `timestamps` and `wait_seconds`. Returns the transcript, or a `job_id` when the work takes longer than you waited. |
| `transcribe_status` | Takes `job_id`, and optionally `wait_seconds`. Picks up a transcript that was still being worked on. |

`hints` are words a recogniser tends to get wrong, such as names, products and
repo names. Near misses are corrected to them.

`timestamps` adds a line per word under the transcript, as `start end word` in
seconds from the start of the video. That is enough to cut the video on a word.
The transcript then reads as the recogniser heard it, without utt's cleanup, so
the words and the times describe the same thing.

`wait_seconds` defaults to 120. Jobs are kept in memory, so a `job_id` does not
survive a restart of the session that started it.

## Settings, inside utt

Reel has its own page in utt, under Extensions:

- **Let assistants turn video into text**: the off switch. When it is off, every request is turned away.
- **Keep a list of the videos**: the list of transcribed videos the page shows.
- **Save the words beside the video**: leaves a `.txt` file next to each video.

## Privacy

Nothing is uploaded. Reel never opens a network connection. ffmpeg reads the
video on your Mac, and utt transcribes the audio on your Mac. Reel hands audio to
utt through files in utt's extensions folder, and keeps its own small history in
`~/Library/Application Support/dev.jurrejan.reel/`. utt's menu bar icon lights
up in Reel's colour while it works on Reel's audio, so transcription never
happens without you being able to see it.

## Development

```bash
bun install
just check        # Justfile format, file sizes, Biome lint, tsc, bun test
bun src/index.ts  # run the server on stdio
```

Bun runs `src/index.ts` directly. There is no build step. See
[CLAUDE.md](CLAUDE.md) for how the code is laid out and the rules it keeps.

## License

[MIT](LICENSE) © 2026 Jurre Jan