talkthrough-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| TALKTHROUGH_OCR | No | Set 'off' to skip OCR | on |
| TALKTHROUGH_HOME | No | Job store root directory | ~/.talkthrough |
| TALKTHROUGH_OCR_LANG | No | Recognition script for on-screen text: a language code or RapidOCR pack name | Latin+Chinese |
| TALKTHROUGH_MAX_FRAMES | No | Keyframe cap per job | 600 |
| TALKTHROUGH_OCR_PARAMS | No | Advanced: JSON object of raw RapidOCR params merged over the derived ones | |
| TALKTHROUGH_MAX_SECONDS | No | Max media duration in seconds | 7200 |
| TALKTHROUGH_WHISPER_MODEL | No | Default whisper model (tiny/base/small/medium/large-v3/large-v3-turbo); the model tool param overrides per call | small |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| process_mediaA | Ingest a LOCAL video or audio file and make it queryable: validates the file, transcribes speech locally (whisper), extracts scene-change keyframes, OCRs on-screen text, resolves the wall-clock start time, and (opt-in) labels who said what via local speaker diarization. Returns a compact summary (job_id, media info, wall_clock, transcript preview, speaker roster when diarized) — full data stays on disk and is served lazily by the other tools. Idempotent by content hash: re-calling on an already-processed file returns instantly. For MULTI-PERSON recordings (meetings, interviews, calls) diarize=true is part of a proper analysis — pass it even when the user only asks for a summary. num_speakers is a target the clusterer may not reach, not a constraint — the payload says when a re-run changed nothing (labels_changed). If an amend changes the labels, verified names become pending-review evidence rather than active identities, with old-roster anchors for re-checking. Current pending labels can be confirmed/replaced/removed; stale labels can only be removed with an explicit null patch. Full force reprocessing of a job with saved or pending identities requires diarize=true and preserves every old identity as pending review against the rebuilt roster; without diarization it refuses before changing the stored job. When NOT to use: to re-fetch data you already processed (use the retrieval tools), or for URLs — local file paths only; a public video/audio URL goes to process_url. Examples:
|
| process_urlA | Download ONE public video/audio URL once (this is the only tool that uses the network), then run the same LOCAL pipeline as process_media: transcript, keyframes, OCR, wall-clock, optional diarization. Supported: direct https:// links to a media file (mp4/mov/webm/mkv/ogv/m4a/mp3/wav/ogg/flac), one public YouTube video (watch, youtu.be, shorts, a completed live), and any public video PAGE yt-dlp can read — Instagram (public reels/posts), TikTok, Wikimedia Commons, pages with an HTML5/HLS player, other sites as far as their yt-dlp extractor works anonymously (Vimeo does not). Not supported: playlists, channels, active live streams, private/members-only/age-restricted/DRM videos, cookies/logins; sites that hide a video behind a login or a bot wall fail with a clear reason. The downloaded source is kept inside the job, so extract_frame works later without network; the raw URL is never stored (only a hash, the provider id/host and a bounded title). A repeat call on the same URL serves the stored job without touching the network unless refresh=true. Job ids stay content hashes: the same video from two URLs is one job. YouTube and other pages need the optional [url] extra. The provider's upload date is NOT the recording start: wall_clock stays null unless recorded_at is passed. When NOT to use: for local files (process_media), or to re-fetch data you already processed (use the retrieval tools). Examples:
|
| get_transcriptA | Retrieve the transcript of a processed job, lazily and paginated. Formats: "segments" (default — seq, t_ms, t_wall when known, speaker when diarized, text), "text" (plain prose; "S1:" prefixes at speaker changes), "srt" (subtitles, speaker-prefixed cues). Diarized jobs also return the roster, attribution_precision, saved speaker_name values, raw OCR name_candidates, and bounded pending-review names plus old-roster context after a relabel. Pre-0.3.1 video jobs may return name_candidates_note because their flat OCR is readable but less useful for hints. Pending names are evidence to re-check, never active identities. A stale pending label can only be removed with label_speakers(..., labels={"Sx":null}). Raw S labels remain canonical. Responses are capped (~8k tokens): when truncated=true, continue from the returned next_start_ms. When NOT to use: to find one keyword (use search) or to inspect one moment with visuals (use get_moment). Examples:
|
| get_framesA | Fetch stored keyframe images (JPEG, <=1568px wide) as MCP image content: the frames nearest to at_ms, OR unique frames across [start_ms, end_ms] evenly thinned to max_frames. Serves unique frames by default (near-duplicates from static scenes are filtered); hard cap 6 images per call. When NOT to use: exact instants between keyframes or native-resolution detail (use extract_frame), or finding on-screen text (use search — OCR text is indexed). Examples:
|
| get_momentA | The "one remark" evidence bundle: transcript slice + up to 3 unique frames + their OCR text + the wall-clock range for [start_ms, end_ms], in a single call. This is the workhorse for triage: one call per finding gives you the quote, the screenshot, and the on-screen text. When NOT to use: broad exploration (get_transcript / get_frames) or keyword lookup (search). Examples:
|
| searchA | Case-insensitive word search across BOTH transcript segments and frame OCR text. The default match_mode="all_words" requires EVERY query word as a substring; match_mode="any_word" requires at least one (ё and е are interchangeable). Hits carry source (transcript|ocr), t_ms, t_wall when known, the matched text, and the nearest frame position — everything needed to jump straight to evidence. Optional speaker accepts a raw label ("S2") or saved name and narrows to that voice's transcript hits. Duplicate saved names search all matching labels honestly. No embeddings. When NOT to use: fuzzy/semantic questions ("anything about performance?") — page get_transcript and read; regex is not supported. Examples:
|
| label_speakersA | Persist VERIFIED human-readable names for anonymous S1/S2/… labels on one diarized job.
|
| extract_frameA | Re-extract ONE frame at an exact timestamp from the ORIGINAL source video at native resolution, with an optional crop {x, y, w, h} in source pixels. Use when the stored keyframes miss the instant (they capture scene changes + a 1 fps floor) or when you need full-resolution detail. Slower than get_frames — it decodes the source file, which must still exist at its recorded path (URL jobs keep their downloaded source inside the job, no network). When NOT to use: normal browsing — get_frames serves stored keyframes instantly without touching the source. Examples:
|
| list_jobsA | List processed recordings, newest first: job_id, source filename, duration, created, wall-clock start, segment/frame counts. The store is content-addressed — the same file maps to the same job even after renames or moves, and jobs persist across sessions and machines restarts. When NOT to use: as a health check or before every call — job_ids are stable, remember them. Examples:
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| bug | Turn one screen recording of a bug into an evidence-backed GitHub issue draft (quote, frames, OCR identifiers, wall-clock; silent recordings work too). |
| triage-recording | Turn a narrated screencast into precise, evidence-backed findings JSON (bug / feature / question routing with frame evidence). |
| spec-from-workshop | Turn a recorded workshop or design walkthrough into a structured spec with quoted decisions and open questions. |
| backlog-from-demo | Turn a recorded product demo into a prioritized backlog with timestamped evidence. |
| meeting-actions | Turn a recorded meeting (audio is enough) into action items, decisions, and open questions with timestamps. |
| correlate-with-logs | Walk a recording's remarks against system logs using wall-clock timestamps. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 9 tools
Each tool targets a distinct resource/action: local vs URL ingestion, transcript retrieval vs keyword search, stored keyframes vs exact re-extraction vs combined evidence bundles. The descriptions include explicit anti-examples that reinforce the boundaries, making misselection unlikely.
Eight of nine tools follow a clear verb_noun pattern: process_media, process_url, get_transcript, get_frames, get_moment, list_jobs, label_speakers, extract_frame. The single bare verb 'search' is a minor deviation, but the overall naming remains predictable and readable.
Nine tools is well-scoped for a media-analysis server. Each tool maps to a distinct phase of the workflow — ingestion, listing, retrieval, searching, evidence gathering, and speaker identity management — with no redundant additions.
The ingest/read/update side is well covered: process_media and process_url create jobs, list_jobs/get_transcript/get_frames/get_moment/search read them, and label_speakers plus force reprocessing update them. There is no MCP-level job deletion tool (gc is external/CLI-only) and no standalone OCR-only dump, which are minor workaround-level gaps rather than core analysis failures.