@clipform/mcp-server 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -18535,6 +18535,7 @@ var MediaAssetItemSchema = external_exports.object({
|
|
|
18535
18535
|
).min(1).describe("Per-word timestamps within the segment. Required - copy the full array from clipform_generate_tts verbatim.")
|
|
18536
18536
|
})
|
|
18537
18537
|
).optional().describe("Word-level captions from clipform_generate_tts. `words` is a required field on each caption (schema-enforced) - pass the full objects returned by clipform_generate_tts unmodified."),
|
|
18538
|
+
caption_ref: external_exports.string().optional().describe("caption_ref from clipform_generate_tts - an opaque handle that attaches that TTS run's word-level captions to this asset, resolved server-side. Preferred over captions."),
|
|
18538
18539
|
ai_generated: external_exports.boolean().optional().describe("Whether this media was AI-generated. Drives the viewer's disclosure chip - set true for AI-rendered/synthesized media.")
|
|
18539
18540
|
});
|
|
18540
18541
|
function registerUploadMediaAssetTool(server) {
|
|
@@ -18544,7 +18545,7 @@ function registerUploadMediaAssetTool(server) {
|
|
|
18544
18545
|
title: "Upload Media Asset",
|
|
18545
18546
|
description: `Put one or more media files into your workspace media library (max 10, uploaded sequentially). This is step one of attaching media to a node - follow up with clipform_attach_node_media to place the returned media_asset_id on a node.
|
|
18546
18547
|
|
|
18547
|
-
When a public URL is provided, the media is fetched and stored automatically. For video: ingested via Mux. For image: stored in Supabase.
|
|
18548
|
+
When a public URL is provided, the media is fetched and stored automatically. For video: ingested via Mux. For image: stored in Supabase. Word-level captions from clipform_generate_tts enable per-word highlighting in the viewer once attached - pass the caption_ref it returned instead of hand-copying the captions array.`,
|
|
18548
18549
|
inputSchema: {
|
|
18549
18550
|
items: external_exports.array(MediaAssetItemSchema).min(1).max(10).describe("One or more media items to create as workspace library assets")
|
|
18550
18551
|
},
|
|
@@ -18592,6 +18593,7 @@ When a public URL is provided, the media is fetched and stored automatically. Fo
|
|
|
18592
18593
|
};
|
|
18593
18594
|
if (item.url) createBody.url = item.url;
|
|
18594
18595
|
if (item.captions) createBody.captions = item.captions;
|
|
18596
|
+
if (item.caption_ref) createBody.caption_ref = item.caption_ref;
|
|
18595
18597
|
if (item.ai_generated !== void 0) createBody.ai_generated = item.ai_generated;
|
|
18596
18598
|
const created = await callApi(`/workspaces/${workspaceId}/media`, { method: "POST", body: createBody });
|
|
18597
18599
|
if (!created.ok) {
|
|
@@ -18629,7 +18631,9 @@ When a public URL is provided, the media is fetched and stored automatically. Fo
|
|
|
18629
18631
|
} else {
|
|
18630
18632
|
resultLines.push(`Media stored in the workspace library.`);
|
|
18631
18633
|
}
|
|
18632
|
-
if (item.
|
|
18634
|
+
if (item.caption_ref) {
|
|
18635
|
+
resultLines.push(`Captions resolved from caption_ref.`);
|
|
18636
|
+
} else if (item.captions) {
|
|
18633
18637
|
resultLines.push(`Captions: ${item.captions.length} segments saved`);
|
|
18634
18638
|
}
|
|
18635
18639
|
lines.push(resultLines.join("\n"));
|
|
@@ -19082,7 +19086,7 @@ Available voices: ryan (British male, clear), sonia (British female, warm), andr
|
|
|
19082
19086
|
|
|
19083
19087
|
Use the tone parameter to direct HOW the voice speaks. Always set a tone that matches the form's mood - e.g. quizzes: "Energetic and playful, like a quiz show host teasing the audience", surveys: "Professional but warm, encouraging honest answers", personality quizzes: "Curious and reflective". This dramatically improves the narration quality.
|
|
19084
19088
|
|
|
19085
|
-
Pass one item or many (max 10) - multiple items run in parallel. Returns
|
|
19089
|
+
Pass one item or many (max 10) - multiple items run in parallel. Returns audio_url and caption_ref per item - pass caption_ref downstream to clipform_render_composition / clipform_render_video_template / clipform_upload_media_asset to attach this run's word-level captions instead of hand-copying the captions array.`,
|
|
19086
19090
|
inputSchema: {
|
|
19087
19091
|
items: external_exports.array(TtsItemSchema).min(1).max(10).describe("One or more TTS items to generate")
|
|
19088
19092
|
},
|
|
@@ -19091,7 +19095,8 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio U
|
|
|
19091
19095
|
external_exports.object({
|
|
19092
19096
|
ok: external_exports.boolean(),
|
|
19093
19097
|
audio_url: external_exports.string().optional(),
|
|
19094
|
-
|
|
19098
|
+
caption_ref: external_exports.string().optional().describe("Pass this as the caption_ref param on clipform_render_composition / clipform_render_video_template / clipform_upload_media_asset to attach this run's word-level captions - never hand-copy the captions array."),
|
|
19099
|
+
captions: external_exports.array(CaptionSchema2).optional().describe("Word-level captions, for reference only - prefer passing caption_ref downstream instead of copying this array."),
|
|
19095
19100
|
error: external_exports.string().optional()
|
|
19096
19101
|
})
|
|
19097
19102
|
).describe("One result per item, in order")
|
|
@@ -19118,6 +19123,9 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio U
|
|
|
19118
19123
|
successCount++;
|
|
19119
19124
|
const data = r.value.data;
|
|
19120
19125
|
lines.push(`Audio URL: ${data.audioUrl}`);
|
|
19126
|
+
if (data.captionRef) {
|
|
19127
|
+
lines.push(`Caption ref: ${data.captionRef} (pass as caption_ref to clipform_render_composition / clipform_render_video_template / clipform_upload_media_asset)`);
|
|
19128
|
+
}
|
|
19121
19129
|
const rawCaptions = Array.isArray(data.captions) ? data.captions : [];
|
|
19122
19130
|
const captions = rawCaptions.map((c) => ({
|
|
19123
19131
|
start: c.start,
|
|
@@ -19129,6 +19137,7 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio U
|
|
|
19129
19137
|
structured.push({
|
|
19130
19138
|
ok: true,
|
|
19131
19139
|
...data.audioUrl ? { audio_url: String(data.audioUrl) } : {},
|
|
19140
|
+
...data.captionRef ? { caption_ref: String(data.captionRef) } : {},
|
|
19132
19141
|
captions
|
|
19133
19142
|
});
|
|
19134
19143
|
} else {
|
|
@@ -19144,7 +19153,7 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio U
|
|
|
19144
19153
|
lines.unshift(`TTS: ${successCount}/${items.length} succeeded
|
|
19145
19154
|
`);
|
|
19146
19155
|
}
|
|
19147
|
-
lines.push(`Pass
|
|
19156
|
+
lines.push(`Pass caption_ref downstream (to clipform_render_composition / clipform_render_video_template / clipform_upload_media_asset) instead of hand-copying the captions array.`);
|
|
19148
19157
|
if (successCount === 0) return errorResult(lines.join("\n"));
|
|
19149
19158
|
return structuredResult(lines.join("\n"), { results: structured });
|
|
19150
19159
|
}
|
|
@@ -19401,6 +19410,7 @@ async function completeViaPlaceholder(placeholder, input) {
|
|
|
19401
19410
|
try {
|
|
19402
19411
|
const body = { url: input.publicUrl };
|
|
19403
19412
|
if (input.captions?.length) body.captions = input.captions;
|
|
19413
|
+
if (input.captionRef) body.caption_ref = input.captionRef;
|
|
19404
19414
|
const completed = await callApi(`/workspaces/${placeholder.workspaceId}/media/${placeholder.assetId}/complete`, {
|
|
19405
19415
|
method: "POST",
|
|
19406
19416
|
body
|
|
@@ -19429,6 +19439,7 @@ async function legacyAutoAttach(input) {
|
|
|
19429
19439
|
url: input.publicUrl
|
|
19430
19440
|
};
|
|
19431
19441
|
if (input.captions?.length) createBody.captions = input.captions;
|
|
19442
|
+
if (input.captionRef) createBody.caption_ref = input.captionRef;
|
|
19432
19443
|
const created = await callApi(`/workspaces/${workspaceId}/media`, { method: "POST", body: createBody });
|
|
19433
19444
|
if (!created.ok) return { attached: false, error: `Failed to create media asset: ${created.error}` };
|
|
19434
19445
|
const mediaAssetId = created.data?.media_asset_id;
|
|
@@ -19474,7 +19485,8 @@ var RenderItemSchema = external_exports.object({
|
|
|
19474
19485
|
outputFormat: external_exports.enum(["mp4", "png"]).default("mp4").describe("Output format (default: mp4)"),
|
|
19475
19486
|
inputProps: external_exports.record(external_exports.unknown()).optional().describe("Props matching the composition's schema - validated strictly"),
|
|
19476
19487
|
node_id: external_exports.string().optional().describe("Form node to attach this item's render to automatically once it completes. Requires the batch's top-level form_id."),
|
|
19477
|
-
captions: external_exports.array(CaptionSchema).optional().describe("Word-level captions from clipform_generate_tts - carried onto the attached media asset. Only used when node_id is set.")
|
|
19488
|
+
captions: external_exports.array(CaptionSchema).optional().describe("Word-level captions from clipform_generate_tts - carried onto the attached media asset. Only used when node_id is set."),
|
|
19489
|
+
caption_ref: external_exports.string().optional().describe("caption_ref from clipform_generate_tts - an opaque handle that attaches that TTS run's word-level captions to the media asset, resolved server-side. Preferred over captions. Only used when node_id is set.")
|
|
19478
19490
|
});
|
|
19479
19491
|
function fireRender(item, formId) {
|
|
19480
19492
|
const job = createJob("clipform_render_composition");
|
|
@@ -19506,6 +19518,7 @@ function fireRender(item, formId) {
|
|
|
19506
19518
|
publicUrl,
|
|
19507
19519
|
mediaType,
|
|
19508
19520
|
captions: item.captions,
|
|
19521
|
+
captionRef: item.caption_ref,
|
|
19509
19522
|
placeholder
|
|
19510
19523
|
});
|
|
19511
19524
|
} else {
|
|
@@ -19544,7 +19557,8 @@ ${RENDER_ATTACH_RULE} In batch mode, set node_id per item (see items) and form_i
|
|
|
19544
19557
|
items: external_exports.array(RenderItemSchema).min(1).max(10).optional().describe("Batch mode: multiple renders in one call. All fire in parallel; returns one job ID per item - collect with clipform_check_render (job_ids). Use this whenever rendering more than one clip."),
|
|
19545
19558
|
node_id: external_exports.string().optional().describe("Single render only: form node to attach this render to automatically once it completes. Requires form_id. For batch mode, set node_id per item instead."),
|
|
19546
19559
|
form_id: external_exports.string().uuid().optional().describe("The form UUID - required when node_id is set (single render) or any item sets node_id (batch)."),
|
|
19547
|
-
captions: external_exports.array(CaptionSchema).optional().describe("Single render only: word-level captions from clipform_generate_tts, carried onto the attached media asset. Only used when node_id is set. For batch mode, set captions per item instead.")
|
|
19560
|
+
captions: external_exports.array(CaptionSchema).optional().describe("Single render only: word-level captions from clipform_generate_tts, carried onto the attached media asset. Only used when node_id is set. For batch mode, set captions per item instead."),
|
|
19561
|
+
caption_ref: external_exports.string().optional().describe("Single render only: caption_ref from clipform_generate_tts - an opaque handle that attaches that TTS run's word-level captions to the media asset, resolved server-side. Preferred over captions. Only used when node_id is set. For batch mode, set caption_ref per item instead.")
|
|
19548
19562
|
},
|
|
19549
19563
|
outputSchema: {
|
|
19550
19564
|
jobs: external_exports.array(
|
|
@@ -19567,7 +19581,7 @@ ${RENDER_ATTACH_RULE} In batch mode, set node_id per item (see items) and form_i
|
|
|
19567
19581
|
// node_id too (destructive/openWorld apply "even in only select modes").
|
|
19568
19582
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }
|
|
19569
19583
|
},
|
|
19570
|
-
async ({ compositionId, outputFormat, inputProps, wait, items, node_id, form_id, captions }) => {
|
|
19584
|
+
async ({ compositionId, outputFormat, inputProps, wait, items, node_id, form_id, captions, caption_ref }) => {
|
|
19571
19585
|
if (items?.length && compositionId) {
|
|
19572
19586
|
return errorResult("Pass EITHER items (batch) OR compositionId (single render), not both.");
|
|
19573
19587
|
}
|
|
@@ -19604,7 +19618,7 @@ ${RENDER_ATTACH_RULE} In batch mode, set node_id per item (see items) and form_i
|
|
|
19604
19618
|
);
|
|
19605
19619
|
}
|
|
19606
19620
|
if (wait === false) {
|
|
19607
|
-
const job = fireRender({ compositionId, outputFormat, inputProps, node_id, captions }, form_id);
|
|
19621
|
+
const job = fireRender({ compositionId, outputFormat, inputProps, node_id, captions, caption_ref }, form_id);
|
|
19608
19622
|
return structuredResult(
|
|
19609
19623
|
[
|
|
19610
19624
|
`Render started (${compositionId}).`,
|
|
@@ -19638,6 +19652,7 @@ ${RENDER_ATTACH_RULE} In batch mode, set node_id per item (see items) and form_i
|
|
|
19638
19652
|
publicUrl: data.public_url,
|
|
19639
19653
|
mediaType: mediaTypeSingle,
|
|
19640
19654
|
captions,
|
|
19655
|
+
captionRef: caption_ref,
|
|
19641
19656
|
placeholder
|
|
19642
19657
|
});
|
|
19643
19658
|
} else if (placeholder) {
|
|
@@ -19893,7 +19908,8 @@ ${RENDER_ATTACH_RULE}`,
|
|
|
19893
19908
|
wait: external_exports.boolean().optional().default(true).describe("true (default) blocks until the render is ready and returns its URL; false returns a job ID for clipform_check_render."),
|
|
19894
19909
|
node_id: external_exports.string().optional().describe("Form node to attach this render to automatically once it completes - skips the manual clipform_upload_media_asset + clipform_attach_node_media steps and republishes the form if it's currently live. Requires form_id."),
|
|
19895
19910
|
form_id: external_exports.string().uuid().optional().describe("The form UUID (required when node_id is set)."),
|
|
19896
|
-
captions: external_exports.array(CaptionSchema).optional().describe("Word-level captions from clipform_generate_tts - carried onto the attached media asset. Only used when node_id is set.")
|
|
19911
|
+
captions: external_exports.array(CaptionSchema).optional().describe("Word-level captions from clipform_generate_tts - carried onto the attached media asset. Only used when node_id is set."),
|
|
19912
|
+
caption_ref: external_exports.string().optional().describe("caption_ref from clipform_generate_tts - an opaque handle that attaches that TTS run's word-level captions to the media asset, resolved server-side. Preferred over captions. Only used when node_id is set.")
|
|
19897
19913
|
},
|
|
19898
19914
|
outputSchema: {
|
|
19899
19915
|
status: external_exports.enum(["rendering", "complete"]),
|
|
@@ -19912,7 +19928,7 @@ ${RENDER_ATTACH_RULE}`,
|
|
|
19912
19928
|
// node_id too (destructive/openWorld apply "even in only select modes").
|
|
19913
19929
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }
|
|
19914
19930
|
},
|
|
19915
|
-
async ({ template, controls, outputFormat, wait, node_id, form_id, captions }) => {
|
|
19931
|
+
async ({ template, controls, outputFormat, wait, node_id, form_id, captions, caption_ref }) => {
|
|
19916
19932
|
if (node_id && !form_id) {
|
|
19917
19933
|
return errorResult("form_id is required when node_id is set.");
|
|
19918
19934
|
}
|
|
@@ -19936,7 +19952,7 @@ ${RENDER_ATTACH_RULE}`,
|
|
|
19936
19952
|
const publicUrl = r.data.public_url;
|
|
19937
19953
|
const placeholder = await placeholderPromise2;
|
|
19938
19954
|
if (publicUrl) {
|
|
19939
|
-
attach2 = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl, mediaType, captions, placeholder });
|
|
19955
|
+
attach2 = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl, mediaType, captions, captionRef: caption_ref, placeholder });
|
|
19940
19956
|
} else {
|
|
19941
19957
|
const message = "Render completed without a public_url; nothing to attach.";
|
|
19942
19958
|
attach2 = { attached: false, error: message };
|
|
@@ -19974,7 +19990,7 @@ ${RENDER_ATTACH_RULE}`,
|
|
|
19974
19990
|
if (node_id && form_id) {
|
|
19975
19991
|
const placeholder = await placeholderPromise;
|
|
19976
19992
|
if (data.public_url) {
|
|
19977
|
-
attach = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl: data.public_url, mediaType, captions, placeholder });
|
|
19993
|
+
attach = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl: data.public_url, mediaType, captions, captionRef: caption_ref, placeholder });
|
|
19978
19994
|
} else if (placeholder) {
|
|
19979
19995
|
await failPlaceholder(placeholder, "Render completed without a public_url; nothing to attach.");
|
|
19980
19996
|
}
|
|
@@ -20165,7 +20181,7 @@ ${RENDER_ATTACH_RULE}`,
|
|
|
20165
20181
|
const publicUrl = r.data.public_url;
|
|
20166
20182
|
const placeholder = await placeholderPromise2;
|
|
20167
20183
|
if (publicUrl) {
|
|
20168
|
-
attach2 = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl, mediaType: "video", captions, placeholder });
|
|
20184
|
+
attach2 = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl, mediaType: "video", captions, captionRef: audio_url, placeholder });
|
|
20169
20185
|
} else {
|
|
20170
20186
|
const message = "Render completed without a public_url; nothing to attach.";
|
|
20171
20187
|
attach2 = { attached: false, error: message };
|
|
@@ -20200,7 +20216,7 @@ ${RENDER_ATTACH_RULE}`,
|
|
|
20200
20216
|
if (node_id && form_id) {
|
|
20201
20217
|
const placeholder = await placeholderPromise;
|
|
20202
20218
|
if (data.public_url) {
|
|
20203
|
-
attach = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl: data.public_url, mediaType: "video", captions, placeholder });
|
|
20219
|
+
attach = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl: data.public_url, mediaType: "video", captions, captionRef: audio_url, placeholder });
|
|
20204
20220
|
} else if (placeholder) {
|
|
20205
20221
|
await failPlaceholder(placeholder, "Render completed without a public_url; nothing to attach.");
|
|
20206
20222
|
}
|
|
@@ -20704,4 +20720,4 @@ export {
|
|
|
20704
20720
|
buildInstructions,
|
|
20705
20721
|
createServer
|
|
20706
20722
|
};
|
|
20707
|
-
//# sourceMappingURL=chunk-
|
|
20723
|
+
//# sourceMappingURL=chunk-66KZWBI7.js.map
|