@clipform/mcp-server 1.44.4 → 1.46.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-6IRFVCIG.js";
9
+ } from "./chunk-QLREKMS2.js";
10
10
  import {
11
11
  GUIDE_TYPES,
12
12
  QUIZ_VARIANTS,
@@ -14,8 +14,9 @@ import {
14
14
  getGuideUri,
15
15
  guideFallbackText,
16
16
  registerResources
17
- } from "./chunk-GAAMMQM3.js";
17
+ } from "./chunk-PCWSRPV6.js";
18
18
  import {
19
+ ACTIVE_NODE_TYPES,
19
20
  BUSINESS,
20
21
  CONTACT_FIELDS,
21
22
  FORM_TYPE_ALIASES,
@@ -33,7 +34,7 @@ import {
33
34
  errorResult,
34
35
  resolveFormType,
35
36
  textResult
36
- } from "./chunk-PCCTN3T7.js";
37
+ } from "./chunk-AHWMH66L.js";
37
38
  import {
38
39
  __commonJS,
39
40
  __export,
@@ -16996,7 +16997,7 @@ var EXPOSED_COMPOSITIONS = [
16996
16997
  ];
16997
16998
 
16998
16999
  // src/lib/schemas.ts
16999
- var ACTIVE_NODE_TYPES = Object.entries(NODE_TYPES).filter(([, def]) => def.is_active && !def.is_system).map(([type]) => type);
17000
+ var ACTIVE_NODE_TYPES2 = ACTIVE_NODE_TYPES;
17000
17001
  var CONTACT_FIELD_IDS = CONTACT_FIELDS.map(
17001
17002
  (f) => f.id
17002
17003
  );
@@ -17051,7 +17052,7 @@ function formatDefaultConfig(defaultConfig) {
17051
17052
  }
17052
17053
  var NODE_TYPES_DESCRIPTION = (() => {
17053
17054
  const lines = ["Node types (omit config to use defaults where shown):"];
17054
- for (const type of ACTIVE_NODE_TYPES) {
17055
+ for (const type of ACTIVE_NODE_TYPES2) {
17055
17056
  const def = NODE_TYPES[type];
17056
17057
  let line = `- ${type}: ${def.description || def.label}`;
17057
17058
  if (def.has_options) {
@@ -17078,7 +17079,7 @@ var OptionSchema = external_exports.object({
17078
17079
  });
17079
17080
  var OPTIONS_DESCRIPTION = (() => {
17080
17081
  const hints = ["Answer options."];
17081
- for (const type of ACTIVE_NODE_TYPES) {
17082
+ for (const type of ACTIVE_NODE_TYPES2) {
17082
17083
  const def = NODE_TYPES[type];
17083
17084
  if (!def.has_options) continue;
17084
17085
  const parts = [`${type}: required`];
@@ -17090,7 +17091,7 @@ var OPTIONS_DESCRIPTION = (() => {
17090
17091
  return hints.join(" ");
17091
17092
  })();
17092
17093
  var NodeSchema = external_exports.object({
17093
- type: external_exports.enum(ACTIVE_NODE_TYPES),
17094
+ type: external_exports.enum(ACTIVE_NODE_TYPES2),
17094
17095
  prompt: external_exports.string().describe("The text shown to the respondent"),
17095
17096
  label: external_exports.string().optional().describe("Short label for the node (used in logic builder). Defaults to the prompt text."),
17096
17097
  required: external_exports.boolean().optional().default(true),
@@ -17123,7 +17124,7 @@ function registerCreateFormTool(server) {
17123
17124
 
17124
17125
  ${NODE_TYPES_DESCRIPTION}
17125
17126
 
17126
- All type definitions and config schemas are derived from @vid-master/config (answer-types). Refer to the config descriptions above for the correct keys and shapes. AI-PROTECTED parameters have restrictions noted in their descriptions.
17127
+ 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.
17127
17128
 
17128
17129
  Example: A form that asks a question, collects contact info, then finishes:
17129
17130
  {
@@ -17155,7 +17156,7 @@ Example: A form that asks a question, collects contact info, then finishes:
17155
17156
  readOnlyHint: false,
17156
17157
  destructiveHint: false,
17157
17158
  idempotentHint: false,
17158
- openWorldHint: true
17159
+ openWorldHint: false
17159
17160
  },
17160
17161
  _meta: { "anthropic/alwaysLoad": true }
17161
17162
  },
@@ -17292,7 +17293,11 @@ Example: A form that asks a question, collects contact info, then finishes:
17292
17293
  form_id: formId,
17293
17294
  viewer_url: data.viewer_url,
17294
17295
  ...formUrl ? { dashboard_url: formUrl } : {},
17295
- nodes: createdNodes,
17296
+ // Project to just the fields the agent needs - the API node rows may
17297
+ // carry created_at/config/etc., and a cast doesn't strip them at
17298
+ // runtime. structuredContent should return only relevant data (ChatGPT
17299
+ // App Directory response-hygiene policy, #797).
17300
+ nodes: createdNodes.map((n) => ({ id: n.id, type: n.type, prompt: n.prompt })),
17296
17301
  ...planContext ? { plan: { name: planContext.plan_name, auth_mode: planContext.auth_mode } } : {}
17297
17302
  }
17298
17303
  };
@@ -17324,7 +17329,7 @@ function registerListFormsTool(server) {
17324
17329
  readOnlyHint: true,
17325
17330
  destructiveHint: false,
17326
17331
  idempotentHint: true,
17327
- openWorldHint: true
17332
+ openWorldHint: false
17328
17333
  }
17329
17334
  },
17330
17335
  async ({ limit, cursor, tag, published, search, sort, order }) => {
@@ -17407,7 +17412,7 @@ function registerGetFormTool(server) {
17407
17412
  readOnlyHint: true,
17408
17413
  destructiveHint: false,
17409
17414
  idempotentHint: true,
17410
- openWorldHint: true
17415
+ openWorldHint: false
17411
17416
  }
17412
17417
  },
17413
17418
  async ({ form_id }) => {
@@ -17448,7 +17453,7 @@ function registerUpdateFormTool(server) {
17448
17453
  readOnlyHint: false,
17449
17454
  destructiveHint: false,
17450
17455
  idempotentHint: true,
17451
- openWorldHint: true
17456
+ openWorldHint: false
17452
17457
  }
17453
17458
  },
17454
17459
  async ({ form_id, title, is_live, show_step_counter, disable_back_navigation, total_steps, primary_color, background_color, font_family, description, author, logo_url, show_branding, brand_name, tags }) => {
@@ -17555,7 +17560,7 @@ function registerDeleteFormTool(server) {
17555
17560
  readOnlyHint: false,
17556
17561
  destructiveHint: true,
17557
17562
  idempotentHint: false,
17558
- openWorldHint: true
17563
+ openWorldHint: false
17559
17564
  }
17560
17565
  },
17561
17566
  async ({ form_id, confirm }) => {
@@ -17596,7 +17601,7 @@ function registerAddNodeTool(server) {
17596
17601
  readOnlyHint: false,
17597
17602
  destructiveHint: false,
17598
17603
  idempotentHint: false,
17599
- openWorldHint: true
17604
+ openWorldHint: false
17600
17605
  }
17601
17606
  },
17602
17607
  async ({ form_id, node, after_node_id }) => {
@@ -17622,7 +17627,7 @@ var NodeUpdateSchema = external_exports.object({
17622
17627
  node_id: external_exports.string().describe("The node ID to update"),
17623
17628
  prompt: external_exports.string().optional().describe("New node prompt text"),
17624
17629
  label: external_exports.string().optional().describe("Short label for the node (used in logic builder)"),
17625
- type: external_exports.enum(ACTIVE_NODE_TYPES).optional().describe("Change the node type"),
17630
+ type: external_exports.enum(ACTIVE_NODE_TYPES2).optional().describe("Change the node type"),
17626
17631
  required: external_exports.boolean().optional().describe("Whether an answer is required"),
17627
17632
  config: external_exports.record(external_exports.unknown()).optional().describe(CONFIG_FIELD_DESCRIPTION),
17628
17633
  options: external_exports.array(OptionSchema).optional().describe(
@@ -17634,7 +17639,7 @@ function registerUpdateNodeTool(server) {
17634
17639
  "clipform_update_node",
17635
17640
  {
17636
17641
  title: "Update Node",
17637
- description: `Update one or more existing nodes' text, type, config, or options. Pass multiple updates in one call instead of separate tool calls. Requires node IDs (returned by clipform_create_form, clipform_add_node, or clipform_get_form). Does not change node positions in the flow. All type definitions and config schemas are derived from @vid-master/config (answer-types).`,
17642
+ description: `Update one or more existing nodes' text, type, config, or options. Pass multiple updates in one call instead of separate tool calls. Requires node IDs (returned by clipform_create_form, clipform_add_node, or clipform_get_form). Does not change node positions in the flow. All type definitions and config schemas are derived from @vid-master/config (node-types).`,
17638
17643
  inputSchema: {
17639
17644
  form_id: external_exports.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
17640
17645
  updates: external_exports.array(NodeUpdateSchema).min(1).max(20).describe("One or more node updates to apply")
@@ -17643,7 +17648,7 @@ function registerUpdateNodeTool(server) {
17643
17648
  readOnlyHint: false,
17644
17649
  destructiveHint: false,
17645
17650
  idempotentHint: true,
17646
- openWorldHint: true
17651
+ openWorldHint: false
17647
17652
  }
17648
17653
  },
17649
17654
  async ({ form_id, updates }) => {
@@ -17699,7 +17704,7 @@ function registerDeleteNodeTool(server) {
17699
17704
  readOnlyHint: false,
17700
17705
  destructiveHint: true,
17701
17706
  idempotentHint: false,
17702
- openWorldHint: true
17707
+ openWorldHint: false
17703
17708
  }
17704
17709
  },
17705
17710
  async ({ form_id, node_id, confirm }) => {
@@ -17763,7 +17768,7 @@ When a public URL is provided, the media is fetched and stored automatically. On
17763
17768
  readOnlyHint: false,
17764
17769
  destructiveHint: false,
17765
17770
  idempotentHint: false,
17766
- openWorldHint: true
17771
+ openWorldHint: false
17767
17772
  }
17768
17773
  },
17769
17774
  async ({ form_id, items }) => {
@@ -17786,13 +17791,15 @@ When a public URL is provided, the media is fetched and stored automatically. On
17786
17791
  );
17787
17792
  if (result.ok) {
17788
17793
  successCount++;
17789
- const resultLines = [`Media ID: ${result.data.media_id}`];
17794
+ const resultLines = [];
17790
17795
  if (result.data.upload_url) {
17791
17796
  resultLines.push(
17792
17797
  `Upload URL: ${result.data.upload_url}`,
17793
17798
  `Upload method: ${result.data.upload_method}`,
17794
17799
  `Upload the file directly to the upload URL using ${result.data.upload_method === "tus" ? "TUS resumable upload" : "HTTP PUT"}.`
17795
17800
  );
17801
+ } else {
17802
+ resultLines.push(`Media stored.`);
17796
17803
  }
17797
17804
  if (item.captions) {
17798
17805
  resultLines.push(`Captions: ${item.captions.length} segments saved`);
@@ -17806,8 +17813,6 @@ When a public URL is provided, the media is fetched and stored automatically. On
17806
17813
  if (items.length > 1) {
17807
17814
  lines.unshift(`Media upload: ${successCount}/${items.length} succeeded
17808
17815
  `);
17809
- } else if (successCount > 0) {
17810
- lines.unshift(`Media uploaded successfully.`);
17811
17816
  }
17812
17817
  if (successCount === 0) return errorResult(lines.join("\n"));
17813
17818
  return textResult(lines.join("\n"));
@@ -17830,7 +17835,7 @@ function registerGetNodeMediaTool(server) {
17830
17835
  readOnlyHint: true,
17831
17836
  destructiveHint: false,
17832
17837
  idempotentHint: true,
17833
- openWorldHint: true
17838
+ openWorldHint: false
17834
17839
  }
17835
17840
  },
17836
17841
  async ({ form_id, node_id }) => {
@@ -17872,7 +17877,7 @@ function registerDeleteNodeMediaTool(server) {
17872
17877
  readOnlyHint: false,
17873
17878
  destructiveHint: true,
17874
17879
  idempotentHint: false,
17875
- openWorldHint: true
17880
+ openWorldHint: false
17876
17881
  }
17877
17882
  },
17878
17883
  async ({ form_id, node_id, confirm }) => {
@@ -17929,7 +17934,7 @@ Example:
17929
17934
  readOnlyHint: false,
17930
17935
  destructiveHint: false,
17931
17936
  idempotentHint: true,
17932
- openWorldHint: true
17937
+ openWorldHint: false
17933
17938
  }
17934
17939
  },
17935
17940
  async ({ form_id, nodes }) => {
@@ -18004,7 +18009,7 @@ Returns: article title, source, author, date, URL, description, and image URL pe
18004
18009
  query: external_exports.string().describe("News search query (e.g. 'Iran war 2026', 'Australian Open final', 'UK election')"),
18005
18010
  count: external_exports.number().min(1).max(15).default(5).optional().describe("Max results per provider (default 5)")
18006
18011
  },
18007
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
18012
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
18008
18013
  },
18009
18014
  async ({ query, count }) => {
18010
18015
  const result = await callApi("/internal/search-news", {
@@ -18053,7 +18058,7 @@ Supports any public YouTube video with captions enabled. Does NOT work for priva
18053
18058
  readOnlyHint: true,
18054
18059
  destructiveHint: false,
18055
18060
  idempotentHint: true,
18056
- openWorldHint: true
18061
+ openWorldHint: false
18057
18062
  }
18058
18063
  },
18059
18064
  async ({ url, lang, max_chars }) => {
@@ -18100,7 +18105,7 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio U
18100
18105
  inputSchema: {
18101
18106
  items: external_exports.array(TtsItemSchema).min(1).max(10).describe("One or more TTS items to generate")
18102
18107
  },
18103
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }
18108
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }
18104
18109
  },
18105
18110
  async ({ items }) => {
18106
18111
  const workspace_id = getMcpAuth()?.workspace_id;
@@ -18121,7 +18126,14 @@ Pass one item or many (max 10) - multiple items run in parallel. Returns audio U
18121
18126
  successCount++;
18122
18127
  const data = r.value.data;
18123
18128
  lines.push(`Audio URL: ${data.audioUrl}`);
18124
- lines.push(`Captions: ${JSON.stringify(data.captions)}`);
18129
+ const rawCaptions = Array.isArray(data.captions) ? data.captions : [];
18130
+ const captions = rawCaptions.map((c) => ({
18131
+ start: c.start,
18132
+ end: c.end,
18133
+ text: c.text,
18134
+ ...Array.isArray(c.words) ? { words: c.words.map((w) => ({ word: w.word, start: w.start, end: w.end })) } : {}
18135
+ }));
18136
+ lines.push(`Captions: ${JSON.stringify(captions)}`);
18125
18137
  } else {
18126
18138
  const error2 = r.status === "rejected" ? r.reason?.message || String(r.reason) : r.value.error;
18127
18139
  const status = r.status === "fulfilled" ? r.value.status : 0;
@@ -18160,7 +18172,7 @@ Example: { queries: [{ query: "saturn rings" }, { query: "mars surface", count:
18160
18172
  })
18161
18173
  ).min(1).max(10).describe("One or more search queries to run")
18162
18174
  },
18163
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
18175
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
18164
18176
  },
18165
18177
  async ({ queries }) => {
18166
18178
  const allLines = [];
@@ -18398,7 +18410,7 @@ function registerSearchMusicTool(server) {
18398
18410
  maxDuration: external_exports.number().optional().describe("Maximum duration in seconds"),
18399
18411
  tags: external_exports.array(external_exports.string()).optional().describe("Genre/mood tags to filter by")
18400
18412
  },
18401
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
18413
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
18402
18414
  },
18403
18415
  async ({ query, count, instrumentalOnly, minDuration, maxDuration, tags }) => {
18404
18416
  const result = await callApi("/internal/search-music", {
@@ -18582,7 +18594,7 @@ For multi-question builds, pass wait: false on every render: each call returns a
18582
18594
  background_color: external_exports.string().optional().describe("Background color (default '#000')"),
18583
18595
  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.")
18584
18596
  },
18585
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }
18597
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }
18586
18598
  },
18587
18599
  async ({ items, audio_url, background_audio_url, background_audio_volume, duration_seconds, random_effects, transition, style_preset, texture, duotone, background_color, wait }) => {
18588
18600
  const workspace_id = getMcpAuth()?.workspace_id;
@@ -18760,7 +18772,7 @@ mainlandOnly excludes small islands and overseas territories (e.g. Corsica for F
18760
18772
  mainlandOnly: external_exports.boolean().default(true).describe("Keep only the largest landmass, excluding small islands and overseas territories"),
18761
18773
  maxPoints: external_exports.number().default(500).describe("Maximum points per polygon ring for simplification (default 500, lower = smaller payload)")
18762
18774
  },
18763
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
18775
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
18764
18776
  },
18765
18777
  async ({ query, type, mainlandOnly, maxPoints }) => {
18766
18778
  const params = new URLSearchParams({
@@ -19035,4 +19047,4 @@ export {
19035
19047
  JSONRPCMessageSchema,
19036
19048
  createServer
19037
19049
  };
19038
- //# sourceMappingURL=chunk-MSXDS22S.js.map
19050
+ //# sourceMappingURL=chunk-UM6UZ7GH.js.map