{"ok":true,"site":{"host":"relaylab-three.vercel.app","url":"https://relaylab-three.vercel.app/","type":"live","desc":"RelayLab lets a human and an external AI agent co-edit one B-roll timeline through a structured WebMCP contract.","tools":[{"name":"get_timeline","kind":"answer","impl":"imperative","description":"Read the live RelayLab timeline, including ghost and committed B-roll overlays, distinct source-video and main-timeline ranges, human locks, reasons, project approval status, and immutable audio policy. Call this after the human edits or locks an overlay; it always reads current shared state.","title":"Get RelayLab timeline","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_edit_plan","kind":"answer","impl":"imperative","description":"Read the agent's current structured editorial plan: every decision (uploaded-B-roll placement, generated-B-roll suggestion) with its timeline range, transcript context, reason, status (proposed/accepted/rejected/modified-by-human/locked), and ranked alternatives where known. This is the coherent 'what is the plan' answer, derived live from the same overlays and suggestions get_timeline reports — never a separate or stale copy. Includes timelineRevisionUsed, the timeline revision this snapshot reflects.","title":"Get RelayLab edit plan","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_project_summary","kind":"answer","impl":"imperative","description":"Read a compact project summary: title, duration, approval status, transcript/B-roll counts, overlay counts by state, the current pacing preference, and the immutable audio policy. Use this before deeper reads to decide what to look at next.","title":"Get project summary","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_transcript","kind":"answer","impl":"imperative","description":"Read a bounded slice of timestamped transcript by optional startSeconds/endSeconds and/or segment count. Never returns the full transcript unbounded: defaults to 20 segments and caps at 100.","title":"Get transcript range","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"startSeconds":{"type":"number","minimum":0,"description":"Only include segments ending after this time in seconds."},"endSeconds":{"type":"number","exclusiveMinimum":0,"description":"Only include segments starting before this time in seconds."},"startTime":{"type":"number","minimum":0,"description":"Deprecated compatibility alias for startSeconds."},"endTime":{"type":"number","exclusiveMinimum":0,"description":"Deprecated compatibility alias for endSeconds."},"maxSegments":{"type":"number","minimum":1,"maximum":100,"description":"Maximum number of segments to return; defaults to 20, capped at 100."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"find_overlay_opportunities","kind":"answer","impl":"imperative","description":"Read-only heuristic scan for B-roll candidate slots. Finds pacing gaps plus transcript cues for products/apps, lists, concrete objects/places, and examples. Optional startSeconds/endSeconds bound the scan; maxTalkingHeadSeconds is safely clamped to 5-30. Returns overlapping transcript text and a stable reason enum. Never creates or modifies an overlay.","title":"Find overlay opportunities","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"maxTalkingHeadSeconds":{"type":"number","description":"Pacing threshold in seconds; safely clamped to the 5-30 range."},"startSeconds":{"type":"number","minimum":0,"description":"Optional inclusive start of the timeline range to inspect."},"endSeconds":{"type":"number","exclusiveMinimum":0,"description":"Optional exclusive end of the timeline range to inspect."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"search_broll","kind":"answer","impl":"imperative","description":"Search available indexed B-roll source moments by description/tag relevance, optional minDuration/maxDuration, duration fit, and recent-reuse penalty. Returns source ranges and scores. Excludes unindexed or invalid source ranges and never creates a proposal.","title":"Search indexed B-roll","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Free-text search terms, matched against moment descriptions and tags."},"minDuration":{"type":"number","exclusiveMinimum":0,"description":"Exclude source moments shorter than this many seconds."},"maxDuration":{"type":"number","exclusiveMinimum":0,"description":"Exclude source moments longer than this many seconds."},"targetDuration":{"type":"number","exclusiveMinimum":0,"description":"Optional precise desired duration for compatibility and fit scoring."},"matchThreshold":{"type":"number","minimum":0,"maximum":1,"description":"Optional deterministic strong-match threshold; defaults to the configured 0.65 value."},"limit":{"type":"number","minimum":1,"maximum":50,"description":"Maximum number of ranked results to return; defaults to 10."}},"required":["query"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"propose_overlay","kind":"act","impl":"imperative","description":"Create a non-destructive GHOST B-roll proposal from an indexed moment while the project is planning. This never commits, approves, locks, or changes the base track, and B-roll remains muted. Arguments are validated and clamped to safe source/project bounds.","title":"Propose B-roll overlay","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"momentId":{"type":"string","minLength":1,"description":"Indexed B-roll moment identifier from the project library."},"timelineStart":{"type":"number","minimum":0,"description":"Desired start in seconds on the locked base-video timeline."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Desired duration in seconds; clamped to source and project bounds."},"reason":{"type":"string","minLength":1,"maxLength":500,"description":"Concise editorial reason for this visual support."}},"required":["momentId","timelineStart","duration","reason"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"update_overlay_proposal","kind":"act","impl":"imperative","description":"Update an existing unlocked GHOST proposal while planning. May change timeline start, duration, validated source in/out, or reason. Rejects human-locked overlays with HUMAN_LOCKED and cannot change approval, base media, locks, or audio.","title":"Update B-roll proposal","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"overlayId":{"type":"string","minLength":1},"timelineStart":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0},"sourceStart":{"type":"number","minimum":0},"sourceEnd":{"type":"number","exclusiveMinimum":0},"reason":{"type":"string","minLength":1,"maxLength":500}},"required":["overlayId"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"remove_overlay_proposal","kind":"act","impl":"imperative","description":"Remove an unlocked GHOST B-roll proposal while planning. Rejects human-locked overlays with HUMAN_LOCKED. Cannot remove committed edits, approve the plan, change locks, or affect any audio.","title":"Remove B-roll proposal","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"overlayId":{"type":"string","minLength":1}},"required":["overlayId"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"propose_generated_broll","kind":"act","impl":"imperative","description":"Create a visually distinct GHOST GENERATION SUGGESTION only after search_broll shows no strong uploaded-footage match. Stores a proposed prompt, timing, and editorial reason for human review. It does not call fal.ai, generate media, approve anything, spend credits, or create an overlay.","title":"Propose generated B-roll fallback","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"timelineStart":{"type":"number","minimum":0,"description":"Desired start on the locked base-video timeline."},"duration":{"type":"number","minimum":1,"maximum":10,"description":"Suggested clip duration in seconds, limited to 1-10."},"prompt":{"type":"string","minLength":10,"maxLength":1000,"description":"Visually grounded generation prompt: one clear action, useful framing, subtle motion, no dialogue or text overlays."},"reason":{"type":"string","minLength":1,"maxLength":500,"description":"Why visual support helps and why no uploaded source moment is adequate."},"searchQuery":{"type":"string","minLength":1,"maxLength":200,"description":"Concise visual need used to recheck the uploaded library before allowing this fallback."}},"required":["searchQuery","timelineStart","duration","prompt","reason"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"update_generated_broll_suggestion","kind":"act","impl":"imperative","description":"Revise the timing, prompt, or reason of an unresolved generation suggestion while planning. This changes metadata only and never invokes a provider or spends credits. A suggestion already being generated by the human is rejected as SUGGESTION_BUSY.","title":"Update generated B-roll suggestion","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"suggestionId":{"type":"string","minLength":1},"timelineStart":{"type":"number","minimum":0},"duration":{"type":"number","minimum":1,"maximum":10},"prompt":{"type":"string","minLength":10,"maxLength":1000},"reason":{"type":"string","minLength":1,"maxLength":500}},"required":["suggestionId"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"remove_generated_broll_suggestion","kind":"act","impl":"imperative","description":"Remove an unresolved generation suggestion while planning. This never cancels or starts paid generation; a suggestion already being generated by the human is rejected as SUGGESTION_BUSY.","title":"Remove generated B-roll suggestion","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"suggestionId":{"type":"string","minLength":1}},"required":["suggestionId"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_pacing_preference","kind":"act","impl":"imperative","description":"Set the maximum uninterrupted talking-head duration (seconds) used by find_overlay_opportunities pacing-gap detection. Clamped to 5-30 seconds. Planning-only; does not move, lock, approve, or commit any overlay.","title":"Set pacing preference","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"maxTalkingHeadSeconds":{"type":"number","minimum":5,"maximum":30,"description":"Maximum uninterrupted talking-head seconds before a pacing gap is flagged."}},"required":["maxTalkingHeadSeconds"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_caption_style","kind":"act","impl":"imperative","description":"Set one or more caption presentation fields: position (top/center/bottom), fontFamily (one of a small free-font preset list), fontSize (12-56px, clamped), text color, background mode (none/solid), and background color. Only provided fields change; omitted fields keep their current value. Planning-only. Applies to both the live preview and the burned-in ffmpeg export.","title":"Set caption style","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"position":{"type":"string","enum":["top","center","bottom"],"description":"Caption vertical placement."},"fontFamily":{"type":"string","enum":["inter","roboto","poppins","montserrat","oswald","bebas-neue"],"description":"Caption font preset."},"fontSize":{"type":"number","minimum":12,"maximum":56,"description":"Caption font size in pixels, clamped to 12-56."},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Caption text color as a 6-digit hex string, e.g. #ffffff."},"background":{"type":"string","enum":["none","solid"],"description":"Whether captions render on a solid background box or with no box."},"backgroundColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Caption background box color as a 6-digit hex string, used only when background is solid."}},"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"replan_unlocked_sections","kind":"act","impl":"imperative","description":"Re-read the shared timeline and update only unlocked, agent-authored ghost B-roll proposals whose source moment is no longer the strongest available uploaded match. Human locks, human-authored overlays, and committed edits are always preserved untouched, and a moment the human previously rejected for any slot is never re-proposed. Requires the timelineRevision last read from get_timeline/get_edit_plan/get_project_summary; a stale value is rejected with STALE_TIMELINE instead of silently overwriting a timeline the human has since changed. Never creates new overlays or generation suggestions; only revises existing unlocked ones.","title":"Replan unlocked sections","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"inputSchema":{"type":"object","properties":{"objective":{"type":"string","minLength":1,"maxLength":500,"description":"Optional editorial objective/search focus guiding which unlocked decisions are re-evaluated. Defaults to each decision's own stored reason or overlapping transcript text."},"preserveHumanChanges":{"type":"boolean","const":true,"description":"Must be true; replan never overwrites human locks or human-placed overlays."},"timelineRevision":{"type":"integer","minimum":0,"description":"The timelineRevision this plan was built against, from the most recent get_timeline/get_edit_plan/get_project_summary read."}},"required":["preserveHumanChanges","timelineRevision"],"additionalProperties":false},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"Media & Personal","apiSurface":"spec","toolCount":15}}