@clipform/mcp-server 2.15.9 → 2.15.11

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-SKNKSZOA.js";
9
+ } from "./chunk-PCRTQ4DJ.js";
10
10
  import {
11
11
  GUIDE_TYPES,
12
12
  QUIZ_VARIANTS,
@@ -15,7 +15,7 @@ import {
15
15
  getGuideUri,
16
16
  guideFallbackText,
17
17
  registerResources
18
- } from "./chunk-ORZYVIW3.js";
18
+ } from "./chunk-F3MU6JRT.js";
19
19
  import {
20
20
  ACTIVE_NODE_TYPES,
21
21
  CONTACT_FIELDS,
@@ -40,7 +40,7 @@ import {
40
40
  resolveFormType,
41
41
  structuredResult,
42
42
  textResult
43
- } from "./chunk-VLI2LYIB.js";
43
+ } from "./chunk-CW6LYA3K.js";
44
44
  import {
45
45
  getMcpAuth,
46
46
  runWithMcpTool
@@ -16998,6 +16998,22 @@ import { readFileSync } from "fs";
16998
16998
  import { dirname, join } from "path";
16999
16999
  import { fileURLToPath } from "url";
17000
17000
 
17001
+ // src/lib/onboarding-copy.ts
17002
+ var ONBOARDING_OFFER_CONTROL_VARIANT = "control";
17003
+ var ONBOARDING_OFFER_COPY = {
17004
+ // #4089 review: this cohort has already completed OAuth to connect - they
17005
+ // have an account. Never claim "no account needed" or otherwise imply an
17006
+ // anonymous/no-sign-up lane here; that framing contradicts what they just
17007
+ // did and reads as broken. Acknowledge the connection instead, then offer
17008
+ // to build. (The anonymous/no-auth entry point is a different surface,
17009
+ // #4088 - not this cohort.)
17010
+ [ONBOARDING_OFFER_CONTROL_VARIANT]: "When this is the start of a new conversation and the user has not yet said what they want to build, welcome them as someone who is now connected to Clipform and offer to build their first form together, then offer these starting points as plain text: lead-gen, feedback, quiz, or something else - ask which one fits, or invite them to describe what they need instead. If the user's first message already states what they want to build, even loosely, skip that offer entirely and go straight into the brief-driven flow below."
17011
+ };
17012
+ function buildOnboardingOffer(variant = ONBOARDING_OFFER_CONTROL_VARIANT) {
17013
+ return ONBOARDING_OFFER_COPY[variant] ?? ONBOARDING_OFFER_COPY[ONBOARDING_OFFER_CONTROL_VARIANT];
17014
+ }
17015
+ var ONBOARDING_OFFER_TOOL_CUE = "If the user hasn't said what to build yet, offer to build their first form and suggest starting points: lead-gen, feedback, quiz, or something else.";
17016
+
17001
17017
  // src/lib/config.ts
17002
17018
  var _endScreen = NODE_TYPES.end_screen.config_schema.properties;
17003
17019
  var END_SCREEN_ICONS = _endScreen.icon.enum;
@@ -17185,6 +17201,8 @@ function registerCreateFormTool(server) {
17185
17201
  title: "Create Clipform",
17186
17202
  description: `Create a new Clipform (interactive video-style form). Returns a viewer URL and form ID. When connected via an authenticated MCP client (e.g. claude.ai), the form lands directly in the user's workspace. Anonymous sessions get a claim URL to transfer ownership later.
17187
17203
 
17204
+ ${ONBOARDING_OFFER_TOOL_CUE}
17205
+
17188
17206
  ${NODE_TYPES_DESCRIPTION}
17189
17207
 
17190
17208
  All type definitions and config schemas are derived from @vid-master/config (node-types). Refer to the config descriptions above for the correct keys and shapes. AI-PROTECTED parameters have restrictions noted in their descriptions.
@@ -17297,7 +17315,13 @@ Example: A form that asks a question, collects contact info, then finishes:
17297
17315
  workspace_id: workspaceId,
17298
17316
  nodes,
17299
17317
  ...Object.keys(settings).length > 0 ? { settings } : {}
17300
- }
17318
+ },
17319
+ // The batch build (createFormFromNodes) does sequential node inserts
17320
+ // server-side - documented at ~62s for 50 nodes (#4070) - well past
17321
+ // callApi's 30s default. A fixed ceiling clears that worst case with
17322
+ // margin; the /me and /forms GET pre-flight checks above stay on the
17323
+ // fast default.
17324
+ timeoutMs: 12e4
17301
17325
  });
17302
17326
  if (!createResult.ok) {
17303
17327
  return errorResult(`Form NOT created (nothing was saved): ${createResult.error}`);
@@ -19155,7 +19179,9 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio_u
19155
19179
  items.map(
19156
19180
  (item) => callApi("/internal/tts", {
19157
19181
  body: { text: item.text, voice: item.voice, tone: item.tone, workspace_id },
19158
- timeoutMs: 45e3
19182
+ // Synthesize + audio upload + caption store (#4070) occasionally
19183
+ // exceeds 45s; 90s clears the real tail with margin.
19184
+ timeoutMs: 9e4
19159
19185
  })
19160
19186
  )
19161
19187
  );
@@ -20118,6 +20144,9 @@ function registerListAssetsTool(server) {
20118
20144
  }
20119
20145
 
20120
20146
  // src/tools/generate-video.ts
20147
+ var httpUrl = () => external_exports.string().url().refine((v) => /^https?:\/\//i.test(v), {
20148
+ message: "URL must start with http:// or https://"
20149
+ });
20121
20150
  function registerGenerateVideoTool(server) {
20122
20151
  server.registerTool(
20123
20152
  "clipform_generate_video",
@@ -20136,7 +20165,7 @@ ${RENDER_ATTACH_RULE}`,
20136
20165
  items: external_exports.array(
20137
20166
  external_exports.object({
20138
20167
  type: external_exports.enum(["image", "video"]).describe("'image' for still images with Ken Burns effects, 'video' for video clips"),
20139
- url: external_exports.string().url().describe("Media URL"),
20168
+ url: httpUrl().describe("Media URL"),
20140
20169
  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"),
20141
20170
  aspect_ratio: external_exports.number().positive().optional().describe("Image width/height ratio (image only). Enables auto blur-pad for landscape images."),
20142
20171
  fit: external_exports.enum(KEN_BURNS_FIT_MODES).optional().describe("Framing mode (image only). auto = cover for portrait, blur-pad for landscape."),
@@ -20144,8 +20173,8 @@ ${RENDER_ATTACH_RULE}`,
20144
20173
  volume: external_exports.number().min(0).max(1).optional().describe("Clip audio volume 0-1 (video only, default 0 = muted)")
20145
20174
  })
20146
20175
  ).min(1).max(20).describe("Media items (images, video clips, or a mix)"),
20147
- audio_url: external_exports.string().url().optional().describe("Audio track URL. Video duration matches audio duration."),
20148
- background_audio_url: external_exports.string().url().optional().describe("Ambience/music bed under the narration (crowd noise, room tone). Loops to fill the video. Find tracks with clipform_search_music."),
20176
+ audio_url: httpUrl().optional().describe("Audio track URL. Video duration matches audio duration."),
20177
+ 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."),
20149
20178
  background_audio_volume: external_exports.number().min(0).max(1).optional().describe("Background bed volume 0-1 (default 0.15 - sits under speech)"),
20150
20179
  duration_seconds: external_exports.number().positive().optional().describe("Video duration in seconds (required if no audio_url)"),
20151
20180
  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.`),
@@ -20681,6 +20710,7 @@ var MCP_SERVER_IDENTITY = Object.freeze({
20681
20710
  });
20682
20711
  function buildInstructions(caps) {
20683
20712
  return [
20713
+ buildOnboardingOffer(),
20684
20714
  "Clipform builds interactive video-style forms. When the brief is clear, build the form directly; when it's vague, ask one or two short questions first.",
20685
20715
  caps.media && "Prefer rich media: video over images over plain text.",
20686
20716
  caps.media ? "Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every rendering choice - narration tone, motion preset, music, pacing. Never mix registers in one form." : "Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every question, option, and end-screen line. Never mix registers in one form.",
@@ -20773,4 +20803,4 @@ export {
20773
20803
  buildInstructions,
20774
20804
  createServer
20775
20805
  };
20776
- //# sourceMappingURL=chunk-4YDGMSPG.js.map
20806
+ //# sourceMappingURL=chunk-2ONI6XP5.js.map