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. reused describes the pipeline cache, NOT network activity: a new URL is downloaded to compare bytes even when reused=true; a local rebuild can have reused=false with no download. Read origin.network and origin.reused_url_mapping for the download outcome. An indexed job with an unreadable manifest can rebuild from its verified local source; manifest_recovery_note explains recovery. list_jobs omits unreadable manifests. Lost provider metadata stays unknown unless refresh=true. 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 uses usable container creation metadata or recorded_at; download mtime is never used. 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. Jobs with unreadable manifests are omitted; an empty list does not prove there are no stored sources. process_media or process_url may rebuild such a job and report manifest_recovery_note. 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 stage of the pipeline: ingestion (process_url vs process_media), browsing (list_jobs), retrieval (get_transcript, get_frames, extract_frame, get_moment), search, and annotation (label_speakers). The descriptions include explicit 'When NOT to use' sections and anti-examples that sharply delineate boundaries, e.g. get_frames (stored keyframes) vs extract_frame (exact native-resolution frame) vs get_moment (bundled evidence).
Names are uniformly snake_case and follow a predictable verb_noun pattern (process_url, process_media, list_jobs, extract_frame, get_frames, get_moment, get_transcript, label_speakers). The single tool 'search' is a minor stylistic deviation but remains natural and readable within the set.
Nine tools is well-scoped for a media ingestion and analysis server. Each tool earns its place by covering a required capability without redundancy or bloat.
The surface covers ingestion (local and URL), listing, transcript retrieval, frame access, evidence bundling, lexical search, and speaker labeling—a complete workflow. The one notable gap is a delete/GC tool for managing stored jobs; the server only mentions a CLI `talkthrough-mcp gc`, leaving no in-band way to remove recordings.