Skip to content

CueVideo answers with timestamp-level proof.

The default read is container metadata, streams, chapters, and embedded subtitles. Scenes are a separate request. A frame is a separate tool.

The difference

A caption is not a timestamp.
A subtitle cue you can seek to is.

Cue reads a local file with ffprobe and ffmpeg. The default profile is fast. It does not detect scenes, extract frames, or run speech recognition. quality adds scene boundaries. One frame is video_evidence.

What a guess says

“The pricing line is somewhere in the middle.” No stream, no cue, no warning if the file has no subtitles.

What Cue returns

container and streams from ffprobe · chapter start_ms when the file has chapters · subtitle start_ms / end_ms / text when a subtitle stream exists · a warning when it does not.

The subtitle object. Not a sample file. ​

When an embedded subtitle stream exists, each cue has this shape. The numbers and the words come from that file. This page does not invent them.

json
{
  "index": 0,
  "start_ms": 0,
  "end_ms": 0,
  "text": "cue text",
  "provenance": { "method": "ffmpeg_extract", "format": "srt" }
}

method is ffmpeg_extract and format is srt. index, start_ms, end_ms, and text are filled from the first subtitle stream. If that stream is missing, the read still returns the probe and adds the warning “No readable embedded subtitle stream was found.”

How it works

Three steps from a file to a timestamp

Step 1

Add it to your agent

One npx line. A stdio MCP server starts for Claude, Cursor, VS Code, Codex, or any other MCP client. No API key. ffmpeg and ffprobe must be on PATH.

Step 2

Read the timeline first

read_video with no profile is fast. search_video matches embedded subtitle text only. It does not run speech recognition.

Step 3

Open the moment

Use start_ms and the source hash. For a picture of that moment, call video_evidence with the timestamp. Do not describe a frame the tool did not return.

What you call

Name the work. The expensive pass stays off.

Scene detection decodes the file. It does not run unless you set profile to quality or set include_scenes. Nothing in the default read samples frames.

read_video

fast returns format, streams, chapters, and embedded subtitles. quality adds ffmpeg scene changes at threshold 0.4 unless you set another. A scene object is time_ms plus provenance.method ffmpeg_scene_filter.

search_video

Finds the query in embedded subtitle cues and returns start_ms and end_ms. No transcript is created for the search.

video_evidence

Named follow-up. op is render_frame, crop_frame, or ocr_frame at one timestamp. It is not part of read_video.

Limits

What the shipped server does not do.

fast
default profile. Container, streams, chapters, embedded subtitles. No scene pass.
0.4
default ffmpeg scene threshold, only after quality or include_scenes.
None
API key. No cloud speech recognition and no vision model on this path.
Empty
include_keyframes and include_transcript warn and return no frames and no transcript.

These are the switches in the shipped Rust server, not a speed benchmark. npx -y @sylphx/cue runs that server. A missing ffprobe is an error, not a guessed timeline.

Install ​

bash
npx -y @sylphx/cue
json
{
  "mcpServers": {
    "cue": { "command": "npx", "args": ["-y", "@sylphx/cue"] }
  }
}
bash
claude mcp add cue -- npx -y @sylphx/cue
bash
npx -y @sylphx/cue

Read the timeline. Seek the cue.

No API key. Scenes stay off until you ask. A frame is a tool you name.

Read the quickstart Star the repo

Cue · local-first agent tooling · MIT