@clipform/mcp-server 2.18.0 → 3.0.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.
@@ -6,7 +6,7 @@ import {
6
6
  getWorkflowText,
7
7
  objectType,
8
8
  registerPrompts
9
- } from "./chunk-WWIQEIFF.js";
9
+ } from "./chunk-KCF7ZVDI.js";
10
10
  import {
11
11
  GUIDE_TYPES,
12
12
  QUIZ_VARIANTS,
@@ -15,35 +15,27 @@ import {
15
15
  getGuideUri,
16
16
  guideFallbackText,
17
17
  registerResources
18
- } from "./chunk-CHSPV2VI.js";
18
+ } from "./chunk-EXV5M7YV.js";
19
19
  import {
20
20
  ACTIVE_NODE_TYPES,
21
21
  CONTACT_FIELDS,
22
22
  FEATURE_FLAGS,
23
23
  FORM_TYPE_ALIASES,
24
24
  FULL_CAPS,
25
- HTTP_URL_MESSAGE,
26
- KEN_BURNS_EFFECTS,
27
- KEN_BURNS_FIT_MODES,
28
- KEN_BURNS_PRESETS,
29
25
  MCP_TOOL_TIERS,
30
26
  MCP_TOOL_TOOLSETS,
31
27
  NODE_TYPES,
32
28
  NON_COUNTABLE_TYPES,
33
- SLIDESHOW_COMPOSITION_TRANSITIONS,
34
- SLIDESHOW_TRANSITION_DURATION,
35
- VIDEO_LOOK_NAMES,
36
29
  bfsOrder,
37
30
  callApi,
38
31
  capsFromToolsets,
39
32
  defaultTarget,
40
33
  errorResult,
41
34
  exposedCompositionIds,
42
- isHttpUrl,
43
35
  resolveFormType,
44
36
  structuredResult,
45
37
  textResult
46
- } from "./chunk-RKYB6247.js";
38
+ } from "./chunk-KNOCYZHG.js";
47
39
  import {
48
40
  getMcpAuth,
49
41
  runWithMcpTool
@@ -17111,7 +17103,6 @@ var NODE_TYPES_DESCRIPTION = (() => {
17111
17103
  return lines.join("\n");
17112
17104
  })();
17113
17105
  var CONFIG_FIELD_DESCRIPTION = "Type-specific configuration keyed by node type. Omit to use defaults. Per-type keys, shapes, and defaults are listed in the clipform_create_form description; craft guidance via clipform_get_guide.";
17114
- var STYLE_PRESET_ENUM = external_exports.enum(KEN_BURNS_PRESETS).describe(`Ken Burns style preset: ${KEN_BURNS_PRESETS.join(", ")}`);
17115
17106
  var CaptionSchema = external_exports.object({
17116
17107
  start: external_exports.number().describe("Segment start time in seconds"),
17117
17108
  end: external_exports.number().describe("Segment end time in seconds"),
@@ -18832,7 +18823,7 @@ var MEDIA_SUPPORTED_TYPES = Object.entries(NODE_TYPES).filter(([, def]) => def.s
18832
18823
  var AttachMediaItemSchema = external_exports.object({
18833
18824
  node_id: external_exports.string().describe("The node ID"),
18834
18825
  media_asset_id: external_exports.string().describe("A media asset ID returned by clipform_upload_media_asset"),
18835
- fit_media: external_exports.boolean().optional().describe("Show the whole frame (contain) instead of cover-cropping. ALWAYS set true when attaching renders from clipform_render_composition or clipform_generate_video - they are composed 9:16 frames that must never be cropped. Leave unset for user-supplied media (arbitrary aspect ratios want the cover default)."),
18826
+ fit_media: external_exports.boolean().optional().describe("Show the whole frame (contain) instead of cover-cropping. ALWAYS set true when attaching renders from clipform_render_composition or clipform_render_video_template - they are composed 9:16 frames that must never be cropped. Leave unset for user-supplied media (arbitrary aspect ratios want the cover default)."),
18836
18827
  show_captions: external_exports.boolean().optional().describe("Display captions/subtitles on the node. Defaults to on; pass false to hide them.")
18837
18828
  });
18838
18829
  function registerAttachNodeMediaTool(server) {
@@ -19301,7 +19292,7 @@ function registerSearchMediaTool(server) {
19301
19292
  "clipform_search_media",
19302
19293
  {
19303
19294
  title: "Search Media",
19304
- description: `Search images or stock video clips. Pass one query or many (max 10) - multiple queries run in one call instead of separate tool calls. Use results to feed into clipform_generate_video for narrated slideshow videos, or upload directly as still images via clipform_upload_media_asset then clipform_attach_node_media. All results are pre-cleared for commercial use. Results include a description (alt text where the provider has it) - use it to pick visually distinct images.
19295
+ description: `Search images or stock video clips. Pass one query or many (max 10) - multiple queries run in one call instead of separate tool calls. Use results to feed into clipform_render_video_template (slideshow) for narrated slideshow videos, or upload directly as still images via clipform_upload_media_asset then clipform_attach_node_media. All results are pre-cleared for commercial use. Results include a description (alt text where the provider has it) - use it to pick visually distinct images.
19305
19296
 
19306
19297
  Example: { queries: [{ query: "saturn rings" }, { query: "mars surface", count: 3 }] } returns portrait images for both.`,
19307
19298
  inputSchema: {
@@ -19395,8 +19386,7 @@ Example: { queries: [{ query: "saturn rings" }, { query: "mars surface", count:
19395
19386
  }
19396
19387
 
19397
19388
  // src/lib/render-routing.ts
19398
- var RENDER_ROUTING_RULE = `Choosing a render tool: for a recognisable form/quiz beat (guess-the-city, this-or-that, mystery reveal, multiple choice, photo montage...) reach for a video template first (clipform_list_video_templates + clipform_render_video_template) - it is a one-call recipe. Use clipform_generate_video for a narrated or audio-synced media montage (images/clips timed to a voice track). Use clipform_render_composition only when neither fits and you need a custom layer stack.`;
19399
- var MONTAGE_NARRATION_RULE = `Montage disambiguation: choose clipform_generate_video when the montage is narrated or synced to an audio track; choose the slideshow video template when it is silent (motion + transitions only, no voice-over).`;
19389
+ var RENDER_ROUTING_RULE = `Choosing a render tool: for a recognisable form/quiz beat (guess-the-city, this-or-that, mystery reveal, multiple choice, photo montage...) reach for a video template first (clipform_list_video_templates + clipform_render_video_template) - it is a one-call recipe. For a photo/clip montage, narrated or silent, use the slideshow template (pass audio_url to sync it to a voice track). Use clipform_render_composition only when neither fits and you need a custom layer stack.`;
19400
19390
  var RENDER_ATTACH_RULE = `A render for a form node is not done until it is attached to that node. Pass node_id (and form_id) so the completed render attaches itself automatically - do not poll clipform_check_render to completion or manually chain clipform_upload_media_asset + clipform_attach_node_media; fire the render and move on.`;
19401
19391
 
19402
19392
  // ../../node_modules/.pnpm/uuid@11.1.1/node_modules/uuid/dist/esm/stringify.js
@@ -19680,7 +19670,7 @@ function registerRenderCompositionTool(server) {
19680
19670
  "clipform_render_composition",
19681
19671
  {
19682
19672
  title: "Render Composition",
19683
- description: `Render a specialised video composition to MP4 or PNG - custom animated visuals that clipform_generate_video can't provide, such as geography animations or designed motion graphics. Available composition names and their required input props schemas come from clipform_list_compositions.
19673
+ description: `Render a specialised video composition to MP4 or PNG - custom animated visuals that a video template can't provide, such as geography animations or designed motion graphics. Available composition names and their required input props schemas come from clipform_list_compositions.
19684
19674
 
19685
19675
  Output formats: mp4 (H.264, best for social media) or png (single frame). Returns a public URL when complete.
19686
19676
 
@@ -19825,7 +19815,7 @@ function registerSearchMusicTool(server) {
19825
19815
  "clipform_search_music",
19826
19816
  {
19827
19817
  title: "Search Music",
19828
- description: `Search for royalty-free music tracks and ambient sounds. Quiz forms especially benefit from background music - it keeps energy up between questions. Also consider it for multi-step surveys and longer forms. Pass the returned URL as the audio track to clipform_generate_video, or as the audio for the slideshow video template via clipform_render_video_template. Returns download URLs, duration, artist, and license info.`,
19818
+ description: `Search for royalty-free music tracks and ambient sounds. Quiz forms especially benefit from background music - it keeps energy up between questions. Also consider it for multi-step surveys and longer forms. Pass the returned URL as the audio for the slideshow video template via clipform_render_video_template. Returns download URLs, duration, artist, and license info.`,
19829
19819
  inputSchema: {
19830
19820
  query: external_exports.string().min(1).describe("What to search for (e.g. 'upbeat quiz background', 'calm ambient', 'playful pizzicato')"),
19831
19821
  count: external_exports.number().int().min(1).max(10).default(5).optional().describe("Max results (default: 5)"),
@@ -19845,7 +19835,7 @@ function registerSearchMusicTool(server) {
19845
19835
  source: external_exports.string().optional(),
19846
19836
  license: external_exports.string().optional()
19847
19837
  })
19848
- ).describe("Matching tracks (empty if none); pass a url as the audio track to generate_video")
19838
+ ).describe("Matching tracks (empty if none); pass a url as the audio for the slideshow template")
19849
19839
  },
19850
19840
  // Fetches from an external royalty-free music provider - openWorldHint:
19851
19841
  // true (#2976).
@@ -19915,7 +19905,7 @@ function registerListCompositionsTool(server) {
19915
19905
  "clipform_list_compositions",
19916
19906
  {
19917
19907
  title: "List Compositions",
19918
- description: `Browse available video compositions and their expected props schemas. Call this before using clipform_render_composition to discover visual styles and their input props. For an image or photo montage, reach for a video template (clipform_list_video_templates + clipform_render_video_template) or clipform_generate_video instead of a composition.`,
19908
+ description: `Browse available video compositions and their expected props schemas. Call this before using clipform_render_composition to discover visual styles and their input props. For an image or photo montage, reach for a video template (clipform_list_video_templates + clipform_render_video_template) instead of a composition.`,
19919
19909
  inputSchema: {},
19920
19910
  outputSchema: {
19921
19911
  compositions: external_exports.array(
@@ -20214,180 +20204,6 @@ function registerListAssetsTool(server) {
20214
20204
  );
20215
20205
  }
20216
20206
 
20217
- // src/tools/generate-video.ts
20218
- var httpUrl = () => external_exports.string().url().refine(isHttpUrl, { message: HTTP_URL_MESSAGE });
20219
- function registerGenerateVideoTool(server) {
20220
- server.registerTool(
20221
- "clipform_generate_video",
20222
- {
20223
- title: "Generate Video",
20224
- description: `Generate a video from images, video clips, or both, synced to an audio track. Use this for narrated question backgrounds, topic visualisations, or any form node that benefits from video. Combine with clipform_generate_tts for narrated audio and clipform_search_media for royalty-free images. Creates 9:16 (720x1280) with Ken Burns pan/zoom effects and transitions. Returns a public URL when complete.
20225
-
20226
- Items: type "image" (Ken Burns motion) or "video" (cover-cropped, muted by default). Duration matches audio_url or set duration_seconds explicitly.
20227
-
20228
- For multi-question builds, pass wait: false on every render: each call returns a job ID immediately, so all renders run in parallel - then collect URLs with clipform_check_render. Sequential waiting renders take ${RENDER_TIMING.expectedRange} EACH.
20229
-
20230
- ${RENDER_ROUTING_RULE}
20231
- ${MONTAGE_NARRATION_RULE}
20232
- ${RENDER_ATTACH_RULE}`,
20233
- inputSchema: {
20234
- items: external_exports.array(
20235
- external_exports.object({
20236
- type: external_exports.enum(["image", "video"]).describe("'image' for still images with Ken Burns effects, 'video' for video clips"),
20237
- url: httpUrl().describe("Media URL"),
20238
- effect: external_exports.enum([...KEN_BURNS_EFFECTS, "random"]).optional().describe("Advanced override: a specific Ken Burns effect (image only), overriding the preset look's own effect choice"),
20239
- aspect_ratio: external_exports.number().positive().optional().describe("Image width/height ratio (image only). Enables auto blur-pad for landscape images."),
20240
- fit: external_exports.enum(KEN_BURNS_FIT_MODES).optional().describe("Framing mode (image only). auto = cover for portrait, blur-pad for landscape."),
20241
- start_from: external_exports.number().min(0).optional().describe("Start time in seconds (video only). Trims the clip."),
20242
- volume: external_exports.number().min(0).max(1).optional().describe("Clip audio volume 0-1 (video only, default 0 = muted)")
20243
- })
20244
- ).min(1).max(20).describe("Media items (images, video clips, or a mix)"),
20245
- audio_url: httpUrl().optional().describe("Audio track URL. Video duration matches audio duration."),
20246
- background_audio_url: httpUrl().optional().describe("Ambience/music bed under the narration (crowd noise, room tone). Loops to fill the video. Find tracks with clipform_search_music."),
20247
- background_audio_volume: external_exports.number().min(0).max(1).optional().describe("Background bed volume 0-1 (default 0.15 - sits under speech)"),
20248
- duration_seconds: external_exports.number().positive().optional().describe("Video duration in seconds (required if no audio_url)"),
20249
- preset: external_exports.enum(VIDEO_LOOK_NAMES).optional().default("clean").describe(`Named look driving transition + motion + colour treatment together (default: 'clean'). One of: ${VIDEO_LOOK_NAMES.join(", ")}. The advanced fields below (transition, style_preset, texture, duotone, background_color, per-item effect) override individual pieces of the chosen look when set.`),
20250
- random_effects: external_exports.boolean().optional().default(true).describe("Shuffle Ken Burns effects across image items (default: true)"),
20251
- transition: external_exports.object({
20252
- type: external_exports.enum(SLIDESHOW_COMPOSITION_TRANSITIONS).optional().describe(`Advanced override: ${SLIDESHOW_COMPOSITION_TRANSITIONS.join(", ")} - overrides the preset look's own transition`),
20253
- duration: external_exports.number().min(SLIDESHOW_TRANSITION_DURATION.min).max(SLIDESHOW_TRANSITION_DURATION.max).optional().describe(`Advanced override: transition duration in seconds (${SLIDESHOW_TRANSITION_DURATION.min}-${SLIDESHOW_TRANSITION_DURATION.max}). For a hard cut use type: 'none' instead - duration is ignored then.`)
20254
- }).optional().describe("Advanced: overrides the preset look's transition"),
20255
- style_preset: STYLE_PRESET_ENUM.optional().describe(`Advanced override: a raw Ken Burns motion preset, overriding the preset look's own motion.`),
20256
- texture: external_exports.object({
20257
- type: external_exports.enum(["checker", "halftone", "scanlines"]).describe("checker = square dither mesh, halftone = dot grid, scanlines = horizontal lines"),
20258
- sizePx: external_exports.number().positive().optional().describe("Pattern cell size in px (default 4)"),
20259
- opacity: external_exports.number().min(0).max(1).optional().describe("Pattern darkness 0-1 (default 0.35)")
20260
- }).optional().describe("Advanced override: print-style pattern overlay on image items, overriding the preset look's own texture - makes stock imagery read as designed (screen-print dither look)"),
20261
- duotone: external_exports.object({
20262
- shadow: external_exports.string().describe("Darker tone (maps to image shadows), e.g. '#1a1633'"),
20263
- highlight: external_exports.string().describe("Lighter tone (maps to image highlights), e.g. '#f5c542'"),
20264
- contrast: external_exports.number().positive().optional().describe("Contrast boost before mapping (default 1.1)")
20265
- }).optional().describe("Advanced override: two-tone editorial recolour on image items, overriding the preset look's own duotone - desaturates then maps to a shadow->highlight palette. Pair with a halftone texture for a screen-print poster look."),
20266
- background_color: external_exports.string().optional().describe("Advanced override: background color, overriding the preset look's own background (default '#000')"),
20267
- wait: external_exports.boolean().optional().default(true).describe("true (default) blocks until the video is ready and returns its URL. false returns a job ID immediately - fire all renders first, then poll clipform_check_render. Use false whenever rendering more than one video."),
20268
- 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."),
20269
- form_id: external_exports.string().uuid().optional().describe("The form UUID (required when node_id is set)."),
20270
- 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.")
20271
- },
20272
- outputSchema: {
20273
- status: external_exports.enum(["rendering", "complete"]).describe("'rendering' when wait:false (poll check_render); 'complete' with a public_url when wait:true"),
20274
- job_id: external_exports.string().optional().describe("Present when status is 'rendering' - pass to check_render"),
20275
- public_url: external_exports.string().optional().describe("Present when status is 'complete' - attach via upload_media_asset then attach_node_media (fit_media: true), unless node_id was set (auto-attached)"),
20276
- duration_seconds: external_exports.number().optional(),
20277
- attached: external_exports.boolean().optional().describe("True when node_id was provided and the render was attached to the node automatically (present once the attach outcome is known)."),
20278
- media_asset_id: external_exports.string().optional().describe("The workspace media asset created from this render, when attached."),
20279
- republished: external_exports.boolean().optional().describe("True when the form was live and was republished to include this media."),
20280
- attach_error: external_exports.string().optional().describe("Present when node_id was provided but auto-attach failed - the render itself still succeeded.")
20281
- },
20282
- // node_id auto-attach replaces the node's existing media placement and
20283
- // republishes an already-live form - an indirect but real overwrite +
20284
- // publish (#2976 research pass 2), even though this tool works with no
20285
- // node_id too (destructive/openWorld apply "even in only select modes").
20286
- annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }
20287
- },
20288
- async ({ items, audio_url, background_audio_url, background_audio_volume, duration_seconds, preset, random_effects, transition, style_preset, texture, duotone, background_color, wait, node_id, form_id, captions }) => {
20289
- if (node_id && !form_id) {
20290
- return errorResult("form_id is required when node_id is set.");
20291
- }
20292
- const default_style = style_preset || texture || duotone ? {
20293
- ...style_preset ? { preset: style_preset } : {},
20294
- ...texture ? { texture } : {},
20295
- ...duotone ? { duotone } : {}
20296
- } : void 0;
20297
- const apiCall = () => callApi("/internal/generate-video", {
20298
- timeoutMs: 3e5,
20299
- // local renders pay a cold webpack bundle; Lambda is fast but bursty
20300
- body: {
20301
- items,
20302
- audio_url,
20303
- background_audio_url,
20304
- background_audio_volume,
20305
- duration_seconds,
20306
- // preset expands to its base transition/style/background on the
20307
- // API side (expandVideoLook); transition/default_style/background_color
20308
- // below are only sent when the caller actually set the advanced
20309
- // override, so the API can tell "explicit" apart from "unset" and
20310
- // apply the look's own base value instead (#4038).
20311
- preset,
20312
- random_effects: random_effects ?? true,
20313
- transition,
20314
- default_style,
20315
- background_color
20316
- }
20317
- });
20318
- if (wait === false) {
20319
- const job = createJob("clipform_generate_video");
20320
- const placeholderPromise2 = node_id && form_id ? createRenderPlaceholder({ formId: form_id, nodeId: node_id, mediaType: "video" }) : Promise.resolve(void 0);
20321
- apiCall().then(async (r) => {
20322
- if (!r.ok) {
20323
- failJob(job.id, r.error);
20324
- const placeholder = await placeholderPromise2;
20325
- if (placeholder) await failPlaceholder(placeholder, r.error);
20326
- return;
20327
- }
20328
- let attach2;
20329
- if (node_id && form_id) {
20330
- const publicUrl = r.data.public_url;
20331
- const placeholder = await placeholderPromise2;
20332
- if (publicUrl) {
20333
- attach2 = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl, mediaType: "video", captions, captionRef: resolveCaptionRef(void 0, audio_url), placeholder });
20334
- } else {
20335
- const message = "Render completed without a public_url; nothing to attach.";
20336
- attach2 = { attached: false, error: message };
20337
- if (placeholder) await failPlaceholder(placeholder, message);
20338
- }
20339
- }
20340
- completeJob(job.id, r.data, attach2);
20341
- }).catch(async (err) => {
20342
- const message = err instanceof Error ? err.message : String(err);
20343
- failJob(job.id, message);
20344
- const placeholder = await placeholderPromise2;
20345
- if (placeholder) await failPlaceholder(placeholder, message);
20346
- });
20347
- return structuredResult(
20348
- [
20349
- `Render started (${items.length} item${items.length > 1 ? "s" : ""}).`,
20350
- `Job ID: ${job.id}`,
20351
- node_id ? `Will attach to node ${node_id} automatically once it completes - no need to poll to completion.` : `Fire any remaining renders now, then poll clipform_check_render. Renders typically take ${RENDER_TIMING.expectedRange}.`
20352
- ].join("\n"),
20353
- { status: "rendering", job_id: job.id }
20354
- );
20355
- }
20356
- const placeholderPromise = node_id && form_id ? createRenderPlaceholder({ formId: form_id, nodeId: node_id, mediaType: "video" }) : Promise.resolve(void 0);
20357
- const result = await apiCall();
20358
- if (!result.ok) {
20359
- const placeholder = await placeholderPromise;
20360
- if (placeholder) await failPlaceholder(placeholder, result.error);
20361
- return errorResult(result.error);
20362
- }
20363
- const data = result.data;
20364
- let attach;
20365
- if (node_id && form_id) {
20366
- const placeholder = await placeholderPromise;
20367
- if (data.public_url) {
20368
- attach = await autoAttachRender({ formId: form_id, nodeId: node_id, publicUrl: data.public_url, mediaType: "video", captions, captionRef: resolveCaptionRef(void 0, audio_url), placeholder });
20369
- } else if (placeholder) {
20370
- await failPlaceholder(placeholder, "Render completed without a public_url; nothing to attach.");
20371
- }
20372
- }
20373
- return structuredResult(
20374
- [
20375
- `Video rendered (${items.length} item${items.length > 1 ? "s" : ""}).`,
20376
- `Public URL: ${data.public_url}`,
20377
- data.duration_seconds ? `Duration: ${data.duration_seconds}s` : "",
20378
- attach ? attachSummaryLine(node_id, attach) : `Attach via clipform_upload_media_asset then clipform_attach_node_media with fit_media: true (composed 9:16 frame - contain, never crop).`
20379
- ].filter(Boolean).join("\n"),
20380
- {
20381
- status: "complete",
20382
- ...data.public_url ? { public_url: data.public_url } : {},
20383
- ...typeof data.duration_seconds === "number" ? { duration_seconds: data.duration_seconds } : {},
20384
- ...attachStructuredFields(attach)
20385
- }
20386
- );
20387
- }
20388
- );
20389
- }
20390
-
20391
20207
  // src/tools/check-render.ts
20392
20208
  function projectJob(id, job) {
20393
20209
  if (!job) return { job_id: id, status: "not_found" };
@@ -20410,7 +20226,7 @@ var LOST_JOB_RECOVERY = [
20410
20226
  `Jobs expire after 30 minutes and are lost if the server restarts - the render itself may still have completed.`,
20411
20227
  `To recover, re-run the original render call with identical arguments:`,
20412
20228
  `- clipform_render_composition results are content-cached: a finished render returns its URL immediately without re-rendering.`,
20413
- `- clipform_generate_video is not cached and will re-render.`
20229
+ `- clipform_render_video_template results are content-cached too: re-running with identical controls returns the finished URL.`
20414
20230
  ].join("\n");
20415
20231
  function describeJob(id, job) {
20416
20232
  if (!job) {
@@ -20436,7 +20252,7 @@ function registerCheckRenderTool(server) {
20436
20252
  "clipform_check_render",
20437
20253
  {
20438
20254
  title: "Check Render Status",
20439
- description: `Check the status of render jobs started by clipform_generate_video, clipform_render_video_template, or clipform_render_composition.
20255
+ description: `Check the status of render jobs started by clipform_render_video_template or clipform_render_composition.
20440
20256
 
20441
20257
  Pass job_ids to check a whole batch in ONE call - one line of status per job. Pass job_id for a single job. Returns the output URL for each completed render. Typical render time: 10-60 seconds. Attach is automatic when node_id was provided to the render tool - no need to poll to completion, and the attach outcome is reported here once known.`,
20442
20258
  inputSchema: {
@@ -20846,7 +20662,6 @@ function createServer(options) {
20846
20662
  registerLogGenerationTool(server);
20847
20663
  registerSearchNewsTool(server);
20848
20664
  registerGenerateTtsTool(server);
20849
- registerGenerateVideoTool(server);
20850
20665
  registerSearchMediaTool(server);
20851
20666
  registerRenderCompositionTool(server);
20852
20667
  registerSearchMusicTool(server);
@@ -20870,4 +20685,4 @@ export {
20870
20685
  buildInstructions,
20871
20686
  createServer
20872
20687
  };
20873
- //# sourceMappingURL=chunk-Y4RGN6KA.js.map
20688
+ //# sourceMappingURL=chunk-QBPE32AV.js.map