{"name":"io.github.oxbshw/watch-skill","slug":"oxbshw-watch-skill","title":null,"description":"Watch video and live sessions, keep timestamped evidence, and verify an agent's own work.","url":"https://mcp.market/server/oxbshw-watch-skill","rating":null,"grade":"B","score":77,"certified":false,"status":"active","category":"ai","tags":["ai","media"],"presence":{"score":43,"stars":379,"forks":56,"downloads_week":null,"last_push_at":"2026-09-14T19:58:02.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/oxbshw/watch-skill","website":"https://github.com/oxbshw/watch-skill","version":"1.4.3","remotes":[],"packages":[{"registryType":"pypi","registryBaseUrl":"https://pypi.org","identifier":"watch-skill","version":"1.4.3","runtimeHint":"uvx","transport":{"type":"stdio"},"runtimeArguments":[{"description":"Pinned to the version this entry declares. Unpinned, uvx resolves the newest stable release, so a pre-release entry would advertise one version and start another.","value":"watch-skill[standard]==1.4.3","type":"named","name":"--from"}],"packageArguments":[{"description":"Starts the MCP server on stdio.","value":"serve","type":"positional","valueHint":"serve"}]}],"tools":[{"name":"aligned_evidence","description":"What EVERY stream observed around one moment of a live session.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyze_hook","description":"Creator mode: score the first N seconds of a watched video as a hook — attention trigger in the opening line, speech pacing, visual change rate, on-screen text — each with an actionable critique plus a combined 0-100 score and verdict (strong/promising/weak).","write_action":false,"price_micros":0,"input_schema":null},{"name":"ask_live","description":"Ask what is happening right now, or what happened earlier in a live session. Answers come with the media timestamps they came from.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ask_video","description":"ANY follow-up question about a video you (or anyone) already watched — ALWAYS prefer this over re-running watch_video: the self-healing answer engine retrieves from the persistent index, scores its own confidence, escalates (dense re-sampling, zoom-crop re-OCR, stronger model) when unsure, and states plainly when the video does not clearly show the answer — it never guesses. Responses are TEXT-FIR","write_action":false,"price_micros":0,"input_schema":null},{"name":"cancel_job","description":"Stop a durable background job.","write_action":true,"price_micros":0,"input_schema":null},{"name":"capture","description":"Record NEW footage when none exists yet — a live web page (headless browser session with optional goto/click/fill/scroll/wait script), `screen:` (full desktop), `window:<exact title>`, or adopt an existing video file. The recording is analyzed and indexed; returns video_id for ask_video. To record AND judge against pass criteria, use loop_start instead — capture alone never critiques.","write_action":false,"price_micros":0,"input_schema":null},{"name":"capture_capabilities","description":"What this machine can actually record, and how each answer was established. Check before attempting screen/window/camera capture — nothing here is reported available on the strength of a code path existing.","write_action":false,"price_micros":0,"input_schema":null},{"name":"check_source","description":"Whether an indexed video still matches what its source holds NOW, plus every revision recorded for it.","write_action":false,"price_micros":0,"input_schema":null},{"name":"doctor","description":"Run this when ANY other tool fails with a dependency/download error, or on first use. Checks AND self-heals: installs missing ffmpeg/yt-dlp, updates a stale yt-dlp, verifies disk space, GPU, and API keys. Each failing check includes a `fix` you can act on.","write_action":true,"price_micros":0,"input_schema":null},{"name":"execution_plan","description":"What a run would send and what it could cost, BEFORE it sends anything.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extract_bug_report","description":"QA mode: pinpoint WHERE an error appears in a watched screen recording — the timestamp, the frame, the exact on-screen error text (OCR), and the steps/narration that led up to it. Returns found=false when no error signal exists rather than guessing.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extract_chapters","description":"Segment an already-watched video into titled chapters with start/end timestamps (from scene changes + transcript topic shifts). Use for navigation, summaries per section, or building a table of contents. Deterministic — no extra model calls, answers straight from the index.","write_action":false,"price_micros":0,"input_schema":null},{"name":"fused_timeline","description":"A correlated account of a live session: what was seen, read and heard, joined into single happenings rather than three parallel logs.","write_action":false,"price_micros":0,"input_schema":null},{"name":"generate_viewer","description":"Render a SHAREABLE, self-contained HTML page for an analyzed video: timeline + key frames (inlined — works offline, zero external requests), the transcript, on-screen text, and every cached answer with the exact evidence the engine cited. Give the user the returned path; the file can be opened directly in any browser or sent to anyone as-is.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_evidence","description":"Read back a verification run's evidence bundle and attestation.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_live_status","description":"How a live session is doing: state, frames captured vs analyzed, dropped frames, queue depths, buffer size. Omit session_id to list every live session on this machine.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_moment","description":"Zoom into ONE SPECIFIC MOMENT of an indexed video — use when the user names a timestamp (\"what happens at 2:30?\") or when an ask_video hit needs more surrounding detail. Returns dense frames + transcript + OCR within `window` seconds around `timestamp` (SS, MM:SS, or HH:MM:SS). For a broad question about the whole video, use ask_video instead.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_status","description":"Check a background job started with watch_video(background=true). Returns state/stage/progress; when it succeeds it includes the video_id to use with ask_video. Poll every few seconds, not in a tight loop.","write_action":false,"price_micros":0,"input_schema":null},{"name":"library_overview","description":"What the video library knows: how many videos and hours are indexed, the note counts (entities/claims/chapters), the entities that recur across multiple videos, and the most recent additions. Use it to orient before library_synthesize, or when the user asks what has been watched.","write_action":false,"price_micros":0,"input_schema":null},{"name":"library_synthesize","description":"Answer a question from the WHOLE video library at once — use when no single video answers it (\"what did the meetings decide about X?\", \"which tutorials cover Y and do they agree?\"). Retrieves distilled notes across every indexed video, drills into real indexed evidence, and returns a synthesis where every finding carries a per-video timestamp citation. Says plainly when the library does not clearl","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_videos","description":"See what is already in the index (id, title, duration, source) — check here BEFORE watch_video when the video might have been analyzed in an earlier session; if it's listed, go straight to ask_video.","write_action":false,"price_micros":0,"input_schema":null},{"name":"loop_game","description":"START A GAME/SIMULATION LOOP to catch visual glitches or state failures in a running game or sim: optionally launches run_cmd, records gameplay from `target` (a canvas game URL, window:<title>, or screen:), and critiques the recording against your criteria (e.g. 'the score counter must never show negative numbers, no black flicker frames'). Fix the game code between iterations, then loop_iterate.","write_action":false,"price_micros":0,"input_schema":null},{"name":"loop_iterate","description":"CONTINUE THE LOOP — call this ONLY after you actually changed the code/ UI in response to loop_start's issues. Re-captures the same target with the same script, re-critiques, and diffs against the previous iteration (fixed / unchanged / new issues). Stops on pass, max_iterations, or no-progress; on pass it renders the before/after MP4+GIF proof.","write_action":false,"price_micros":0,"input_schema":null},{"name":"loop_monitor","description":"WATCH a folder of videos or a live target until a described condition appears (e.g. 'a demo error screen shows'), then return a structured event. Bounded by max_checks — it always terminates. Folder sources consume each video once; live targets (URL / screen: / window:) sample `sample_seconds` every `interval`. Events also land in events.jsonl under the monitor's loop dir so other tools can react.","write_action":false,"price_micros":0,"input_schema":null},{"name":"loop_start","description":"START THE LOOP when you built/changed something visual and need to VERIFY it actually looks right: records the target (URL / screen: / window:<title> / video file), watches the recording, and critiques it against your natural-language pass criteria with the strong vision model. Returns loop_id + structured issues with timestamps and suggested fixes. YOU apply the fixes in code, then call loop_iter","write_action":false,"price_micros":0,"input_schema":null},{"name":"loop_status","description":"Inspect a loop's persisted state (status, scores per iteration, artifacts).","write_action":false,"price_micros":0,"input_schema":null},{"name":"loop_video_gen","description":"START A VIDEO-GENERATION LOOP when you are generating a video (Manim, Remotion, ffmpeg, any command) and need to verify the render matches the spec: runs generator_cmd, watches the video it writes at `output`, and critiques it against the spec/pass_criteria. YOU edit the generator (scene code, prompt, args) between iterations, then call loop_iterate — the same iterate/diff/artifact machinery as th","write_action":false,"price_micros":0,"input_schema":null},{"name":"observe_live","description":"Read what has happened in a live session since your last cursor.","write_action":false,"price_micros":0,"input_schema":null},{"name":"report_mistake","description":"The answer to a video question turned out WRONG? Report it here with the correction — Watch Skill learns from it locally (nothing uploaded): the mistake is classified, stored as a lesson, injected into future similar questions, and where possible the original question is re-asked immediately to confirm the lesson works. Do this whenever the user corrects a video answer; it makes every later answer","write_action":false,"price_micros":0,"input_schema":null},{"name":"search_videos","description":"Find something across EVERY video ever watched, when you don't know which video contains it (\"which video mentioned X?\"). Hybrid keyword + semantic search; Arabic and other scripts are matched with proper normalization. Returns videos with timestamped evidence — follow up with ask_video or get_moment on a hit. For a question about one known video, use ask_video directly.","write_action":false,"price_micros":0,"input_schema":null},{"name":"start_live_watch","description":"Start WATCHING SOMETHING AS IT HAPPENS — a web page, a stream, or a local file replayed at real time. Events (scene changes, on-screen text changes, browser errors) are produced while the source is still playing, not after it ends.","write_action":false,"price_micros":0,"input_schema":null},{"name":"stats","description":"Lifetime token-savings meter: how many tokens Watch Skill's text-first answers + semantic cache have saved vs naive raw-frame injection.","write_action":false,"price_micros":0,"input_schema":null},{"name":"stop_live_watch","description":"Stop a live session. With finalize=true the pinned evidence becomes an ordinary indexed video — ask_video and search_videos work on it afterwards, with no reprocessing of the media.","write_action":false,"price_micros":0,"input_schema":null},{"name":"verify_contract","description":"Decide whether an agent run actually succeeded, using deterministic checks rather than an opinion about a screenshot.","write_action":false,"price_micros":0,"input_schema":null},{"name":"watch_batch","description":"Watch + index a WHOLE SET of videos in one call: a playlist/channel URL (auto-expanded), a folder of video files, or an explicit list of URLs/paths. Every video lands in the same persistent index, so one search_videos/ask_video afterwards spans the entire batch — cross-video questions become possible. One failing video never stops the rest.","write_action":false,"price_micros":0,"input_schema":null},{"name":"watch_video","description":"FIRST LOOK at any video — use when given a video you have NOT analyzed yet. Accepts any URL yt-dlp supports (1800+ sites), direct media URLs, HLS/DASH manifests, and local file paths. Downloads, extracts scene-aware deduplicated frames, OCRs them, transcribes (captions first, then local whisper), and INDEXES everything. Returns a report + key frames as images. For follow-ups about the same video c","write_action":false,"price_micros":0,"input_schema":null},{"name":"watch_workspace","description":"Open the Watch Skill live workspace — the visual view of a session.","write_action":false,"price_micros":0,"input_schema":null},{"name":"workspace_delta","description":"Events after a cursor, as JSON. The app's polling call.","write_action":false,"price_micros":0,"input_schema":null},{"name":"workspace_snapshot","description":"Canonical workspace state as JSON. Used by the app and by tests.","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":77,"grade":"B","scanned_at":"2026-09-19T21:42:28.265Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-19T21:42:28.247Z","components":{"code":{"score":15,"max":25,"notes":["205 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 5 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[{"id":"exec.shell-true","severity":"medium","component":"code","title":"subprocess with shell=True","evidence":"watch_skill-1.4.3/src/watch_skill/loop/framework.py: …sult = subprocess.run( cmd, shell=True, capture_output=True, text=True, …"},{"id":"exec.eval","severity":"medium","component":"code","title":"eval / new Function used","evidence":"watch_skill-1.4.3/src/watch_skill/vision/worker_main.py: …_mem_usage=True, local_files_only=True).eval() STATE.model, STATE.processor = mo…"}],"inputs":{"packages":[{"registryType":"pypi","identifier":"watch-skill","version":"1.4.3","found":true,"license":"MIT","dependencyCount":48,"publishedAt":"2026-09-08T18:51:04.213171Z","repositoryUrl":"https://github.com/oxbshw/watch-skill"}],"repo":{"found":true,"owner":"oxbshw","repo":"watch-skill","archived":false,"pushedAt":"2026-09-14T19:58:02Z","stars":379,"forks":56,"openIssues":2,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/212214682?v=4","ownerCreatedAt":"2025-05-18T09:31:39Z","license":"MIT"},"icon":{"url":"https://avatars.githubusercontent.com/u/212214682?v=4&s=128","source":"github"},"presence":{"stars":379,"forks":56,"downloadsWeek":null,"license":"MIT","lastPushAt":"2026-09-14T19:58:02.000Z","score":43}}}},"grade_history":[],"reviews":[]}