muvid.mcp¶
muvid MCP server — the music-visualizer tool surface for a remote connector.
Optional subpackage (extra muvid[mcp]: fastmcp + py2mcp + nw).
import muvid never imports this. The connector references the tools by name via
TOOL_REFS; register_tools() aggregates them onto a host FastMCP server
(the unified reelee AV connector, thorwhalen/muvid#3), and build_server()
assembles a standalone server for local (stdio) testing.
Almost every tool is free. The one exception is
propose_lyric_treatments_ai (COSTED_TOOLS), which calls an LLM to author a
lyric-video treatment — muvid’s first tool that spends money. It is a separate tool from
the free heuristic proposer because a host meters by tool NAME and cannot see an
argument, so a “free unless you pass a flag” tool is unmeterable by construction.
Its cost is reported as UNKNOWN rather than zero: muvid’s budget gate is conjunctive and
an unpriced call must force approval (muvid#47).
Module Attributes
All tools this package exposes (all free). |
|
Alias — muvid has no costed tools. |
|
Bare tool name → its |
Functions
|
Register muvid's MCP tools onto an EXISTING FastMCP |
|
Assemble a standalone FastMCP server exposing muvid's tools (stdio dev/testing). |
The caller's identity for the in-flight tool call (raises if unauthenticated). |
|
The verified caller's email from the OAuth token ( |
|
|
Bind the caller identity for the duration of the block (local/stdio/testing). |
The muvid data root: |
Classes
|
A single caller's private visualizer area, addressed by |
- muvid.mcp.FREE_TOOLS = ['list_visuals', 'list_projects', 'project_status', 'render_visualizer', 'footage_status', 'set_song', 'add_footage', 'remove_footage', 'align_footage', 'footage_set_offset', 'footage_clear_offset', 'footage_set_has_song', 'footage_timeline', 'beat_grid', 'footage_peaks', 'footage_beat_signals', 'footage_filmstrips', 'footage_filmstrip', 'list_strategies', 'propose_edit', 'footage_save_edit', 'footage_edits', 'footage_explain_edit', 'footage_get_edit', 'footage_replace_edit', 'footage_set_cut', 'footage_split_cut', 'footage_merge_cut', 'footage_fit_to_beat', 'footage_set_span', 'footage_rename_edit', 'footage_looks', 'footage_undo_edit', 'footage_redo_edit', 'footage_delete_edit', 'footage_render', 'footage_renders', 'footage_editor_document', 'add_footage_folder', 'assemble_music_video', 'list_music_video_projects', 'footage_edl_from_annotations', 'score_footage', 'footage_scores', 'footage_score_status', 'list_archetypes', 'analyze_song_lyrics', 'propose_lyric_treatments', 'validate_lyric_treatment', 'render_lyric_video', 'list_subgenres', 'render_subgenre']¶
Alias — muvid has no costed tools.
- muvid.mcp.TOOL_NAMES = ['list_visuals', 'list_projects', 'project_status', 'render_visualizer', 'footage_status', 'set_song', 'add_footage', 'remove_footage', 'align_footage', 'footage_set_offset', 'footage_clear_offset', 'footage_set_has_song', 'footage_timeline', 'beat_grid', 'footage_peaks', 'footage_beat_signals', 'footage_filmstrips', 'footage_filmstrip', 'list_strategies', 'propose_edit', 'footage_save_edit', 'footage_edits', 'footage_explain_edit', 'footage_get_edit', 'footage_replace_edit', 'footage_set_cut', 'footage_split_cut', 'footage_merge_cut', 'footage_fit_to_beat', 'footage_set_span', 'footage_rename_edit', 'footage_looks', 'footage_undo_edit', 'footage_redo_edit', 'footage_delete_edit', 'footage_render', 'footage_renders', 'footage_editor_document', 'add_footage_folder', 'assemble_music_video', 'list_music_video_projects', 'footage_edl_from_annotations', 'score_footage', 'footage_scores', 'footage_score_status', 'list_archetypes', 'analyze_song_lyrics', 'propose_lyric_treatments', 'propose_lyric_treatments_ai', 'validate_lyric_treatment', 'render_lyric_video', 'list_subgenres', 'render_subgenre']¶
All tools this package exposes (all free). Bare names; a host may prefix them.
- muvid.mcp.TOOL_REFS = {'add_footage': 'muvid.mcp.footage_tools:add_footage', 'add_footage_folder': 'muvid.mcp.footage_tools:add_footage_folder', 'align_footage': 'muvid.mcp.footage_tools:align_footage', 'analyze_song_lyrics': 'muvid.mcp.lyricvid_tools:analyze_song_lyrics', 'assemble_music_video': 'muvid.mcp.footage_tools:assemble_music_video', 'beat_grid': 'muvid.mcp.footage_tools:beat_grid', 'footage_beat_signals': 'muvid.mcp.footage_tools:footage_beat_signals', 'footage_clear_offset': 'muvid.mcp.footage_tools:footage_clear_offset', 'footage_delete_edit': 'muvid.mcp.footage_tools:footage_delete_edit', 'footage_editor_document': 'muvid.mcp.footage_tools:footage_editor_document', 'footage_edits': 'muvid.mcp.footage_tools:footage_edits', 'footage_edl_from_annotations': 'muvid.mcp.footage_tools:footage_edl_from_annotations', 'footage_explain_edit': 'muvid.mcp.footage_tools:footage_explain_edit', 'footage_filmstrip': 'muvid.mcp.footage_tools:footage_filmstrip', 'footage_filmstrips': 'muvid.mcp.footage_tools:footage_filmstrips', 'footage_fit_to_beat': 'muvid.mcp.footage_tools:footage_fit_to_beat', 'footage_get_edit': 'muvid.mcp.footage_tools:footage_get_edit', 'footage_looks': 'muvid.mcp.footage_tools:footage_looks', 'footage_merge_cut': 'muvid.mcp.footage_tools:footage_merge_cut', 'footage_peaks': 'muvid.mcp.footage_tools:footage_peaks', 'footage_redo_edit': 'muvid.mcp.footage_tools:footage_redo_edit', 'footage_rename_edit': 'muvid.mcp.footage_tools:footage_rename_edit', 'footage_render': 'muvid.mcp.footage_tools:footage_render', 'footage_renders': 'muvid.mcp.footage_tools:footage_renders', 'footage_replace_edit': 'muvid.mcp.footage_tools:footage_replace_edit', 'footage_save_edit': 'muvid.mcp.footage_tools:footage_save_edit', 'footage_score_status': 'muvid.mcp.scoring_tools:footage_score_status', 'footage_scores': 'muvid.mcp.scoring_tools:footage_scores', 'footage_set_cut': 'muvid.mcp.footage_tools:footage_set_cut', 'footage_set_has_song': 'muvid.mcp.footage_tools:footage_set_has_song', 'footage_set_offset': 'muvid.mcp.footage_tools:footage_set_offset', 'footage_set_span': 'muvid.mcp.footage_tools:footage_set_span', 'footage_split_cut': 'muvid.mcp.footage_tools:footage_split_cut', 'footage_status': 'muvid.mcp.footage_tools:footage_status', 'footage_timeline': 'muvid.mcp.footage_tools:footage_timeline', 'footage_undo_edit': 'muvid.mcp.footage_tools:footage_undo_edit', 'list_archetypes': 'muvid.mcp.lyricvid_tools:list_archetypes', 'list_music_video_projects': 'muvid.mcp.footage_tools:list_music_video_projects', 'list_projects': 'muvid.mcp.tools:list_projects', 'list_strategies': 'muvid.mcp.footage_tools:list_strategies', 'list_subgenres': 'muvid.mcp.subgenre_tools:list_subgenres', 'list_visuals': 'muvid.mcp.tools:list_visuals', 'project_status': 'muvid.mcp.tools:project_status', 'propose_edit': 'muvid.mcp.footage_tools:propose_edit', 'propose_lyric_treatments': 'muvid.mcp.lyricvid_tools:propose_lyric_treatments', 'propose_lyric_treatments_ai': 'muvid.mcp.lyricvid_tools:propose_lyric_treatments_ai', 'remove_footage': 'muvid.mcp.footage_tools:remove_footage', 'render_lyric_video': 'muvid.mcp.lyricvid_tools:render_lyric_video', 'render_subgenre': 'muvid.mcp.subgenre_tools:render_subgenre', 'render_visualizer': 'muvid.mcp.tools:render_visualizer', 'score_footage': 'muvid.mcp.scoring_tools:score_footage', 'set_song': 'muvid.mcp.footage_tools:set_song', 'validate_lyric_treatment': 'muvid.mcp.lyricvid_tools:validate_lyric_treatment'}¶
Bare tool name → its
module:functionreference (tools live in three modules).
- class muvid.mcp.VisualizerWorkspace(email, root)[source]¶
Bases:
objectA single caller’s private visualizer area, addressed by
email.emailand everyproject_idare validated as single path components, so a caller can never escape their own subtree.- create_project(project_id, *, title='', force=False)[source]¶
Create (and return) a new visualizer bucket under this user.
- Return type:
- muvid.mcp.build_server(*, name='muvid', instructions="muvid music-visualizer — turn a song into a 16:9, YouTube-ready visualizer video (+ thumbnail), deterministically and for free (ffmpeg only, no AI, no keys).\n\nWorkflow:\n1. Create a project: create_project(genre='music-visualizer', template='<look>'). See list_visuals() for the looks (still / cqt / bars / spectrum / waves / scope) or use 'auto'.\n2. Render: render_visualizer(project_id, audio='<https URL to the song>', cover='<https URL to the cover>', visual='<look>'). Audio/cover are direct media URLs, fetched server-side; the 'still' look needs a cover.\n3. Inspect: project_status(project_id) lists your renders (paths + the platform-check verdict).\n\nAll tools are free. Renders are stored server-side in your project bucket.", auth=None, middleware=None)[source]¶
Assemble a standalone FastMCP server exposing muvid’s tools (stdio dev/testing).
The hosted path aggregates onto the reelee connector via
register_tools(); this is the convenience builder formuvid.mcpon its own.
- muvid.mcp.current_email()[source]¶
The caller’s identity for the in-flight tool call (raises if unauthenticated).
Resolves from the explicit
use_email()override when present (local/stdio/ tests), else the verified OAuth token — so tools work under any host middleware, and an unauthenticated call is failed closed.- Return type:
- muvid.mcp.data_root()[source]¶
The muvid data root:
$MUVID_DATA_HOMEor~/.local/share/muvid.Public API (
muvid.mcpre-exports it), so the name stays though the body moved. A forwarder, not an alias, for the introspection reason given on the footage twin.- Return type:
- muvid.mcp.register_tools(server, *, prefix='', include=None, exclude=None)[source]¶
Register muvid’s MCP tools onto an EXISTING FastMCP
server— the aggregation seam for a host connector (the unified reelee connector, muvid#3).Mirrors
braidio.mcp.register_tools/falaw.bridges.mcp.register_tools.prefixnamespaces the tool names (e.g."muvid_") to avoid collisions;include/exclude(sets of bare names) select a subset. Returns the registered (prefixed) names. The host installs identity/metering separately — muvid’s tools resolve the caller viacurrent_email(), which works under any host middleware.
- muvid.mcp.token_email()[source]¶
The verified caller’s email from the OAuth token (
emailclaim, elsesub).Lowercased, or
Nonewhen there is no request/token context — deliberately no fallback, so a caller is failed closed rather than handed a shared identity.
- muvid.mcp.use_email(email)[source]¶
Bind the caller identity for the duration of the block (local/stdio/testing).
Modules
MCP tools for the footage-aligned |
|
Caller identity for the muvid MCP tools — resolved from the OAuth token, fail-closed. |
|
MCP tools for the footage SCORING layer (thorwhalen/muvid#13). |
|
Per-user output bucket for the muvid |