Reelsaw
OCI · GHCR.IO/OSBYTES/REELSAW
Drive a self-hosted Reelsaw: turn long videos into vertical clips, edit, re-render and export them.
Available components
Last scanned (1 hour ago)
Scores higher than 86% of OCI servers
Category Design and Media
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security0
- No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.Unverified
- Known CVEs could not be checked: this image's dependency list comes from an SBOM its publisher attached, which nothing verifies, so we will not report it as a clean result.Unverified
- Install-script risk not yet assessed.Unverified
- Dependency health could not be checked: this image's dependency list comes from an SBOM its publisher attached. It names packages and versions but not whether each is deprecated, still maintained or linked to its source, so there is nothing we can fairly grade.Unverified
Provenance & Transparency100
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to osbytes/reelsaw). View diagnostics → Pass
- Clear OSI-approved license (AGPL-3.0).Pass
- Actively maintained (last published 0 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability66
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 15138 tokens (~180/item across 84 items; 84 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 Management17
- Stability observed for 5 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety95
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 11 of 14 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "test_webhook" implies "send" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Partial
- An AI judge read all 85 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Unverified: 1 category
A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.
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.
- 5 Nov 26 +1
- Package version: 0.31.0 → 0.32.0 functional
- 2 Nov 26 +1
- Stability: 0.03 → unverified ▼ security
- Tool safety: pass → unverified ▼ security
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- First check of Schema quality: unverified functional
- Package version: 0.30.3 → 0.31.0 functional
- Package version: 0.30.3 → 0.30.4 functional
- 1 Nov 26 0
- Stability: 0.00 → unverified ▼ security
- Tool safety: pass → unverified ▼ security
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- First check of Schema quality: unverified functional
- Package version: 0.30.1 → 0.30.3 functional
- Package version: 0.30.1 → 0.30.2 functional
- 31 Oct 26 50
First indexed and scored.
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 5 Nov 2026 · Analysed oci/ghcr.io/osbytes/reelsaw@0.32.0
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | oci |
| Reason | Verified |
| Discovered via | OCI referrers API |
| Source repo | osbytes/reelsaw |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/osbytes/reelsaw/.github/workflows/release.yml@refs/tags/v0.32.0 |
| Rekor log index | 3692516147 |
| Predicate type | SLSA build provenance https://slsa.dev/provenance/v1 |
| Subject digest | sha256:8a5ba67d1f86b6ec86615ed771e8f7034facb010661648acfd2788c03b8f72d2 |
Background: How many MCP packages publish verified provenance →
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 →
add_asset Add library asset ~377
Add from exactly one source: a public url or an uploadId (video, image, GIF, SVG or sound) becomes one of your library uploads; a search_assets catalog / provider hit (provider + externalId) materializes one instance-shared copy (checksum verified, license recorded; not listed in your library). Returns { id, name, kind, mime, durationSec, duplicate, restored, owner } (the same file twice returns the existing item). setDefault on an upload makes it your default intro/outro for NEW projects only.
| Name | Type | Req | Description |
|---|---|---|---|
| color | string | – | iconify hits only: icon color as hex, e.g. #ffffff (default white) |
| externalId | string | – | A search_assets hit's externalId, together with provider |
| imageSeconds | number | – | How long a still image shows as an intro/outro (1-10 s) |
| name | string | – | Library name (url or uploadId; default: the file name). update_asset changes it later |
| provider | string | – | A search_assets hit's provider (catalog or an enabled provider), together with externalId; materializes the instance-shared file instead of adding an upload |
| setDefault | string | – | Also make it your default intro or outro for new projects |
| tags | array | – | Search tags (lowercase words; max 20) |
| uploadId | string | – | An existing upload id (from POST /api/upload) instead of a url |
| url | string | – | http(s) link to a video (MP4/MOV/WebM), image (PNG/JPG/WebP/GIF/SVG) or sound (MP3/M4A/AAC/WAV/OGG/FLAC); the server downloads it into your library (max 50 MB, 60 s) |
No output schema declared.
No examples provided.
add_transcript_correction Correct transcript words ~166
Make captions show "text" instead of the words spoken between startSec and endSec (a misheard name, say); the span must cover whole words. Returns { ok, flagId, rerendered, hint }. Undo it by passing the flagId to review_transcript_flags with status rejected.
| Name | Type | Req | Description |
|---|---|---|---|
| endSec | number | yes | End of the words to correct, seconds |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| rerender | boolean | – | Re-render finished clips whose captions overlap the span (default true) |
| startSec | number | yes | Start of the words to correct, seconds from the start of the source video |
| text | string | yes | What the captions should say for that span |
No output schema declared.
No examples provided.
add_transcript_cut Cut transcript words ~148
Remove the words spoken between startSec and endSec from the transcript, so captions and the rendered video skip them; the span must cover whole words. Returns { ok, flagId, rerendered, hint }. Undo it by passing the flagId to review_transcript_flags with status rejected.
| Name | Type | Req | Description |
|---|---|---|---|
| endSec | number | yes | End of the words to cut, seconds |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| rerender | boolean | – | Re-render finished clips whose captions overlap the span (default true) |
| startSec | number | yes | Start of the words to cut, seconds from the start of the source video |
No output schema declared.
No examples provided.
apply_framing Apply framing to the project ~217
Make one clip's framing the whole project's, for a recording whose layout never changes (a slide deck with a webcam tile, a fixed camera): the clip's section at `at` (else its first framed section) gives the mode and its nudge / subject / crop, which become the project's reframe and reframeAdjust; every clip's own sections are cleared (unless keepOverrides) and the finished clips re-render. New clips get it too. Returns { reframe, adjust, cleared, rerendered }.
| Name | Type | Req | Description |
|---|---|---|---|
| at | number | – | Seconds from the start of the source: which section of the clip to copy (default: its first section that is not plain automatic) |
| clipId | string | yes | Clip whose framing to copy (from get_project or search_clips) |
| keepOverrides | boolean | – | Leave other clips' own sections in place; they still win over the project's framing (default false: clear them) |
| rerender | boolean | – | Re-render the finished clips now (default true) |
No output schema declared.
No examples provided.
apply_layer_template Apply layer template to clips ~248
Write a template onto clips of one project (up to 200 clipIds, or all): its layers fitted to each clip's length, and the intro / outro it sets as each clip's own. Not linked afterwards. mode replace (default) swaps the clips' layers, add keeps them and adds. rerender true re-renders finished clips now, else the next render shows them. update_project settings.layerTemplateId only affects clips created later. Returns { updated, rerendered, skipped: [{ clipId, reason }], layersSkipped, bumpers: slots set }
| Name | Type | Req | Description |
|---|---|---|---|
| clipIds | array | – | Clip ids of that project (get_project), 1-200; omitted = every clip of the project |
| mode | string | – | "replace" (default) = the template becomes the clip's layers; "add" = its layers join the ones the clip already has |
| projectId | string | yes | Project the clips belong to (list_projects) |
| rerender | boolean | – | true = re-render the affected finished clips now; false = the layers show on their next render |
| templateId | string | yes | Layer template id (list_layer_templates) |
No output schema declared.
No examples provided.
asset_usage Where a library asset is used ~112
Where a library item is used: as intro, outro, overlay or music on projects and clips (replaced clips left out), and in layer templates. Returns { projects: [{ id, title, slots, clips: [{ id, index, title, slots, via, overlays, music }] }], templates: [{ id, name, layers }] }. A deleted asset's layer is skipped when a template is applied. Check before deleting one.
| Name | Type | Req | Description |
|---|---|---|---|
| assetId | string | yes | Library asset id (from search_assets) |
No output schema declared.
No examples provided.
billing_checkout_url Checkout URL ~111
Hosted instances: a Stripe Checkout URL for a plan (or, when the account already pays, the Billing Portal page that confirms the plan change). Returns { url, kind: "checkout" | "change" }; a person must open it in a browser, an agent cannot pay. Plans and intervals come from get_billing.
| Name | Type | Req | Description |
|---|---|---|---|
| interval | string | – | Billing interval: month (default) or year |
| plan | string | yes | Plan name from get_billing (e.g. creator, pro) |
No output schema declared.
No examples provided.
billing_portal_url Billing portal URL ~60
Hosted instances: a Stripe Billing Portal URL to see invoices, change the card or cancel at period end. Returns { url }; a person must open it in a browser. On a self-hosted Reelsaw this answers that billing is not enabled.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
check_for_update Check for update ~109
Admins only: is a newer Reelsaw published? Returns { current, latest: { version, url, publishedAt }, available, checkedAt, error, upgrade: { command, note, docsUrl } }; available is null when the running build is not a release (from source). The server checks every few hours; refresh: true asks GitHub again now.
| Name | Type | Req | Description |
|---|---|---|---|
| refresh | boolean | – | true = ask GitHub now instead of returning the last answer (at most once a minute) |
No output schema declared.
No examples provided.
create_clip Create clip ~182
Add a clip from a time range of the source (needs a transcript). mode exact keeps your bounds (3 s-10 min); mode ai lets the model pick the best moment inside them (≥8 s). Returns the new clip summary { id, status: "preparing", queued: "prepare", hint }; preparation (title, hook, scores) is queued and the render follows by itself (about a minute), so poll get_clip until done. To change an existing clip use update_clip instead.
| Name | Type | Req | Description |
|---|---|---|---|
| endSec | number | yes | Range end, seconds |
| mode | string | – | exact = these bounds (default); ai = best moment inside them |
| projectId | string | yes | Project id (from list_projects, search_clips or create_project) |
| startSec | number | yes | Range start, seconds from the start of the source video |
No output schema declared.
No examples provided.
create_project Create project ~402
Start clipping a video from a URL (anything yt-dlp fetches) or a file you uploaded: POST /api/upload with the file as the body, header x-filename and your API key as Authorization: Bearer, then pass the uploadId it returns. Returns { id, title, status: "queued", next } at once; the pipeline (download, transcribe, pick, render) runs in the background for minutes, so follow with wait_for_project(id). Intro/outro default to your library defaults unless introAssetId/outroAssetId say otherwise.
| Name | Type | Req | Description |
|---|---|---|---|
| introAssetId | – | – | Library asset id (search_assets with source library) for the intro of every clip; null = no intro; omitted = your default intro |
| introSec | number | – | Seconds an intro image shows (1-10) |
| metadata | object | – | Your own key/value strings (≤20 keys, 1 KB), returned by get_project and sent in every webhook for this project, e.g. { runId: "n8n-123" } |
| outroAssetId | – | – | Same for the outro |
| outroSec | number | – | Seconds an outro image shows (1-10) |
| settings | object | – | Project settings; omit for the defaults (automatic clip count, 20–60 s clips, natural pauses, name fixes and the on-screen text scan on, filler removal off). Set refineDisfluency / disfluencyLlm true… |
| sourceUrl | string | – | http(s) URL of the video; give this or uploadId |
| title | string | – | Project title (default: the video's own title) |
| uploadId | string | – | Id returned by POST /api/upload (the file body, x-filename header, API key as Bearer); give this or sourceUrl |
No output schema declared.
No examples provided.
create_webhook Create webhook ~144
Subscribe a URL to events: project.created, project.done (with every clip, share links and the zip), project.failed, clip.done (also re-renders), clip.failed. This is how a Zapier or Make app subscribes (delete_webhook unsubscribes). Returns { endpoint, secret }: the whsec_ signing secret is shown only here; verify deliveries with any Standard Webhooks library. The URL must be public https unless the admin allows private networks.
| Name | Type | Req | Description |
|---|---|---|---|
| description | string | – | Your label, e.g. "n8n clips workflow" |
| events | array | yes | Events to send |
| url | string | yes | Where to POST (https) |
No output schema declared.
No examples provided.
delete_asset Delete library asset ~76
Delete one of your uploads: it leaves the library and your defaults and goes to Deleted. Projects and clips already using it keep rendering with it. Undo with restore_asset (list_deleted says how long it is kept); check asset_usage first. Returns { ok }.
| Name | Type | Req | Description |
|---|---|---|---|
| assetId | string | yes | Library asset id (from search_assets) |
No output schema declared.
No examples provided.
delete_clip Delete clip ~113
Delete one clip of a live project; a render in progress stops. It shows up on Deleted (list_deleted). Reversible: restore_clip brings it back for DELETED_RETENTION_DAYS (7 days by default). Storage still counts until purge_clip. For several clips of one project use delete_clips. Returns { changed, stoppedRender (a render in flight was stopped), renderQueued: false, restorable, storedBytes }.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Clip id (from get_project or search_clips) |
No output schema declared.
No examples provided.
delete_clips Delete clips ~132
Delete several clips of one live project in one step (the selection bar's Delete); renders in progress stop. Each shows up on Deleted (list_deleted) and restore_clip brings it back for DELETED_RETENTION_DAYS. Already-deleted ids are skipped. Storage still counts until purge_clip. Returns { deleted, skipped, stoppedRenders, renderQueued: false, restorable, storedBytes }.
| Name | Type | Req | Description |
|---|---|---|---|
| clipIds | array | yes | Clip ids of that project (get_project), 1-200 |
| projectId | string | yes | Project id (from list_projects, search_clips or create_project) |
No output schema declared.
No examples provided.
delete_layer_template Delete layer template ~82
Delete a template (it goes to Deleted) and drop it from your project defaults; clips that already got its layers keep them. Undo with restore_layer_template (list_deleted says how long it is kept). Returns { ok, clearedDefault } (it was your default and no longer is)
| Name | Type | Req | Description |
|---|---|---|---|
| templateId | string | yes | Layer template id (list_layer_templates) |
No output schema declared.
No examples provided.
delete_project Delete project ~152
Delete one of your projects and all its clips; work in progress stops. Reversible: restore_project brings it back for DELETED_RETENTION_DAYS (7 days by default). Storage still counts until purge_project (or the retention sweep) removes it for good; minutes already used stay counted. Returns { changed, restorable, storedBytes, forgetDecisions, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| forgetDecisions | boolean | – | Forget what Reelsaw learned from it (its decision log entries) when it is deleted for good, by purge_project or the retention sweep; restoring it cancels that. Default false keeps them |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
No output schema declared.
No examples provided.
delete_webhook Delete webhook ~51
Remove a webhook (unsubscribe); nothing more is sent to it and its delivery log goes with it. Returns { ok, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Webhook id (from list_webhooks) |
No output schema declared.
No examples provided.
export_decisions Export decisions ~151
A page of your decision log in export form, oldest first, for evals. Returns { items (one decision each, the same objects `reelsaw decisions export` writes as JSON lines), cases: { disfluency: [eval cases in eval/fixtures/disfluency/cases.json shape, split dev/heldout by project] }, nextCursor }. Pass nextCursor back until it is null.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | integer | – | nextCursor from the previous page |
| kind | string | – | Only this kind of decision |
| limit | integer | – | Page size (1-1000, default 200) |
| since | string | – | Only decisions made at or after this ISO time |
No output schema declared.
No examples provided.
export_project Export clips ~147
A download link for a zip of the project's rendered clips with YouTube/TikTok metadata. Same conditions as the app's Export: the project must be live and at least one picked clip rendered, else the answer says why (not found, or nothing rendered yet). Returns { url, clips (rendered, in the zip), notRendered (picked but not finished, left out) }; the link needs the same Authorization header as this server.
| Name | Type | Req | Description |
|---|---|---|---|
| clipIds | array | – | Only these clips (max 200; must be rendered clips of the project); omitted = every rendered clip |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
No output schema declared.
No examples provided.
forget_decisions Forget decisions ~73
Delete entries from your decision log so Reelsaw stops learning from them: one project's (projectId, live or already deleted forever) or, without projectId, all of them. Cannot be undone. Returns { forgotten, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| projectId | string | – | Only this project's decisions; omitted = everything |
No output schema declared.
No examples provided.
get_billing Billing ~101
Hosted instances: your plan and subscription, the billing period, the limits in force with where each comes from (instance, plan, an admin's override), what you have used this period, whether renders carry a watermark, and the plans on offer. Returns { enabled, plan, reason, subscription, period, limits, limitSource, usage, watermark, canManage, plans }. On a self-hosted Reelsaw this answers that billing is not enabled.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_clip Get clip ~136
Everything about one clip: text, bounds, scores, emphasis, layers (assets, text, sounds), render diagnostics, video/thumbnail/editor links, and what the next render will use with where each comes from: style { own, effective, from: clip|project|default }, framing { own, effective: { mode, adjust, sections }, from }, bumpers { own, effective } (intro/outro). Returns the clip object. get_project lists all clips in brief; poll this after an edit to see the render finish (status done).
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Clip id (from get_project or search_clips) |
No output schema declared.
No examples provided.
get_clip_captions Get clip captions ~141
The captions of a clip's last render as an SRT or WebVTT file: the same lines and times as the video (intro included), even when the style has captions off. Returns the file text; VTT with words: true adds karaoke word timestamps. A clip rendered before caption files existed answers that it needs a re-render (rerender_clip).
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | – | srt (default) or vtt |
| id | string | yes | Clip id (from get_project or search_clips) |
| words | boolean | – | VTT only: add a <timestamp> before every word after the first in each cue |
No output schema declared.
No examples provided.
get_email_preferences Email preferences ~55
Which optional emails you get, by topic. Returns { emailEnabled, emailPreferences: { ready } }; ready is the note sent when projects finish while you are away. emailEnabled false means this instance sends no mail at all.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_failure Get a failed project or clip ~102
Admins only: one failed project or clip (title, owner email, stage, full recorded reason, when). A clip whose project also failed is not returned — retry the project. Returns the item or null if it is gone (retried, deleted). Hosted non-admins are refused.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Project id or clip id |
| kind | string | yes | project = the whole pipeline stopped; clip = one clip failed to prepare or render |
No output schema declared.
No examples provided.
get_instance_settings Instance settings ~95
Admins only: the instance settings in force (sign-up mode, email verification, captcha, legal links, quotas, upload limits, retention, stall watchdog, update check, health details) and where each comes from. Returns { values, env, override, source: { KEY: "env" | "db" }, ignored: { KEY: reason }, groups, help, updatedAt, updatedBy }; secrets are masked.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_media_links Get share links ~261
Links anyone can download without an Authorization header, for a scheduler (Buffer, Metricool), Instagram's video_url, Zapier/Make or a person. Returns { clips: [{ clipId, links: { clip, thumb, srt, vtt } }], export } with each link's { linkId, url, expiresAt }; unrendered clips say why. The active link is reused unless label or ttlDays ask for a separate one. A link serves the current render until it expires or revoke_media_link turns it off.
| Name | Type | Req | Description |
|---|---|---|---|
| clipIds | array | – | Only these clips; omitted = every rendered clip |
| export | boolean | – | Also a link to the zip of these clips with YouTube/TikTok metadata |
| kinds | array | – | Which files (default: clip): clip = the MP4, thumb = its JPEG, srt / vtt = its captions |
| label | string | – | A name for a separate link you can revoke on its own, e.g. "Buffer queue" |
| projectId | string | yes | Project id (from list_projects, search_clips or create_project) |
| ttlDays | – | – | Days the links last (capped by the instance); null = never expires where allowed |
No output schema declared.
No examples provided.
get_project Get project ~106
One of your projects: status, settings, effective intro/outro, transcript summary, and every clip (id, title, hook, bounds, score, status, download links); replacedClips lists deleted or replaced clips for restore_clip. Returns the project object. For one clip's full detail use get_clip, for the words get_transcript, for the pipeline history get_project_events.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
No output schema declared.
No examples provided.
get_project_defaults Get project defaults ~66
The settings every new project starts with (Settings, Project defaults): language, vocabulary, instructions, focus, clip lengths, pauses, caption look and refine steps. Returns { projectDefaults }; keys you never set are absent and use the built-in value. Change them with set_project_defaults.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_project_events Project activity ~115
The project's pipeline history, newest first (the same events the Activity panel shows; live progress ticks are not stored): stage starts and completions, clip renders, retries, failures with reasons. Returns [{ at, type, ...details }]. Use it to find out why something failed or is slow; get_project shows the current state.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| limit | integer | – | Most events to return (1-200, default 50) |
No output schema declared.
No examples provided.
get_project_transcript_file Get transcript file ~124
The project transcript as an SRT or WebVTT subtitle file, one cue per transcript segment, in source-video seconds. Returns the file text; VTT with words: true adds word timestamps. Use get_transcript to read it as plain timed lines instead.
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | – | srt (default) or vtt |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| words | boolean | – | VTT only: add a <timestamp> before every word after the first in each cue |
No output schema declared.
No examples provided.
get_queue Queue summary ~86
Admins only: waiting, running and retrying job counts per pipeline stage with when the longest wait began (oldestWaitingAt), plus the jobs currently in flight (project title, attempt, started, and a retrying job's lastError). Returns { queues, active, truncated, error? }. Failed work is list_failures, not this. Hosted non-admins are refused.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_transcript Get transcript ~139
The project's transcript as timed lines "[m:ss] text", optionally only a time range. Returns text; output longer than maxChars is cut with a note saying which fromSec to continue from. Use it to pick your own moments for create_clip.
| Name | Type | Req | Description |
|---|---|---|---|
| fromSec | number | – | Start of the range, seconds from the start of the video |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| maxChars | integer | – | Cut the output at this many characters (1000-200000, default 60000) |
| toSec | number | – | End of the range, seconds |
No output schema declared.
No examples provided.
import_transcript Import transcript ~221
Use an SRT or WebVTT file as the project's transcript instead of transcribing: right after create_project (only the video is fetched) or on a done or failed project (it then re-cleans the transcript and picks clips again). Give exactly one of text, uploadId or url. Returns { format, cues, words, warnings, message }; follow with wait_for_project.
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | – | auto (default) decides from the WEBVTT header |
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| language | string | – | Language code of the text, e.g. en, es, ja (default: the existing transcript's, else unknown) |
| text | string | – | The contents of the .srt or .vtt file |
| uploadId | string | – | Upload id of an .srt/.vtt file sent to POST /api/upload |
| url | string | – | http(s) link to a public .srt/.vtt file |
No output schema declared.
No examples provided.
list_decisions List decisions ~184
Your decision log: what you accepted, rejected, cut, corrected, edited, deleted or restored, newest first, kept after a project is deleted so Reelsaw learns from it. Returns { summary: { enabled, total, projects, byKind }, items: [{ id, kind, explicit, projectId, clipId, before, after, context, models, source, createdAt }], nextCursor, total }. kinds are fix.* (transcript fixes) and clip.*; clip.replaced (explicit false) is a pick a re-analyze replaced.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | integer | – | nextCursor from the previous page |
| kind | string | – | Only this kind of decision |
| limit | integer | – | Page size (1-200, default 50) |
| projectId | string | – | Only decisions about this project (it may already be deleted) |
No output schema declared.
No examples provided.
list_deleted List deleted items ~121
Restorable deletes (the Deleted page): one newest-first list of projects, clips of live projects, library items and templates. Returns { items: [{ kind, id, title, deletedAt, purgeAt, storedBytes, canPurge, … }], total, truncated } (max 200) plus keepDays / libraryDays / templateDays. purgeAt null = kept until deleted forever. restore_project / restore_clip / restore_asset / restore_layer_template bring them back; purge_project / purge_clip / purge_asset / purge_layer_template remove them for good.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
list_failures List failed work ~158
Admins only: failed projects and clips across the instance (owner email, stage, reason, when). A failed project's clips are not listed separately — retry the project. Returns { items, nextCursor, total, limit, truncated }. Filter with q (substring of the error), stage, since (ISO time). Hosted non-admins are refused.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | nextCursor from the previous page |
| limit | integer | – | Page size, default 50 |
| q | string | – | Case-insensitive substring of the recorded error (e.g. disk, encoder, model) |
| since | string | – | ISO timestamp; only failures updated at or after this time |
| stage | string | – | Pipeline stage that failed |
No output schema declared.
No examples provided.
list_layer_templates List layer templates ~175
Your layer templates (layers that fit any clip length, plus an optional intro / outro), newest first. Returns { items: [{ id, name, layerCount, layers, bumpers, updatedAt }], nextCursor, total, deleted } (nextCursor goes in cursor; deleted = restorable). A layer has the clip-layer fields plus timing { mode, start, end, minSec, maxSec }: head = seconds after the start; tail = seconds before the end (end 0 = the very end); fill = whole clip; relative = fractions 0-1 of the length, held between minSec and maxSec
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | nextCursor from the previous page; omit for the first page |
| limit | integer | – | Templates per page (1-500, default 100) |
No output schema declared.
No examples provided.
list_media_links List share links ~138
Your share links, newest first. Returns { items: [{ id, kind, projectId, clipId, title, url (masked), label, source, state (active | expired | revoked), expiresAt, lastUsedAt, useCount }], nextCursor, total }. Use get_media_links for a full URL.
| Name | Type | Req | Description |
|---|---|---|---|
| active | boolean | – | Only links that still work |
| clipId | string | – | Only this clip's links |
| cursor | string | – | nextCursor from the previous page |
| limit | integer | – | Links per page (1-100) |
| projectId | string | – | Only this project's links |
No output schema declared.
No examples provided.
list_projects List projects ~162
Your projects, most recently updated first. Returns { projects: [{ id, title, status, stage, clips: "n/m rendered", url }], total, nextCursor }; pass nextCursor as cursor for the next page. deleted: true lists restorable deletes (storedBytes still count until purge_project). For every kind of restorable delete (projects, clips, library, templates) use list_deleted. Use get_project for one project's clips, search_clips to find by words.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | nextCursor from the previous page; omit for the first page |
| deleted | boolean | – | true = only deleted projects that restore_project can still bring back |
| limit | integer | – | Projects per page (1-100, default 24) |
No output schema declared.
No examples provided.
list_releases List releases ~123
Published Reelsaw versions from GitHub (reelsaw.com/releases): tag, date, a short summary and the change notes. Returns { releases, total, windowDays, commits, commitDays, releaseDays, truncated, fetchedAt, sourceUrl, error }; pass tag for one version. Cached for an hour.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | How many releases to return (1-100, default 20, newest first) |
| tag | string | – | Only this tag or version (v0.19.1 or 0.19.1) |
No output schema declared.
No examples provided.
list_transcript_flags List transcript fixes ~151
The fixes Reelsaw made or suggests in a project's transcript: misheard names, fillers and repetitions to cut, and your own cuts and corrections. Returns { total, flags: [{ id, kind, subkind, status, start, end, heard, suggested, replacement, confidence }] }; status pending waits for your decision. Use the ids with review_transcript_flags.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Project id (from list_projects, search_clips or create_project) |
| limit | integer | – | Most fixes to return (1-500, default 100) |
| status | string | – | Only fixes in this state; omitted = all (pending = waiting for review, auto = applied automatically) |
No output schema declared.
No examples provided.
list_webhook_deliveries List webhook deliveries ~156
The delivery log, newest first. Returns { items: [{ id, endpointId, eventId, type, projectId, status (pending | sending | delivered | failed | cancelled), attempt, lastStatusCode, lastError, nextAttemptAt, deliveredAt }], nextCursor, total }. Failed deliveries were retried 8 times over about 22 h.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | integer | – | nextCursor from the previous page |
| endpointId | string | – | Only this webhook's deliveries (from list_webhooks) |
| limit | integer | – | Deliveries per page (1-100) |
| projectId | string | – | Only deliveries about this project |
| status | string | – | Only deliveries in this state |
No output schema declared.
No examples provided.
list_webhooks List webhooks ~74
Your webhook endpoints. Returns [{ id, url (masked), description, events, status (active | failing | off), disabledReason, failingSince, lastDelivery }]. Reelsaw POSTs signed JSON (Standard Webhooks headers webhook-id, webhook-timestamp, webhook-signature) to each when a subscribed event happens.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
list_workers List workers ~138
Admins only: every Reelsaw process that has checked in (API, worker, combined app): CPU, memory, disk (free/total MB, -1 = unmeasurable; diskLeasedMB = claimed by jobs in flight), GPU, render slots, queues it listens on, and its jobs. A worker out of disk drops the media queues from `queues` until it recovers. `paused` = what it was short of (memory, CPU, disk), null when it has room. Returns { items, live, stale }; stale = no check-in for 45 seconds. Hosted non-admins are refused.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
purge_asset Delete library item forever ~83
Permanently remove an already-deleted library upload and its files so the storage is freed (find it with list_deleted). Refused while a project, clip or live template still names it. An item that is not deleted is refused: call delete_asset first. Returns { storedBytes, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| assetId | string | yes | Library asset id (from list_deleted) |
No output schema declared.
No examples provided.
purge_clip Delete clip forever ~79
Permanently remove a deleted clip of a live project and its rendered file so the storage is freed (find it with list_deleted). A clip that is not deleted is refused: call delete_clip first. Clips of a deleted project go with purge_project. Returns { storedBytes, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Clip id (from list_deleted) |
No output schema declared.
No examples provided.
purge_layer_template Delete layer template forever ~74
Permanently remove an already-deleted layer template (find it with list_deleted). Templates hold no media files; this only drops the row. A template that is not deleted is refused: call delete_layer_template first. Returns { ok, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| templateId | string | yes | Layer template id (list_layer_templates) |
No output schema declared.
No examples provided.
purge_project Delete project forever ~156
Permanently remove a deleted project and its files so the storage is freed (find it with list_deleted or list_projects deleted: true). Minutes, hourly creates and first-video-free are not refunded. A project that is not deleted is refused: call delete_project first. What you decided about it (accepted and rejected fixes, clip edits) stays in your decision log so Reelsaw keeps learning from it, unless forgetDecisions is true. Returns { storedBytes, forgottenDecisions, message }.
| Name | Type | Req | Description |
|---|---|---|---|
| forgetDecisions | boolean | – | Also forget what Reelsaw learned from this project (its entries in the decision log); default false keeps them |
| id | string | yes | Project id (from list_projects with deleted: true) |
No output schema declared.
No examples provided.
How do I install the Reelsaw MCP server?
Reelsaw runs locally as a container image, launched with docker run --rm -i ghcr.io/osbytes/reelsaw:0.32.0. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.
oci · ghcr.io/osbytes/reelsaw
claude mcp add osbytes-reelsaw -- docker run --rm -i ghcr.io/osbytes/reelsaw:0.32.0
What is the Reelsaw MCP server?
Reelsaw is an MCP server listed in the public MCP registry as io.github.osbytes/reelsaw. Drive a self-hosted Reelsaw: turn long videos into vertical clips, edit, re-render and export them. This page covers its container image (ghcr.io/osbytes/reelsaw).
Is the Reelsaw MCP server safe to use?
Reelsaw scores 52 out of 100 on VerifyMCP. Its build provenance is signed and verified. 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 Reelsaw MCP server expose?
Reelsaw exposes 84 tools: list_projects, get_project, create_project, update_project, wait_for_project, and 79 more. Their descriptions and schemas cost roughly 14,095 tokens of context every time the server is loaded.
Is the Reelsaw MCP server still maintained?
Reelsaw is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the Reelsaw MCP server under?
Reelsaw declares the AGPL-3.0 licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.