MCP server¶
videopython-mcp — a stdio Model Context Protocol
server exposing the auto-editing pipeline. Install with the [mcp] extra; setup and
the intended flow are in Drive editing from an MCP agent.
The server caches analyses and the catalog, so tool payloads stay small — the agent passes scene ids, never analysis blobs. The server's filesystem, process, and network access is defined in MCP security boundary.
Tools¶
analyze_video(path, profile="editing")¶
Analyze a source: scenes, transcript, captions. Cached server-side for the catalog.
Returns a short summary. The default profile="editing" skips audio classification,
which the catalog never reads. profile="full" runs all analyzers.
Returns source as a resolved absolute path, plus duration, fps, width,
height, scenes, and analyzers. A successful analysis clears the current catalog.
analyzers contains one record for each configured analysis stage:
status |
reason |
Meaning |
|---|---|---|
completed |
null |
The analyzer completed. |
skipped |
disabled |
The selected profile disabled the analyzer. |
failed |
initialization_failed |
The requested analyzer could not load. |
failed |
execution_failed |
The requested analyzer loaded but did not complete. |
The remaining analysis is still cached when one analyzer fails. Check these records before building a plan that depends on a missing transcript, caption, or face result.
export_analysis(source, output_path)¶
Verify the selected source's content digest and write its cached VideoAnalysis
as JSON at output_path. source resolves to an absolute path. No inference runs.
import_analysis(path)¶
Load saved JSON, reject unsupported formats or changed/unbound sources, then cache
it under its resolved source path. This clears the current catalog. Call
build_catalog before using scene IDs. Import does not start analyzers, change the
saved configuration, or fill unknown provenance from current models.
Both tools return path, source, config, provenance, and analyzers.
path and source are absolute paths. Failed and skipped stage outcomes are
preserved. Format, identity, and file-access errors are MCP tool errors; they do not
use edit-plan error codes. The analysis reference
defines provenance and migration.
build_catalog(sources=None, mode="visual", speech=None)¶
Returns the candidate scenes as one JSON text block — id, duration, shot_type, caption
and transcript per scene, enough to shortlist from text alone — followed by up to 12
downscaled keyframe images. If more scenes exist, a trailing note names the omitted ids.
Author the edit by referencing the returned id values.
For spoken passages, use mode="speech" and a speech object such as
{"min_duration": 10, "max_duration": 30, "pause_duration": 0.8}. Visual mode
requires speech=null. The speech-candidate contract
defines boundaries, missing-alignment behavior, and ID invalidation. If speech mode
finds no passages, the catalog has an empty scenes list and a following text block
explains that no complete aligned passages fit. Building any catalog clears the
previous selection and image cache.
scene_keyframes(scene_ids)¶
Downscaled keyframes for a chosen shortlist of scene ids. Use after build_catalog to
pull frames that were capped out, without re-inlining the whole library. Each call
accepts at most 12 distinct IDs. Duplicates count once; a larger shortlist raises a
descriptive tool error before extraction. Split it into calls of at most 12 IDs.
scene_transcripts(scene_ids)¶
Return a JSON text block mapping requested IDs to full normalized transcript text.
This works for visual scenes and speech passages. Duplicate IDs return one entry.
Unknown IDs return a text block with code unknown_scene_ids, as with
scene_keyframes. Requires a catalog; it performs no inference or media read.
validate_edit(plan)¶
Validate an EditPlan (which references catalog scene_ids). Returns every problem at
once as structured errors.
{
"valid": false,
"errors": [{
"code": "unknown_scene_ids", "message": "Unknown scene ids: ['clip#9']",
"value": ["clip#9"], "location": null, "op": null, "field": null,
"limit": null, "detail": null
}]
}
repair_edit(plan)¶
Clamp mechanical issues and normalize dimensions. Returns the repaired VideoEdit plus a
changelog, for inspection — that edit is a concrete VideoEdit, not a re-submittable
EditPlan. Keep refining the by-id plan.
{
"edit": {
"segments": [
{
"source": "clip.mp4",
"start": 0.0,
"end": 8.0,
"operations": [],
"transition_in": null
}
],
"post_operations": [],
"match_to_lowest_fps": true,
"match_to_lowest_resolution": true,
"music_bed": null
},
"repairs": [
{
"location": "segments[0]",
"field": "end",
"old": 9.0,
"new": 8.0,
"code": "segment_end_exceeds_source"
}
],
"errors": []
}
edit is null when resolution fails. A returned edit has been repaired, but
errors=[] here does not establish that it passes a new validation check. Each repair always has location, field,
old, new, and code.
run_edit(plan, output_path)¶
Resolve, repair, validate, then render to an MP4 (the suffix is normalized to .mp4), or
return the remaining errors.
output_path is null when the plan cannot be resolved or validated.
When the request includes _meta.progressToken, run_edit sends MCP progress
notifications during rendering. The numeric progress is a monotonically increasing
notification sequence; total is omitted. The message is JSON containing the
RenderProgress fields. Counts inside the message
apply to one stage and can reset. Do not display the notification sequence as a
percentage. The tool's final result schema is unchanged.
Rendering runs in a worker thread, leaving the server event loop available to deliver notifications. Progress uses the MCP transport, not prints to stdout. Clients that do not request progress still receive the usual final result.
Error objects¶
Errors from validate_edit, repair_edit, and run_edit have a stable code and a diagnostic message. Code-specific fields are:
- plan validation:
location,op,field,value,limit, anddetail; - unknown scene ids:
value, containing the unknown ids; - invalid plan schema:
detail, containing Pydantic error records.
Fields that do not apply are null. scene_keyframes instead returns a text block
with code, value, and message for unknown ids. Missing catalogs and failures
outside plan validation can surface as MCP tool errors. Error messages are for diagnostics; branch on
code and structured fields instead.
Resource¶
schema://videopython/edit-plan¶
The JSON Schema for the EditPlan the agent authors. The plan types themselves are
documented in AI auto-editing.
Image budget¶
Every image the MCP path returns is downscaled to a longest side of 768 px, and
build_catalog extracts and inlines at most 12. Catalog text does not require image
extraction. scene_keyframes also limits each request to 12 distinct IDs, separately
from the retention limit. Each image request batches scene midpoints by source and decodes only
through the last requested frame. The decode array holds up to 12 full-resolution
RGB frames before downscaling, so peak allocation also depends on source resolution.
The server retains at most 12 downscaled images,
evicting the least recently requested image when the cache is full. A cache hit needs
no decode. Building a new catalog clears the image cache. Omitted catalog rows do not
cause image extraction until requested.
SceneVLM captioning and the in-process planner keep full-resolution frames.
The catalog measurements record the
latency and memory tradeoff.