@clipform/mcp-server 1.29.0 → 1.31.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.
- package/README.md +1 -1
- package/dist/{chunk-5FG2V7B7.js → chunk-46RSQK6L.js} +55 -17
- package/dist/{chunk-5FG2V7B7.js.map → chunk-46RSQK6L.js.map} +1 -1
- package/dist/{chunk-6SFMF2AQ.js → chunk-ELO7KCMZ.js} +49 -61
- package/dist/{chunk-6SFMF2AQ.js.map → chunk-ELO7KCMZ.js.map} +1 -1
- package/dist/{chunk-B6ZWH3GD.js → chunk-J4KJN4C4.js} +2 -2
- package/dist/chunk-J4KJN4C4.js.map +1 -0
- package/dist/index.js +3 -3
- package/dist/prompts.js +1 -1
- package/dist/resources.js +1 -1
- package/dist/server.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-B6ZWH3GD.js.map +0 -1
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ You can also pass the key as a CLI flag: `npx -y @clipform/mcp-server --api-key=
|
|
|
55
55
|
|
|
56
56
|
| Tool | Description |
|
|
57
57
|
|------|-------------|
|
|
58
|
-
| `clipform_create_form` | Create a new form with nodes, theming, and tags in one call |
|
|
58
|
+
| `clipform_create_form` | Create a new form with nodes, theming, and tags in one call. Returns the created node IDs (structured output) so media steps need no follow-up lookup |
|
|
59
59
|
| `clipform_list_forms` | List forms in your workspace with filtering and pagination |
|
|
60
60
|
| `clipform_get_form` | View a form and all its nodes |
|
|
61
61
|
| `clipform_update_form` | Change title, publish status, or settings |
|
|
@@ -6,14 +6,14 @@ import {
|
|
|
6
6
|
getWorkflowText,
|
|
7
7
|
objectType,
|
|
8
8
|
registerPrompts
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ELO7KCMZ.js";
|
|
10
10
|
import {
|
|
11
11
|
GUIDE_TYPES,
|
|
12
12
|
QUIZ_VARIANTS,
|
|
13
13
|
getGuideContent,
|
|
14
14
|
getGuideUri,
|
|
15
15
|
registerResources
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-J4KJN4C4.js";
|
|
17
17
|
import {
|
|
18
18
|
BUSINESS,
|
|
19
19
|
CONTACT_FIELDS,
|
|
@@ -16988,6 +16988,8 @@ var PUBLIC_COMPOSITIONS = [
|
|
|
16988
16988
|
];
|
|
16989
16989
|
var LABS_COMPOSITIONS = [
|
|
16990
16990
|
"CountrySilhouetteClip",
|
|
16991
|
+
"FourImageGrid",
|
|
16992
|
+
"OddOneOutReveal",
|
|
16991
16993
|
"FlagRevealGB",
|
|
16992
16994
|
"FlagRevealJP",
|
|
16993
16995
|
"FlagRevealBR",
|
|
@@ -17094,7 +17096,7 @@ var CONFIG_DESCRIPTION = (() => {
|
|
|
17094
17096
|
var STYLE_PRESET_ENUM = external_exports.enum(KEN_BURNS_PRESETS).describe(`Ken Burns style preset: ${KEN_BURNS_PRESETS.join(", ")}`);
|
|
17095
17097
|
var OptionSchema = external_exports.object({
|
|
17096
17098
|
content: external_exports.string().describe("Option text"),
|
|
17097
|
-
score: external_exports.number().optional().describe("Score value for this option (for scored quizzes). Use 1 for correct, 0 for wrong."),
|
|
17099
|
+
score: external_exports.number().optional().describe("Score value for this option (for scored quizzes). Use 1 for correct, 0 for wrong. Scored options automatically enable correct-answer marking (record_scores) on the node."),
|
|
17098
17100
|
scores: external_exports.record(external_exports.number()).optional().describe("Planned feature - category-based scores keyed by category name. Not yet editable in the dashboard.")
|
|
17099
17101
|
});
|
|
17100
17102
|
var OPTIONS_DESCRIPTION = (() => {
|
|
@@ -17118,6 +17120,21 @@ var NodeSchema = external_exports.object({
|
|
|
17118
17120
|
config: external_exports.record(external_exports.unknown()).optional().describe(CONFIG_DESCRIPTION),
|
|
17119
17121
|
options: external_exports.array(OptionSchema).optional().describe(OPTIONS_DESCRIPTION)
|
|
17120
17122
|
});
|
|
17123
|
+
function applyNodeDefaults(node) {
|
|
17124
|
+
const def = NODE_TYPES[node.type];
|
|
17125
|
+
if (node.type === "button" && (!node.options || node.options.length === 0)) {
|
|
17126
|
+
const buttonDefault = def?.config_schema?.properties?.button_text?.default || "Continue";
|
|
17127
|
+
const label = node.config?.button_text || buttonDefault;
|
|
17128
|
+
node.options = [{ content: label }];
|
|
17129
|
+
}
|
|
17130
|
+
const supportsRecordScores = def?.config_schema?.properties?.choice?.properties?.record_scores !== void 0;
|
|
17131
|
+
const hasScoredOptions = node.options?.some((o) => o.score != null || o.scores != null);
|
|
17132
|
+
if (supportsRecordScores && hasScoredOptions) {
|
|
17133
|
+
const config2 = node.config ??= {};
|
|
17134
|
+
const choice = config2.choice ??= {};
|
|
17135
|
+
if (choice.record_scores === void 0) choice.record_scores = true;
|
|
17136
|
+
}
|
|
17137
|
+
}
|
|
17121
17138
|
|
|
17122
17139
|
// src/tools/create-form.ts
|
|
17123
17140
|
function registerCreateFormTool(server) {
|
|
@@ -17150,6 +17167,13 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
17150
17167
|
font_family: external_exports.string().optional().describe("AI-PROTECTED: Only set when the user explicitly requests a specific font."),
|
|
17151
17168
|
tags: external_exports.array(external_exports.string()).optional().describe("Tags for indexing (e.g. ['quiz', 'trivia', 'arsenal']). Include format, genre, and topics.")
|
|
17152
17169
|
},
|
|
17170
|
+
outputSchema: {
|
|
17171
|
+
form_id: external_exports.string().describe("Form UUID - pass to follow-up tools"),
|
|
17172
|
+
viewer_url: external_exports.string().describe("Live form URL for respondents"),
|
|
17173
|
+
dashboard_url: external_exports.string().optional().describe("Builder URL (sign in to edit)"),
|
|
17174
|
+
nodes: external_exports.array(external_exports.object({ id: external_exports.string(), type: external_exports.string(), prompt: external_exports.string() })).describe("Created nodes in order - IDs for upload_node_media / update_node"),
|
|
17175
|
+
plan: external_exports.object({ name: external_exports.string(), auth_mode: external_exports.string() }).optional().describe("Plan and auth context for this session")
|
|
17176
|
+
},
|
|
17153
17177
|
annotations: {
|
|
17154
17178
|
readOnlyHint: false,
|
|
17155
17179
|
destructiveHint: false,
|
|
@@ -17233,12 +17257,9 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
17233
17257
|
body: settingsBody
|
|
17234
17258
|
});
|
|
17235
17259
|
}
|
|
17260
|
+
const createdNodes = [];
|
|
17236
17261
|
for (const q of nodes) {
|
|
17237
|
-
|
|
17238
|
-
const buttonDefault = NODE_TYPES.button?.config_schema?.properties?.button_text?.default || "Continue";
|
|
17239
|
-
const label = q.config?.button_text || buttonDefault;
|
|
17240
|
-
q.options = [{ content: label }];
|
|
17241
|
-
}
|
|
17262
|
+
applyNodeDefaults(q);
|
|
17242
17263
|
const addResult = await callApi(`/forms/${formId}/nodes`, {
|
|
17243
17264
|
method: "POST",
|
|
17244
17265
|
body: { node: q }
|
|
@@ -17246,6 +17267,11 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
17246
17267
|
if (!addResult.ok) {
|
|
17247
17268
|
return errorResult(`Failed to add node "${q.prompt}": ${addResult.error}`);
|
|
17248
17269
|
}
|
|
17270
|
+
createdNodes.push({
|
|
17271
|
+
id: addResult.data.node_id,
|
|
17272
|
+
type: q.type,
|
|
17273
|
+
prompt: q.prompt
|
|
17274
|
+
});
|
|
17249
17275
|
}
|
|
17250
17276
|
if (tags && tags.length > 0) {
|
|
17251
17277
|
await callApi(`/forms/${formId}/tags`, {
|
|
@@ -17253,13 +17279,16 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
17253
17279
|
body: { tags }
|
|
17254
17280
|
});
|
|
17255
17281
|
}
|
|
17282
|
+
const truncate = (s, n = 60) => s.length > n ? `${s.slice(0, n - 1)}\u2026` : s;
|
|
17256
17283
|
const lines = [
|
|
17257
17284
|
`Form created and live.`,
|
|
17258
17285
|
``,
|
|
17259
17286
|
`Title: ${title}`,
|
|
17260
|
-
`Nodes: ${nodes.length}`,
|
|
17261
17287
|
`Form ID: ${formId}`,
|
|
17262
17288
|
``,
|
|
17289
|
+
`Node IDs (use directly with upload_node_media / update_node - no get_form round-trip needed):`,
|
|
17290
|
+
...createdNodes.map((n) => `- [${n.type}] "${truncate(n.prompt)}": ${n.id}`),
|
|
17291
|
+
``,
|
|
17263
17292
|
`FORM URL (live - share this with respondents): ${data.viewer_url}`
|
|
17264
17293
|
];
|
|
17265
17294
|
if (formUrl) {
|
|
@@ -17268,7 +17297,7 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
17268
17297
|
lines.push(
|
|
17269
17298
|
``,
|
|
17270
17299
|
`The form is live and accessible at the FORM URL above. Continue with media/narration steps if needed - changes appear immediately.`,
|
|
17271
|
-
`
|
|
17300
|
+
`The URLs above are exact values; constructed or guessed URLs return 404. Use the FORM URL and DASHBOARD URL as shown.`,
|
|
17272
17301
|
`Pass form_id on follow-up tools (get_form, add_node, upload_node_media, etc.).`
|
|
17273
17302
|
);
|
|
17274
17303
|
if (planContext) {
|
|
@@ -17287,7 +17316,16 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
17287
17316
|
);
|
|
17288
17317
|
}
|
|
17289
17318
|
}
|
|
17290
|
-
return
|
|
17319
|
+
return {
|
|
17320
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
17321
|
+
structuredContent: {
|
|
17322
|
+
form_id: formId,
|
|
17323
|
+
viewer_url: data.viewer_url,
|
|
17324
|
+
...formUrl ? { dashboard_url: formUrl } : {},
|
|
17325
|
+
nodes: createdNodes,
|
|
17326
|
+
...planContext ? { plan: { name: planContext.plan_name, auth_mode: planContext.auth_mode } } : {}
|
|
17327
|
+
}
|
|
17328
|
+
};
|
|
17291
17329
|
}
|
|
17292
17330
|
);
|
|
17293
17331
|
}
|
|
@@ -17592,11 +17630,7 @@ function registerAddNodeTool(server) {
|
|
|
17592
17630
|
}
|
|
17593
17631
|
},
|
|
17594
17632
|
async ({ form_id, node, after_node_id }) => {
|
|
17595
|
-
|
|
17596
|
-
const buttonDefault = NODE_TYPES.button?.config_schema?.properties?.button_text?.default || "Continue";
|
|
17597
|
-
const label = node.config?.button_text || buttonDefault;
|
|
17598
|
-
node.options = [{ content: label }];
|
|
17599
|
-
}
|
|
17633
|
+
applyNodeDefaults(node);
|
|
17600
17634
|
const body = { node };
|
|
17601
17635
|
if (after_node_id) body.after_node_id = after_node_id;
|
|
17602
17636
|
const result = await callApi(`/forms/${form_id}/nodes`, {
|
|
@@ -17669,6 +17703,10 @@ function registerUpdateNodeTool(server) {
|
|
|
17669
17703
|
if (options !== void 0)
|
|
17670
17704
|
changes.push(`Options \u2192 ${options.map((o) => o.content).join(", ")}`);
|
|
17671
17705
|
allLines.push(`Node ${node_id} updated: ${changes.join(", ")}`);
|
|
17706
|
+
const warnings = result.data.warnings;
|
|
17707
|
+
if (warnings?.length) {
|
|
17708
|
+
for (const w of warnings) allLines.push(`Node ${node_id} warning: ${w}`);
|
|
17709
|
+
}
|
|
17672
17710
|
}
|
|
17673
17711
|
return textResult(allLines.join("\n"));
|
|
17674
17712
|
}
|
|
@@ -18829,4 +18867,4 @@ export {
|
|
|
18829
18867
|
JSONRPCMessageSchema,
|
|
18830
18868
|
createServer
|
|
18831
18869
|
};
|
|
18832
|
-
//# sourceMappingURL=chunk-
|
|
18870
|
+
//# sourceMappingURL=chunk-46RSQK6L.js.map
|