Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Frapea

REMOTE · APP.FRAPEA.COM

A video editor in your browser that your AI drives: cuts, captions, multicam, motion titles, export.

Available components

+5 this week 68 Trust /100

Last scanned (11 hours ago)

Scores higher than 57% of remote servers

Reachable. Last reached 23 Oct 2026.

Category Design and Media

Recent critical change

Authorization (23 Oct 2026). See the changelog before you install this server.

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security63
Transport & Reachability100
Schema Quality & AI Usability62
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 18160 tokens (~271/item across 67 items; 67 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management37
  • Stability observed for 11 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage99
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 98% of tool parameters carry a description.Partial
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 5 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 68 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities60
  • Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28. See how to fix → Fail
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 23 Oct 26 +2
    • Authorization: unverified → fail ▼ critical
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “add_sfx” rewrote its description, which is the text the model reads security
    • Tool “await_user_action” rewrote its description, which is the text the model reads security
    • Tool “close_project” rewrote its description, which is the text the model reads security
    • Tool “create_motion_composition” rewrote its description, which is the text the model reads security
    • Tool “generate_voiceover” rewrote its description, which is the text the model reads security
    • Tool “get_analysis_status” rewrote its description, which is the text the model reads security
    • Tool “get_problems” rewrote its description, which is the text the model reads security
    • Tool “get_projects” rewrote its description, which is the text the model reads security
    • Tool “inspect_timeline” rewrote its description, which is the text the model reads security
    • Tool “open_project” rewrote its description, which is the text the model reads security
    • Tool “read_skill” rewrote its description, which is the text the model reads security
    • Tool “retry_analysis” rewrote its description, which is the text the model reads security
    • Tool “search_sounds” rewrote its description, which is the text the model reads security
    • Tool “search_stock_media” rewrote its description, which is the text the model reads security
    • Tool “set_active_timeline” rewrote its description, which is the text the model reads security
    • Tool “verify_timeline” rewrote its description, which is the text the model reads security
    • Tool “add_clips” is now declared destructive security
    • Tool “apply_layout” is now declared destructive security
    • Tool “bind_face” is now declared destructive security
    • Tool “close_project” is now declared destructive security
    • Tool “manage_effects” is now declared destructive security
    • Tool “manage_queue” is now declared destructive security
    • Tool “manage_tracks” is now declared destructive security
    • Tool “manage_transitions” is now declared destructive security
    • Tool “merge_faces” is now declared destructive security
    • Tool “move_clips” is now declared destructive security
    • Tool “open_project” is now declared destructive security
    • Tool “organize_media” is now declared destructive security
    • Tool “organize_pool” is now declared destructive security
    • Tool “remove_clips” is now declared destructive security
    • Tool “remove_silence” is now declared destructive security
    • Tool “remove_words” is now declared destructive security
    • Tool “retry_analysis” is now declared destructive security
    • Tool “ripple_delete_ranges” is now declared destructive security
    • Tool “set_clip_properties” is now declared destructive security
    • Tool “set_keyframes” is now declared destructive security
    • Tool “set_project_settings” is now declared destructive security
    • Tool “track_faces” is now declared destructive security
    • Tool “trim_clips” is now declared destructive security
    • Tool “undo” is now declared destructive security
    • Tool “update_motion_composition” is now declared destructive security
    • Destructive annotations: All 5 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation. functional
    • New tool “add_sample_media” functional
    • New tool “close_timeline” functional
    • New tool “open_timeline” functional
    • Tool “add_clips” changed its title: Add clips cosmetic
    • Tool “add_sfx” changed its title: Add built-in sound effects cosmetic
    • Tool “apply_layout” changed its title: Apply layout cosmetic
    • Tool “await_user_action” changed its title: Wait for the user cosmetic
    • Tool “bind_face” changed its title: Bind clip to a face cosmetic
    • Tool “close_project” changed its title: Close project cosmetic
    • Tool “connect” changed its title: Connect to Frapea cosmetic
    • Tool “connect_media_folder” changed its title: Ask to connect a media folder cosmetic
    • Tool “create_motion_composition” changed its title: Create motion composition cosmetic
    • Tool “create_timeline” changed its title: Create timeline cosmetic
    • Tool “cut_to_angle” changed its title: Cut to camera angle cosmetic
    • Tool “download_sound” changed its title: Download Freesound sound cosmetic
    • Tool “download_stock_media” changed its title: Download Pexels stock cosmetic
    • Tool “duplicate_timeline” changed its title: Duplicate timeline cosmetic
    • Tool “generate_captions” changed its title: Generate captions cosmetic
    • Tool “generate_voiceover” changed its title: Generate voiceover cosmetic
    • Tool “get_analysis_status” changed its title: Get analysis status cosmetic
    • Tool “get_bug_report” changed its title: Prepare bug report cosmetic
    • Tool “get_job_status” changed its title: Get job status cosmetic
    • Tool “get_media” changed its title: List media cosmetic
    • Tool “get_motion_composition” changed its title: Get motion composition cosmetic
    • Tool “get_problems” changed its title: Get problems cosmetic
    • Tool “get_projects” changed its title: List projects cosmetic
    • Tool “get_timeline” changed its title: Get timeline cosmetic
    • Tool “get_transcript” changed its title: Get transcript cosmetic
    • Tool “insert_clips” changed its title: Insert clips cosmetic
    • Tool “inspect_media” changed its title: Inspect source frames cosmetic
    • Tool “inspect_timeline” changed its title: Inspect timeline frames cosmetic
    • Tool “list_face_tracks” changed its title: List face tracks cosmetic
    • Tool “list_motion_compositions” changed its title: List motion compositions cosmetic
    • Tool “list_voiceover_models” changed its title: List voiceover models cosmetic
    • Tool “manage_effects” changed its title: Manage effects cosmetic
    • Tool “manage_queue” changed its title: Manage background queue cosmetic
    • Tool “manage_tracks” changed its title: Manage tracks cosmetic
    • Tool “manage_transitions” changed its title: Manage transitions cosmetic
    • Tool “measure_loudness” changed its title: Measure loudness cosmetic
    • Tool “merge_faces” changed its title: Merge faces cosmetic
    • Tool “move_clips” changed its title: Move clips cosmetic
    • Tool “new_project” changed its title: New project cosmetic
    • Tool “open_project” changed its title: Open project in the editor cosmetic
    • Tool “organize_media” changed its title: Rename or unlink media cosmetic
    • Tool “organize_pool” changed its title: Organize media bins cosmetic
    • Tool “read_skill” changed its title: Read editing guide cosmetic
    • Tool “remove_clips” changed its title: Remove clips cosmetic
    • Tool “remove_silence” changed its title: Remove silences cosmetic
    • Tool “remove_words” changed its title: Remove spoken words cosmetic
    • Tool “request_ai_models” changed its title: Ask to enable AI models cosmetic
    • Tool “retry_analysis” changed its title: Retry analysis cosmetic
    • Tool “ripple_delete_ranges” changed its title: Ripple delete ranges cosmetic
    • Tool “search_media” changed its title: Search project media cosmetic
    • Tool “search_sounds” changed its title: Search Freesound cosmetic
    • Tool “search_stock_media” changed its title: Search Pexels stock cosmetic
    • Tool “set_active_timeline” changed its title: Set active timeline cosmetic
    • Tool “set_clip_properties” changed its title: Set clip properties cosmetic
    • Tool “set_keyframes” changed its title: Set keyframes cosmetic
    • Tool “set_project_settings” changed its title: Set timeline settings cosmetic
    • Tool “split_clips” changed its title: Split clips cosmetic
    • Tool “start_transcription” changed its title: Start transcription cosmetic
    • Tool “start_visual_indexing” changed its title: Start picture indexing cosmetic
    • Tool “track_faces” changed its title: Track faces cosmetic
    • Tool “trim_clips” changed its title: Trim clips cosmetic
    • Tool “undo” changed its title: Undo cosmetic
    • Tool “update_motion_composition” changed its title: Update motion composition cosmetic
    • Tool “verify_timeline” changed its title: Verify timeline cosmetic
  • 22 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

  • 20 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

  • 19 Oct 26 0
    • “generate_voiceover” reworded the description of “modelId” cosmetic

    1 cosmetic change on this day. Switch on “Show cosmetic changes” to see it.

  • 18 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

  • 16 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

  • 15 Oct 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “get_job_status” rewrote its description, which is the text the model reads security
    • Tool “get_media” rewrote its description, which is the text the model reads security
    • Tool “manage_effects” rewrote its description, which is the text the model reads security
    • New tool “duplicate_timeline” functional
    • New tool “measure_loudness” functional
    • “get_media” added an optional parameter “mediaRef” cosmetic
    • “set_clip_properties” added an optional parameter “motionBlur” cosmetic
  • 13 Oct 26 +1
    • Stability: unverified → 0.03 ▲ functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 23 Oct 2026 · Probed https://app.frapea.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=frapea.com CN=WE1,O=Google Trust Services,C=US 17 Sept 2026 16 Dec 2026 ECDSA 256 ECDSA-SHA256 bfa0b8631af26fed13a78fde1847928e
SANs: frapea.com, app.frapea.com, *.app.frapea.com
CN=WE1,O=Google Trust Services,C=US (CA) CN=GTS Root R4,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 ECDSA 256 ECDSA-SHA384 7ff31977972c224a76155d13b6d685e3
CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 15 Nov 2023 28 Jan 2028 ECDSA 384 SHA256-RSA 7fe530bf331343bedd821610493d8a1b

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of app.frapea.com. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
com. present 19718 13 Verified
frapea.com. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
strict-transport-security max-age=15552000; includeSubDomains

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://app.frapea.com/mcp Verified 200
http (plaintext) http://app.frapea.com/mcp HTTPS enforced 301 https://app.frapea.com/mcp
MCP tools · 67 exposed · ~17,950 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
add_clips ~342

Places media segments on a timeline. Each clip: mediaRef (from get_media, 'timeline:<id>' to NEST another timeline as a clip, 'solid:#rrggbb' , 'motion:<id>' for a MOTION composition (create_motion_composition) for a generated solid-colour matte, 'adjustment:' for an adjustment clip — no picture of its own, its effects/masks/opacity grade everything below it — or 'text:' for a title, restyled via set_clip_properties' `text`), atFrame (timeline position), sourceInSec/sourceOutSec (the segment of the source to use — align these with transcript words or sceneSamples), and optional trackId (from get_timeline) to target a specific same-kind track — without it clips land on V1/A1 with overwrite semantics. A spare empty track always exists above the highest used one, so V2/A2 is available before anything sits on it. Video sources with audio get a linked audio clip automatically (on the matching A track: V2 ⇒ A2). Returns the created clip ids in order. Frames are in the target timeline's fps.

NameTypeReqDescription
clipsarrayyes[{mediaRef, atFrame, sourceInSec, sourceOutSec, trackId?}] — segments in playback order; trackId targets a specific track (default V1/A1).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTarget timeline id from get_timeline.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

add_sample_media ~200

Frapea's SAMPLE MEDIA, for trying the editor without your own footage: a short talking clip with speech and pauses (for transcripts, captions, removing words or silences), a b-roll shot, a photo and a music bed. No API key, no download from elsewhere. Call with no `ids` to list them; call with `ids` (or `all: true`) to copy them into the project's media pool at the Library root — each result gives a mediaRef for add_clips. Adding one already in the project returns its existing mediaRef.

NameTypeReqDescription
allboolean–Add every sample.
idsarray–Sample ids to add (talk, broll, photo, music). Omit to list them.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

add_sfx ~232

Frapea's BUILT-IN sound-effects pack — synthesized, licence-free, no API key, no download wait. Covers common UI and motion sounds; search_sounds is for what the pack does not (ambience, foley, a specific real-world object). Call with no `ids` to get the catalogue: each sound carries what it sounds like AND when to use it. Call with `ids` to copy them into the project's media pool as `sfx-<id>.wav` at the Library root; each result gives a mediaRef ready for add_clips on an audio track. Adding a sound already in the project is a no-op that returns its existing mediaRef.

NameTypeReqDescription
idstring–Convenience: a single sound id.
idsarray–Sound ids to add (e.g. ['whip','thump','ding']). Omit to list the pack.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

apply_layout ~264

Arranges clips into a screen layout by writing ordinary transform + crop values (first clipId → first cell). layout: full | side-by-side | top-bottom | pip-top-left | pip-top-right | pip-bottom-left | pip-bottom-right | grid-2x2 | main-sidebar | three-up. mode 'fit' letterboxes each source in its cell, 'cover' fills the cell and crops the overflow (bias 0–1 picks the surviving part; 0.5/0.5 = centre). Replaces the clips' geometry animation. The clips should overlap in time on different tracks — a layout of clips that never share a frame arranges nothing visible.

NameTypeReqDescription
biasobject–Cover-crop bias 0–1 per axis (default 0.5/0.5).
clipIdsarrayyesClips to arrange, in cell order.
layoutstringyesLayout id (see description).
modestring–fit | cover (default fit).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline containing the clips.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

await_user_action ~154

Waits (up to ~45 s per call) for the user to resolve a pending Frapea prompt — e.g. the folder-permission dialog another tool just opened. The dialog waits for the user in the Frapea tab; the tool that opened it returned what they need to click. Returns {status: 'granted' | 'denied' | 'pending'}: 'pending' means they have not acted yet (call again to keep waiting), 'denied' that they declined.

NameTypeReqDescription
actionIdstringyesThe actionId a previous tool returned.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

bind_face ~300

Makes a clip FOLLOW a tracked face — the way to stick a mask, label or blur onto somebody's head. Movement is relative to where the face was first seen, so the clip keeps the framing it already had and only inherits the motion. Pick what to copy with channels, and what happens while the face is missing with gap. Pass trackId: null to unbind.

NameTypeReqDescription
channelsobject–What to copy: {position, scale, pitch, yaw, roll} booleans. Default position and scale on, the three rotations off.
clipIdstringyesThe clip that should follow the face.
faceIdstring–Which person in that run.
gapstring–While the face is missing: 'hold' stays put then jumps, 'hide' disappears, 'glide' travels smoothly to where it reappears. One of: hold | hide | glide.
maxGlideSecondsnumber–Longest gap 'glide' will cross before hiding instead (default 1.8).
projectIdstringyesProject id from get_projects.
smoothnumber–Jitter filtering 0–1 (default 0.25).
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
trackIdstring–The run; null unbinds this clip.

No output schema declared.

No examples provided.

close_project ~92

Navigates the user's Frapea tab back to the project manager and releases this session's headless runtime for the project. When the tab shows that project it reloads, so an export or render running there stops.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

close_timeline ~126

Closes a timeline's TAB in the editor — hides it from the tab row, does NOT delete it: it stays in the media pool, and you (or anyone) can still edit, verify, nest and export it. When it was the one shown, the editor shows the next open tab, or none.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline whose tab to close.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

connect ~185

Pairs you with the user's Frapea browser tab. TWO WAYS ROUND. (1) If they already have Frapea open: ask them for the pairing code (the Connect MCP button) and call this with it. (2) If they do not, or you are not sure: call this with NO arguments and you get back a link — send them the link, then call this again with the code it contains every few seconds until it returns a token (they have to accept it in their browser first). Either way you end up with a session token to pass on every later call. Codes are single-use and expire in ten minutes; a token lasts until the user disconnects.

NameTypeReqDescription
codestring–The 8-character code — from the user's screen, or from the link this tool gave you. Omit it to get a link to send them.

No output schema declared.

No examples provided.

connect_media_folder ~281

Asks the user to attach a folder of THEIR OWN source footage to the project — opens a dialog in Frapea with a 'Connect folder' button. Only a human can do this (browser security gesture): tell the user IN YOUR REPLY to click it, then call await_user_action with the returned actionId; on 'granted', get_media will list the folder's files. Use when get_media comes back empty and the user has footage somewhere on their disk. NEVER call it for files YOU made or fetched. The project folder's `media/` folder is scanned: any media file placed there joins the pool by itself (within a second, or when the user returns to the tab), with no dialog. `reason` is shown in the dialog word for word — say which footage you need and what you will do with it, so the user knows what to pick.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
reasonstringyesOne or two sentences for the dialog, addressed to the user: which folder to pick and why — e.g. 'Pick the folder with your trip clips from Lisbon, so I can cut them into the reel you asked for.'
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

create_motion_composition ~511

Creates a MOTION COMPOSITION — an animated graphic (infographic, title, promo end-card, chart…) written as a React TSX component. Read the 'motion' skill (read_skill {topic:'motion'}) for the exact API surface, available fonts/icons and golden examples before writing one. files maps file names to TSX source; the entry must `export default` the component. schema declares the editable props (type string|number|color|boolean|select|mediaRef + default) — they become Inspector controls the user can tweak, so parameterize colors, copy and media slots. The composition is compiled and test-rendered BEFORE saving; on failure the error returns verbatim — fix the code and retry. Returns the mediaRef to place with add_clips. Creative guidance is in read_skill {topic:'motion'}. With UI-like parts (buttons, pills, progress bars, cards), write them in their own file with a partsBoard prop (default false) and look at the board first: preview:true, previewProps:{partsBoard:true} returns one large frame with the reply.

NameTypeReqDescription
durationInFramesnumber–Length in frames (default 150).
entrystring–Entry file (default composition.tsx); must export default.
filesobjectyesFile name → TSX source. Relative imports between them work.
fpsnumber–Composition fps (default 30).
heightnumber–Composition height px (default 1080).
namestringyesDisplay name, e.g. 'Pink promo end card'.
previewboolean–Return one large frame (≤1560 px) with the reply. Media is not loaded in a preview: media slots draw empty and the reply says how many.
previewFramenumber–Frame to preview (default 0).
previewPropsobject–Merged over the schema defaults for the preview picture only, e.g. {partsBoard:true}. Nothing saved changes.
projectIdstringyesProject id from get_projects.
schemaobject–Editable props: {key: {type, default, label?, min?, max?, options?, multiline?}}. type mediaRef makes a media-pool slot.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
widthnumber–Composition width px (default 1920).

No output schema declared.

No examples provided.

create_timeline ~172

Creates a new timeline in the project and returns its id. Set fps, width and height for the target format (e.g. 1080×1920 @30 for a vertical short). The new timeline starts with one video and one audio track; spare tracks appear automatically as clips land.

NameTypeReqDescription
fpsnumber–Optional frames per second (default 30).
heightnumber–Optional height in px (default 1080).
namestringyesDisplay name, e.g. 'TikTok short'.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
widthnumber–Optional width in px (default 1920).

No output schema declared.

No examples provided.

cut_to_angle ~277

MULTICAM angle switch. The angles are ordinary video tracks stacked over each other (sync them beforehand — clips of the same take on V1..Vn); this razors the whole angle stack at `atFrame` and keeps only `chosenTrackId` live from there to the next cut — the other angles' clips are DISABLED, not deleted, so every switch stays re-decidable (cut again with a different angle to change your mind). Linked audio follows the video by default (audioFollowsVideo: false keeps audio untouched — the usual choice when one good mic carries the sound). angleTrackIds defaults to every video track with a clip under the frame. Refused when the chosen track has no clip at the frame.

NameTypeReqDescription
angleTrackIdsarray–Optional explicit angle set (video track ids).
atFramenumberyesThe switch point (timeline frame).
audioFollowsVideoboolean–Default true: linked audio toggles with its angle.
chosenTrackIdstringyesThe angle to show from atFrame on.
projectIdstringyesProject id from get_projects.
timelineIdstringyesTarget timeline.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

download_sound ~192

Downloads one Freesound sound (its HQ MP3 preview, ~128 kbps — plenty for SFX/ambience) into the project's media pool as a virtual file at the Library root (name `freesound-<id>.mp3`). Asynchronous: the first call accepts the download and returns its state; CALL AGAIN with the same arguments to poll — state becomes 'done' with the asset's mediaRef, ready for add_clips onto an audio track. Three files stream at a time and the rest wait their turn, shared with stock video, so state 'queued' is normal and needs no action but polling.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
soundIdnumberyesThe sound id from search_sounds.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

download_stock_media ~320

Downloads one Pexels asset into the project's media pool as a virtual file at the Library root (name `pexels-<id>.jpg|.mp4`). Asynchronous: the first call accepts the download and returns its state; CALL AGAIN with the same arguments to poll — state becomes 'done' with the asset's mediaRef, ready for add_clips. maxHeight picks the best video rendition not exceeding it (default: the best available). ASK FOR THE WHOLE SHOT LIST AT ONCE — three files stream at a time and the rest wait their turn, so a batch is queued for you, in the order you asked. State 'queued' is normal and needs no action but polling. ONCE DOWNLOADED, CHECK THE MOMENT YOU MEAN TO USE — not just the first frame. A clip that opens on your subject can cut away, change subject or hold a logo exactly where you planned to trim. Read the scene samples from get_media, or render frames with inspect_media, across the range you intend to cut. See read_skill {topic:'verify'}.

NameTypeReqDescription
kindstringyesphoto | video
maxHeightnumber–Videos only: cap the rendition height (e.g. 1080).
pexelsIdnumberyesThe item id from search_stock_media.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

duplicate_timeline ~230

Copy a timeline under a new name — a backup of the cut before a review round changes it, or a variant to try something on. A DEEP copy: new ids for the timeline, its tracks, clips and transitions; links between clips (A/V pairs, caption groups) are kept, inside the copy. Nested timelines are copied too by default (includeNested), so editing a nest in the original does not change the backup; motion compositions and media are referenced, not copied. The original is not touched and stays the active timeline; one undo removes the copy. Returns {timelineId, name, clips, nestedCopies?}.

NameTypeReqDescription
includeNestedboolean–Copy nested timelines too (default true). false = the copy shares them with the original.
namestring–Name of the copy. Default '<name> copy'.
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline to copy.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

generate_captions ~398

Generates animated captions from a spoken clip's transcript (the same generator as Frapea's UI): transcript words group into caption text clips over the clip's span, word-timed so the animation follows speech. One undo, and they share a captionGroupId — restyle them all via set_clip_properties with text.wholeCaptionGroup. Needs a transcript (get_transcript tells you). Returns the created clip ids. PLACEMENT: they JOIN the existing caption track whenever they fit in its gaps, and only open a new one when they would overlap (a second language, a second layer). So captioning four narration segments in four calls leaves ONE caption track, not four — no tidying needed afterwards for this. Call manage_tracks {action:'tidy'} at the end of the build for the empty tracks left by everything else. They join the LOWEST caption track, so a picture layer you add ABOVE it after an earlier pass will cover them — captions render behind b-roll rather than looking wrong, which is the hardest kind of mistake to notice. Move the whole lane with manage_tracks {action:'merge'} if you want the captions on top.

NameTypeReqDescription
censorProfanityboolean–Star out profane words.
clipIdstringyesThe spoken clip to caption.
maxWordsPerCaptionnumber–Words per caption before a new one starts (default 4).
positionstring–bottom (default) | top.
presetstring–Style preset: clean (default) | boldPop | karaoke | highlight | minimal | editorial.
projectIdstringyesProject id from get_projects.
textCasestring–original (default) | upper | lower.
timelineIdstringyesTimeline containing the spoken clip.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

generate_voiceover ~1,021

Generates an AI voiceover from a script — on-device with the free models, or in the cloud with ElevenLabs (the user's own key and credits). The WAV lands in the project's media library as a normal audio asset (with waveform and analysis), the script is stored as asset metadata, and a script-corrected word-level transcript is written so captions work immediately. Narration is best generated before the picture is cut: a script does not tell you how long it takes to SAY, so a narrated edit assembled first is built on guessed cut points that the real audio then breaks — every section, graphic and transition has to be retimed. Generate the narration, read its word timings with get_transcript, then lay picture against those frames. Segments read better than one block (e.g. hook / body / close, or one per section), each laid on the timeline separately. A single long generation comes out FLAT and evenly paced, everything pressed together at one energy; segmenting gives each part its own intent, puts natural air at the joins, and lets you redo one section instead of all of it. Write for the ear: short sentences, one idea each, LINE BREAKS between them — the strongest signal the model has to actually stop. See read_skill {topic:'voiceover'}. Async: returns {jobId, fileName} — fileName is the audio file's final name in the project's media/ folder, decided up front (WAV for local providers, MP3 for ElevenLabs). The job runs on the analysis MASTER tab and its request is persisted on disk: it survives tab closes and browser restarts, and get_job_status answers from disk even in a fresh session. Poll until done; the finished job also carries the asset's mediaRef. Voices/languages come from list_voiceover_models; a local model must be downloaded first (phase 'ready'), otherwise this returns PERMISSION_REQUIRED. PREMIUM (provider 'elevenlabs' — SPENDS THE USER'S CREDITS): check list_voiceover_models' `elevenlabs` status object first. Structured refusals you must handle: NO_API_KEY…

NameTypeReqDescription
consentActionIdstring–The actionId from a CONSENT_REQUIRED refusal, after await_user_action returned 'granted'. Good for one job.
fileNamestring–Optional base name for the audio file written into media/.
languagestring–Language tag from the provider's manifest (e.g. 'en-us'). Ignored for ElevenLabs — its voices are multilingual.
modelIdstring–ElevenLabs only: TTS model id from list_voiceover_models (default 'eleven_v3' — expressive, reads [calm]-style audio tags as directions; use 'eleven_multilingual_v2' only when the user asks for v2; t…
projectIdstringyesProject id from get_projects.
providerstring–TTS provider id from list_voiceover_models (default 'kokoro'; 'elevenlabs' = premium, needs the user's key + consent).
speednumber–Speaking rate multiplier (default 1). Local providers accept 0.5–2; ElevenLabs 0.7–1.2.
textstringyesThe script to speak (multi-line ok).
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
voicestring–Voice id from the provider's manifest (default: its first voice for the chosen language).
voiceSettingsobject–ElevenLabs only: voice knobs, each optional. stability, similarityBoost and style are 0–1; speakerBoost is a boolean.

No output schema declared.

No examples provided.

get_analysis_status ~164

How far the project's media analysis has got. Analysis runs BY ITSELF whenever media is connected. Returns percent (0-100) — 100 means nothing is OUTSTANDING, not that everything succeeded: `failed` lists items whose analysis failed (retry_analysis re-runs one) — done/total/pending item counts, runningItem {mediaRef, kind, progress}, etaSeconds (null until something has finished), blockedOnModels, and models {visual, speech}. Poll this while you wait; when blockedOnModels is above zero, call request_ai_models.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_bug_report ~198

Prepare a BUG REPORT for the user: it opens in Frapea (Problems → Create bug report) for them to read and save. The report itself is NOT returned to you — it would leave the user's machine before they have seen it. You get a summary: open problems, media counts, and how many of the user's own words remain in composition code. It contains versions, problems with engine details, the project's structure with names and texts replaced, provider files by public id, the user's own files only as encoding fingerprints, and motion code. timelineIds limits it to those timelines and what they nest.

NameTypeReqDescription
projectIdstringyesProject id from get_projects (must be open in the editor).
timelineIdsarray–Only these timelines and the timelines they nest (default: all).
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_job_status ~179

Status of a background job started by a job-returning tool (generate_voiceover, verify_timeline, measure_loudness): {state: queued|running|done|failed|cancelled, progress: 0-1, detail, ...result fields such as mediaRef when done; verify_timeline, measure_loudness puts its report in `result`}. Poll every few seconds while state is 'queued' or 'running' (queued = waiting for the analysis master tab, which loads the models once for the whole browser). For analysis started by start_transcription or start_visual_indexing, poll get_analysis_status instead.

NameTypeReqDescription
jobIdstringyesId returned by the start_* tool.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_media ~396

Lists the project's media library: mediaRef (the id clips use), name, kind (video/audio/image), durationSeconds, resolution, and sceneSamples — timestamps (seconds) where the visual indexer detected distinct moments. sceneSamples is a ready-made shot map: inspect or cut at those times first. Each asset also carries visualIndex and transcript objects: {phase: 'ready'|'pending'|'queued'|'running'|'failed'|'no-audio'|'disabled', error, attempts, sealed}. Analysis starts by itself and retries a failure a few times before sealing it. If a phase is 'failed', read `error` and decide: call retry_analysis to run just that one analysis again, or leave it. If 'disabled', call request_ai_models. Video and audio assets also carry beats: {phase: 'ready'|'pending'|'failed'|'none', bpm, confidence}. These come from an ONSET detector (spectral flux): every energy rise — drum hits, plucks, syllables — not bars or downbeats. bpm is the tempo of those onsets, or null when there is no steady pulse (confidence 0–1 below the detector's 0.3, or too few onsets) — speech has onsets and no bpm. 'none' = no audio to analyze. Pass mediaRef to get ONE asset with beats.onsetsSec (source seconds, the first 2000; truncated + onsetCount say when there are more) — map them through the clip's trim and speed yourself.

NameTypeReqDescription
mediaRefstring–Optional: return only this asset, as {asset}, with its onset times. Omit to list every asset (no onset times).
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_motion_composition ~72

Returns a motion composition's manifest and full TSX sources.

NameTypeReqDescription
compositionIdstringyesComposition id.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_problems ~290

What has gone WRONG in the user's editor — renders that failed or stopped, footage that would not decode, chunks that could not be prepared for playback, exports that failed — each with WHERE (the timeline and frames, the source and its own frames, the footage and frame the engine could not decode) and the reason in the engine's own words. You also hear about new problems for free: every other tool result carries a `problems` list of what changed since your last call. Call this for the whole history, or after a `moreProblems` count. A problem that is open on a timeline means that timeline does NOT play or export correctly there, whatever inspect_timeline showed: fix the named layer (e.g. update_motion_composition) to fix it. `state` is open | fixed | superseded (the thing it was about was edited and not yet re-rendered — NOT proof it works) | dismissed.

NameTypeReqDescription
detailboolean–Include the engine's raw diagnostic text per problem (default false — it can be long).
includeResolvedboolean–Also list problems that are no longer open (default false).
projectIdstring–Project id from get_projects. Omit for every project in this browser.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_projects ~253

Lists the projects Frapea knows on this machine: id, name, lastOpenedAt, and for a project stored in a folder on disk its `folder` (the directory's name — files you write into its `media/` subfolder join the pool by themselves). Call first to find the projectId every other tool needs. A project the browser has no permission for will surface PERMISSION_REQUIRED when used — relay the returned instruction to the user, then retry. ALSO RETURNS `providers` — Pexels (stock video/photos), Freesound (music, ambience, SFX) and ElevenLabs (voiceover), each 'connected' | 'checking' | 'missing' | 'invalid'. These are the user's OWN API keys and they cannot be set from here. When any is not usable, `providersAdvice` is present: a short note for the user saying which and where they connect them (only the user can add a key). When everything is connected it is absent. A call that fails with PERMISSION_REQUIRED carries its own instruction for the user.

NameTypeReqDescription
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_timeline ~221

Reads a project's timeline structure: timelines (id, name, fps, resolution) with tracks and clips. THE USER CAN COPY A CLIP'S ID from the editor's right-click menu, so a bare UUID in their message names exactly one clip — call this with NO timelineId to search every timeline and match `clip.id`, rather than guessing from a name. Clips carry id, name, mediaRef, kind, startFrame, endFrame (exclusive), trimStartFrame and linkGroupId (linked A/V pairs share it), plus `look` (opacity, blend, transform, crop, keyframes) whenever any of it differs from the defaults — an untouched clip has no `look` key. Omit timelineId to get every timeline; frames are in that timeline's fps.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
timelineIdstring–Optional single timeline to read.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

get_transcript ~126

Returns the word-level speech transcript of one media asset: language and words [{text, startSec, endSec}]. Only assets the user has transcribed have one — NOT_FOUND means ask the user to run Transcribe on the clip in Frapea. Use the timestamps to align cuts with what is being said.

NameTypeReqDescription
mediaRefstringyesAsset reference from get_media.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

insert_clips ~136

Ripple-inserts media segments: everything at/after atFrame shifts right to make room (clips under the cut split). Same clip shape as add_clips. Use to splice a shot INTO an existing sequence without overwriting.

NameTypeReqDescription
atFramenumberyesInsertion point (timeline frame).
clipsarrayyes[{mediaRef, sourceInSec, sourceOutSec}]
projectIdstringyesProject id from get_projects.
timelineIdstringyesTarget timeline.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

inspect_media ~300

Looks INSIDE a source asset. Returns ONE contact sheet — every requested moment as a labelled cell in a single grid image — plus a per-cell fingerprint. Pass atSec (max 12 timestamps, seconds); combine with get_media's sceneSamples for an instant storyboard of the whole file. Shows the RAW source; use inspect_timeline for the composed cut. START WITH pixels:false WHEN YOU ARE ONLY CHECKING FOR EMPTINESS. The fingerprint answers 'is this black / flat / did it decode' for no image cost — nonBlankRatio near 0 is an empty or black frame, colorRange near 0 is a featureless one. Ask for pixels when you must judge WHAT is in the frame: subject, framing, legibility.

NameTypeReqDescription
atSecarrayyesTimestamps in seconds, max 12.
cellHeightnumber–Target px height per cell (default 300). Shrunk automatically if the sheet would exceed the response budget — the reply says so when that happens.
columnsnumber–Grid columns (default 3, or one row if ≤3).
mediaRefstringyesAsset from get_media.
pixelsboolean–False = fingerprints only, no image (default true).
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

inspect_timeline ~350

WATCHES the cut. Composites every video layer at each requested frame and returns ONE contact sheet — the frames as labelled cells of a single grid image — plus, per cell, the visibleClipIds that contributed pixels and a fingerprint. Pass frames (timeline frame numbers, max 12). Use it to check an edit: this is the only tool that shows what actually PLAYS, as opposed to what get_timeline says is arranged. SAMPLE THE CUT POINTS AND THE MIDDLE OF EACH SECTION, not only frame 0. An entrance animation that never resolves, a graphic clipped by its own box, an offline clip rendering black — all look perfect in get_timeline and are obvious here. USE pixels:false FOR A CHEAP SWEEP. visibleClipIds plus nonBlankRatio confirms 'the right clip is in every slot and none of them is black' across a dozen positions with no image cost; spend pixels on the few frames where you must judge typography, framing or timing.

NameTypeReqDescription
cellHeightnumber–Target px height per cell (default 300). Shrunk automatically if the sheet would exceed the response budget — the reply says so when that happens.
columnsnumber–Grid columns (default 3, or one row if ≤3).
framesarrayyesTimeline frame numbers, max 12.
pixelsboolean–False = structure + fingerprints only, no image (default true).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline to render.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

list_face_tracks ~123

Lists face-tracking runs and the people each one found: faceId, name, frame range, how many frames it was actually visible for, and how many gaps it has. Sample data is deliberately not returned. Use this to poll a queued run and to pick a faceId for bind_face.

NameTypeReqDescription
clipIdstring–Only runs made from this clip.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

list_motion_compositions ~79

Lists the project's motion compositions: id, mediaRef (for add_clips), name, size, fps, duration and the editable props schema.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

list_voiceover_models ~342

The text-to-speech providers Frapea can generate voiceovers with. Returns providers[]: the FREE in-browser models straight from the TTS registry ({id, label, languages, voices: [{id, label, language, gender, grade}], modelAssets, state: {phase: needs-download|downloading|ready|error}}), plus the PREMIUM cloud provider flagged premium: true ({id: 'elevenlabs', label, premium, voices: [{id, label}], models: [{id, label, creditsPerCharacter, supportsAudioTags, note}]}, voices/models empty until a key is stored). supportsAudioTags tells you whether that model understands inline audio tags like [calm], [laughs], [whispers] as delivery directions (only the v3 family does); on every other model such tags are READ ALOUD, so send those models plain text — each model's `note` restates its rule. Also returns a top-level status object `elevenlabs`: {provider: 'elevenlabs', hasApiKey, credits: {used, limit, remaining} | null, consent: 'ask' | 'always'} — READ IT BEFORE choosing the premium provider, so you know whether a key exists, what the account can afford and whether a consent dialog will be involved. A free provider whose phase is 'needs-download' cannot generate until the user enables it in the Generators panel (Voiceover) — there is no tool to force the download; ask the user.

NameTypeReqDescription
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

manage_effects ~627

Edits a clip's effect stack (ordered, per-effect enable). action: 'add' (type; returns the new effect's id) | 'remove' (effectId) | 'move' (effectId + toIndex — the order IS the render order) | 'toggle' (effectId + enabled) | 'set' (effectId + params patch, clamped to the effect's ranges) | 'curve' (effectId + curve + points). Types: 'colorBasic' (Lumetri Basic Correction-compatible: temperature/tint -100..100, exposure -5..5 stops, contrast/highlights/shadows/whites/blacks -100..100, saturation 0..300, vibrance -100..100), 'colorWheels' (Resolve lift/gamma/gain/offset — {group}Master/{group}R/G/B; lift/gamma 0 neutral, gain 1, offset printer points 25 neutral), 'lut' (.cube from the project library — set `resource`), 'curves' (tone curves), 'hueCurves' (hue-vs-hue/sat/lum). Also 'motionBlur' — NOT the shutter blur: a DIRECTIONAL blur filter (angle 0–360, distance 0–100) that smears every frame the same way whether the clip moves or not (a streak look, a speed effect on footage). For blur that follows the clip's own keyframed movement, use set_clip_properties motionBlur instead.

NameTypeReqDescription
actionstringyesadd | remove | move | toggle | set | curve
clipIdstringyesTarget clip.
curvestring–For 'curve': which curve to replace. 'curves' effect: master|r|g|b (tone, identity = [0,0,1,1]); 'hueCurves': hueHue|hueSat|hueLum (x = hue with red at 0, y 0.5 = untouched).
effectIdstring–Effect instance id (from a previous add or get_timeline).
enabledboolean–For 'toggle'.
paramsobject–For 'set': partial param patch, e.g. { exposure: 1.5 }.
pointsarray–For 'curve': flat control points [x0,y0,x1,y1,…] in the unit square.
projectIdstringyesProject id from get_projects.
resourcestring–For 'set' on resource effects ('lut'): the LUT's library name (a .cube imported into the project). Empty string clears it.
timelineIdstringyesTarget timeline.
toIndexnumber–Target position for 'move' (0 = applied first).
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
typestring–Effect type for 'add'.

No output schema declared.

No examples provided.

manage_queue ~217

Full control of the background work queue. action 'list' returns every queued/running item across all projects (analyses, proxies, beats) plus the visible task rows (downloads, voiceover jobs, failures) with a cancellable flag. action 'cancel' stops ONE kind of work for ONE asset — queued or already running (a running visual index stops at the next sample and keeps its checkpoint). The asset then shows an incomplete-analysis badge; retry_analysis or the tile's retry button runs it again. kind: index | transcribe | stabilize | denoise | proxy | beats.

NameTypeReqDescription
actionstringyeslist | cancel
kindstring–cancel only: index | transcribe | stabilize | denoise | proxy | beats
mediaRefstring–cancel only: asset from get_media.
projectIdstring–cancel only: project id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

manage_tracks ~530

Track operations on a timeline. action: 'mute' | 'unmute' | 'solo' | 'unsolo' (audio only; any solo silences non-solo tracks) | 'hide' | 'show' | 'rename' (needs name) | 'duck' | 'unduck' (audio only: dip this track under speech detected on the other audio tracks — transcript word timings when available, energy VAD otherwise) | 'merge' (needs intoTrackId: moves every clip of trackId onto another track of the same kind; refuses the WHOLE move if any clip would overlap, or if the source carries transitions) | 'delete' (an EMPTY track; refuses one that holds clips — deleting those is remove_clips, by name) | 'tidy' (NO trackId: drops the empty leftover tracks and renumbers). Track ids come from get_timeline. TIDYING UP, AND WHY ORDER MATTERS. Track counts only ratchet up while you build: a spare appears above whatever you fill, and the video and audio counts are kept EQUAL. That last rule is the one that surprises people — five video tracks force five audio tracks, however empty. So: 1. 'merge' the tracks that hold clips but need not be separate (captions from several passes, b-roll that never overlaps). This is what actually lowers the count. 2. 'tidy' once at the end. It settles both sides on one spare above the taller one and reports removedTracks. 'delete' on a single empty track usually reports removedTracks: 0 — the invariant puts it straight back to keep the counts equal. That is not a failure, it is why 'tidy' exists. Neither ever touches a clip, and both keep an empty track you renamed, muted, hid, soloed, unlocked or set to duck.

NameTypeReqDescription
actionstringyesmute | unmute | solo | unsolo | hide | show | rename | duck | unduck | merge | delete | tidy
intoTrackIdstring–Destination track (merge only) — same kind as trackId.
namestring–New name (rename only).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTarget timeline.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
trackIdstring–Track to modify. Required for every action except 'tidy'.

No output schema declared.

No examples provided.

manage_transitions ~343

Transitions on a track's cuts OR lone clip edges (a free head/tail takes a single-sided fade from/to nothing; its alignment is forced). action: 'add' (trackId + atFrame = the cut where one clip ends and the next starts, + type; optional durationFrames (default 30, clamped to the clips' source handles), alignment centered|start|end, params) | 'remove' (transitionId) | 'update' (transitionId + any of type/durationFrames/alignment/params). Types: crossDissolve, dipToBlack, dipToWhite, wipe (params.angle deg, params.softness 0-100), slide (params.angle), push (params.angle). Both clips need source material past the cut — a transition that cannot fit is refused; edits that break the cut remove it. Returns {ok, transitionId?}.

NameTypeReqDescription
actionstringyesadd | remove | update
alignmentstring–centered | start | end
atFramenumber–The cut frame for 'add'.
durationFramesnumber––
paramsobject–Type params patch (e.g. { angle: 90 }).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTarget timeline.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
trackIdstringyesTrack owning the cut (get_timeline).
transitionIdstring–Existing transition id.
typestring–Transition type.

No output schema declared.

No examples provided.

measure_loudness ~566

MEASURE THE MIX — you cannot hear it; this is how you check it. Mixes the timeline's audio offline exactly as an export does (every audio track, nested timelines, fades, volume keyframes, clip audio effects, ducking, mute/solo) and measures it with EBU R128 / ITU-R BS.1770 — the same meter export loudness normalization uses. The mix is measured AS MIXED: an export's loudnessTargetLufs would then shift all of it by one gain. Returns {jobId}; poll get_job_status every few seconds. When done, `result` is {durationSec, integratedLufs, truePeakDbtp (4× oversampled, BS.1770-4), samplePeakDbfs, loudnessRangeLu, maxShortTermLufs, windows: [{fromSec, toSec, integratedLufs, maxShortTermLufs}] one per windowSec, sections?: [...same per requested section], speech: {source: transcript|none, speechSec, gapSec, mixDuringSpeechLufs, mixInGapsLufs, transcribedClips, untranscribedClips}, tracks: [{trackId, name, carriesSpeech, integratedLufs, samplePeakDbfs, duringSpeechLufs, inGapsLufs}]} (true peak is measured on the whole mix). SPEECH comes from transcript word timings mapped onto the timeline (trims, nests, speed): a GAP is a stretch of at least 0.6 s with no word within 0.25 s of it. `inGapsLufs` of a music/ambience track is the bed's level where nobody talks; compare it with the speech track's `duringSpeechLufs`. Without a transcript (speech.source 'none') the speech/gap fields are null — run start_transcription on the dialogue first. Integrated values are gated (−70 LUFS absolute, −10 LU relative), so silence does not drag them down; null means too short (under 0.4 s) or silent. Needs the project open in the editor tab you are paired with (PROJECT_NOT_OPEN otherwise).

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
sectionsarray–Optional named spans to report on their own — e.g. the intro, each interview answer. Timeline seconds.
timelineIdstringyesTimeline to measure (what an export of it would sound like).
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
windowSecnumber–Length of each entry in `windows` (3–600 s, default 10).

No output schema declared.

No examples provided.

merge_faces ~158

Joins two or more faces from one run into a single person — for somebody who walked out of the shot and came back. REFUSED when any two of them appear on the same frame, since they cannot then be one person. The earliest face's id and name survive, so existing bindings keep working, and the time between sightings stays a gap for the clip's gap policy to handle.

NameTypeReqDescription
faceIdsarrayyesTwo or more faceIds within that run.
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
trackIdstringyesThe run, from list_face_tracks.

No output schema declared.

No examples provided.

move_clips ~123

Moves clips to new positions (linked partners follow automatically). Each move: clipId, toStartFrame, optional toTrackId (same-kind track). Overwrite semantics — landing on another clip trims it like a drag-drop.

NameTypeReqDescription
movesarrayyes[{clipId, toStartFrame, toTrackId?}]
projectIdstringyesProject id from get_projects.
timelineIdstringyesTarget timeline.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

new_project ~235

Creates a project. By default it is created in the browser's own storage, which needs no permission and no click: the project id comes back immediately and you can start working. The user can turn it into a real folder on their disk whenever they want (Cmd/Ctrl+S, or File → Save to a Folder) without losing anything. Pass storage:'folder' only when the user asked for a folder up front — that needs a browser security gesture, so it opens a dialog in Frapea with a 'Choose folder' button, returns an actionId, and you must tell the user IN YOUR REPLY to click it, then call await_user_action; on 'granted' the project appears in get_projects.

NameTypeReqDescription
namestringyesProject name, e.g. from the user's brief.
storagestring–Where the project lives. 'browser' (default) needs no user action. 'folder' asks the user to pick a directory on their disk.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

open_project ~104

Navigates the user's Frapea tab to a project so they can WATCH the edit live. Not required for editing — every tool works headlessly; use this for show-your-work moments. This reloads the Frapea tab, so an export or render running there stops.

NameTypeReqDescription
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

open_timeline ~150

Opens a timeline's TAB in the editor (the user can close tabs to keep the tab row short; a closed timeline is not deleted and every tool works on it as before). By default it does not change what the user is looking at; activate:true also shows it, like set_active_timeline. get_timeline reports `open` per timeline, as last saved.

NameTypeReqDescription
activateboolean–Also show it (default false).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline whose tab to open.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

organize_media ~148

Pool file operations. action: 'rename' renames the real file on disk (needs newName; clips referencing the old name go offline). 'delete' UNLINKS the file from the media pool — the real file on disk is NOT touched; clips using it go offline until it is added again.

NameTypeReqDescription
actionstringyesrename | delete
mediaRefstringyesAsset from get_media.
newNamestring–New file name incl. extension (rename).
projectIdstringyesProject id from get_projects.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

organize_pool ~485

THE MEDIA POOL'S SHAPE — bins (the pool's folders) and what sits in them. Use it to tidy a project: group the footage, the voice-over, the music and the graphics instead of leaving eighty files at the root. Bins are VIRTUAL and live in the project, not on disk. Moving an item between bins NEVER touches the file or its mediaRef, so it cannot break a clip's link or make the app ask the user to relocate anything — organise freely. actions: 'list' returns the bin tree and every item with the bin it shows in (call it first — you need the ids). 'create_bin' {name, parentBinId?}. 'rename_bin' {binId, name}. 'move_bin' {binId, toBinId} nests one bin inside another. 'delete_bin' {binId} — its children and items reparent, nothing is lost, no file is deleted. 'move_items' {itemKeys[], toBinId} moves files, timelines and motion compositions alike. Item keys: a media file's mediaRef, 'timeline:<id>', 'motion:<id>'. The Library root is the empty-string bin id. Bins that MIRROR a real folder (mirrorsFolder: true) can be RENAMED — a mirror is matched by the folder it tracks, not by its name — but they cannot be moved or deleted, because their place in the tree follows the folder. Move the items out instead, or make your own bins alongside.

NameTypeReqDescription
actionstringyeslist | create_bin | rename_bin | move_bin | delete_bin | move_items
binIdstring–Target bin (rename/move/delete).
itemKeysarray–move_items: mediaRefs / 'timeline:<id>' / 'motion:<id>' to move together.
namestring–Bin name (create_bin, rename_bin).
parentBinIdstring–Parent for create_bin. Omit or '' = Library root.
projectIdstringyesProject id from get_projects.
toBinIdstring–Destination bin for move_bin / move_items. Omit or '' = Library root.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

read_skill ~401

Returns Frapea's editing documentation for a topic. With no topic: the editing conventions, how the tools fit together and the current feature surface. MOTION topics: 'motion' is the API surface (imports, fonts, props schema, the parts-board-first golden example) and routes to the rest — read before create_motion_composition; 'motion-examples' (two finished pieces that differ in look); 'motion-craft' (anticipation, overshoot, stagger, the tells of machine-made motion — a companion to 'motion'); 'motion-text' (size floors, fitting copy that cannot clip, per-word animation, annotations); 'motion-effects' (grain, duotone, light leaks, blurs, glow); 'motion-transitions' (TransitionSeries, presentations, cut overlays); 'motion-sound' (where sound lives, the built-in SFX pack, placement and levels); 'motion-review' (the same loop as 'review', from a motion job). The CRAFT guides teach how to actually cut: 'core' (rhythm, b-roll, audio hierarchy, restraint — read first), then the format you are making — 'shorts' | 'longform' | 'podcast' | 'tutorial' | 'montage'. Also 'voiceover' (narration in segments, not one block), 'verify' (how to check a cut before export) and 'review' (rounds of critique against rendered frames, for a piece with an audience).

NameTypeReqDescription
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
topicstring–Optional. Motion: motion | motion-examples | motion-craft | motion-text | motion-effects | motion-transitions | motion-sound | motion-review. Craft: core | shorts | longform | podcast | tutorial | mo…

No output schema declared.

No examples provided.

remove_clips ~112

Deletes clips (lift — leaves a gap). Linked partners are NOT removed automatically; pass both ids of a pair to delete it whole. To close the gap too, use ripple_delete_ranges instead.

NameTypeReqDescription
clipIdsarrayyesClip ids to delete.
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline containing the clips.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

remove_silence ~146

Cuts silent gaps inside a clip: any pause between transcribed words longer than minGapSec becomes a ripple delete (a small margin is kept so speech never clips). Typical minGapSec: 0.6 tight, 1.0 balanced, 1.5 loose.

NameTypeReqDescription
clipIdstringyesThe clip to tighten.
minGapSecnumberyesMinimum pause length to cut (seconds).
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline containing the clip.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

remove_words ~164

Text-based editing: cuts the given transcript words OUT of a clip as ripple deletes (everything after each cut shifts left). wordIndices are positions in get_transcript's words array for the clip's media. Contiguous indices merge into single cuts. The go-to tool for removing filler words or tightening an interview.

NameTypeReqDescription
clipIdstringyesThe clip whose speech is being edited.
projectIdstringyesProject id from get_projects.
timelineIdstringyesTimeline containing the clip.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.
wordIndicesarrayyesIndices into get_transcript words, e.g. [4,5,6,12].

No output schema declared.

No examples provided.

request_ai_models ~122

Asks the user to enable Frapea's on-device AI analyzers (picture search, speech). Opens a dialog in every Frapea tab and returns an actionId — tell the user IN YOUR REPLY to confirm it, then call await_user_action and poll get_analysis_status until models are enabled. Call this when get_media reports 'needs-models'.

NameTypeReqDescription
projectIdstringyesProject the work belongs to.
tokenstringyesThe session token `connect` returned. Pass it on every call — it says which browser to drive.

No output schema declared.

No examples provided.

Install

How do I install the Frapea MCP server?

Frapea is a hosted endpoint at https://app.frapea.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · app.frapea.com

# add to Claude Code
claude mcp add --transport http com-frapea-editor 'https://app.frapea.com/mcp'
Common questions

What is the Frapea MCP server?

Frapea is an MCP server listed in the public MCP registry as com.frapea/editor. A video editor in your browser that your AI drives: cuts, captions, multicam, motion titles, export. This page covers its hosted endpoint (https://app.frapea.com/mcp).

Is the Frapea MCP server safe to use?

Frapea scores 68 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Frapea MCP server expose?

Frapea exposes 67 tools: connect, get_projects, get_timeline, get_media, get_transcript, and 62 more. Their descriptions and schemas cost roughly 17,950 tokens of context every time the server is loaded.

Does the Frapea MCP server require authentication?

No. We connected to Frapea without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the Frapea MCP server still maintained?

Frapea is still listed as active in the MCP registry. We last reached this channel on 23 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.