@clipform/mcp-server 1.13.0 → 1.15.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/dist/auth-context.d.ts +3 -1
- package/dist/auth-context.js +5 -3
- package/dist/{chunk-3EHPLYCP.js → chunk-2SPXROLZ.js} +70 -69
- package/dist/{chunk-3EHPLYCP.js.map → chunk-2SPXROLZ.js.map} +1 -1
- package/dist/{chunk-YEDU3G7I.js → chunk-VWGIVJMQ.js} +8 -2
- package/dist/chunk-VWGIVJMQ.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-YEDU3G7I.js.map +0 -1
package/dist/auth-context.d.ts
CHANGED
|
@@ -12,8 +12,10 @@ interface McpAuthContext {
|
|
|
12
12
|
user_id: string;
|
|
13
13
|
workspace_id: string;
|
|
14
14
|
scopes: string[];
|
|
15
|
+
tool_name?: string;
|
|
15
16
|
}
|
|
16
17
|
declare function runWithMcpAuth<T>(ctx: McpAuthContext, fn: () => Promise<T> | T): Promise<T> | T;
|
|
17
18
|
declare function getMcpAuth(): McpAuthContext | undefined;
|
|
19
|
+
declare function runWithMcpTool<T>(toolName: string, fn: () => Promise<T> | T): Promise<T> | T;
|
|
18
20
|
|
|
19
|
-
export { type McpAuthContext, getMcpAuth, runWithMcpAuth };
|
|
21
|
+
export { type McpAuthContext, getMcpAuth, runWithMcpAuth, runWithMcpTool };
|
package/dist/auth-context.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getMcpAuth,
|
|
3
|
-
runWithMcpAuth
|
|
4
|
-
|
|
3
|
+
runWithMcpAuth,
|
|
4
|
+
runWithMcpTool
|
|
5
|
+
} from "./chunk-VWGIVJMQ.js";
|
|
5
6
|
export {
|
|
6
7
|
getMcpAuth,
|
|
7
|
-
runWithMcpAuth
|
|
8
|
+
runWithMcpAuth,
|
|
9
|
+
runWithMcpTool
|
|
8
10
|
};
|
|
9
11
|
//# sourceMappingURL=auth-context.js.map
|
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
__commonJS,
|
|
3
3
|
__export,
|
|
4
4
|
__toESM,
|
|
5
|
-
getMcpAuth
|
|
6
|
-
|
|
5
|
+
getMcpAuth,
|
|
6
|
+
runWithMcpTool
|
|
7
|
+
} from "./chunk-VWGIVJMQ.js";
|
|
7
8
|
|
|
8
9
|
// ../../node_modules/@modelcontextprotocol/sdk/node_modules/ajv/dist/compile/codegen/code.js
|
|
9
10
|
var require_code = __commonJS({
|
|
@@ -20906,7 +20907,7 @@ var NODE_TYPES = {
|
|
|
20906
20907
|
shorthand: "Start",
|
|
20907
20908
|
icon: "ArrowRight",
|
|
20908
20909
|
color: "#D1FAE5",
|
|
20909
|
-
description: "Entry point for the form - connects to the first
|
|
20910
|
+
description: "Entry point for the form - connects to the first node",
|
|
20910
20911
|
category: "start",
|
|
20911
20912
|
sort_order: 0,
|
|
20912
20913
|
has_options: false,
|
|
@@ -20927,11 +20928,12 @@ var NODE_TYPES = {
|
|
|
20927
20928
|
shorthand: "Multi",
|
|
20928
20929
|
icon: "CheckSquare",
|
|
20929
20930
|
color: "#DBEAFE",
|
|
20930
|
-
description: "Single or multiple choice
|
|
20931
|
-
category: "
|
|
20931
|
+
description: "Single or multiple choice node with predefined options",
|
|
20932
|
+
category: "input",
|
|
20932
20933
|
sort_order: 1,
|
|
20933
20934
|
has_options: true,
|
|
20934
20935
|
min_options: 1,
|
|
20936
|
+
max_options: 6,
|
|
20935
20937
|
max_option_length: 36,
|
|
20936
20938
|
is_terminal: false,
|
|
20937
20939
|
show_nav_bar: true,
|
|
@@ -21005,7 +21007,7 @@ var NODE_TYPES = {
|
|
|
21005
21007
|
enum: ["upload", "recorded"],
|
|
21006
21008
|
type: "string",
|
|
21007
21009
|
label: "Content media type",
|
|
21008
|
-
description: "How the
|
|
21010
|
+
description: "How the node media was provided"
|
|
21009
21011
|
}
|
|
21010
21012
|
}
|
|
21011
21013
|
},
|
|
@@ -21029,7 +21031,7 @@ var NODE_TYPES = {
|
|
|
21029
21031
|
icon: "Type",
|
|
21030
21032
|
color: "#DBEAFE",
|
|
21031
21033
|
description: "Free-form text responses from users",
|
|
21032
|
-
category: "
|
|
21034
|
+
category: "input",
|
|
21033
21035
|
sort_order: 2,
|
|
21034
21036
|
has_options: false,
|
|
21035
21037
|
is_terminal: false,
|
|
@@ -21065,7 +21067,7 @@ var NODE_TYPES = {
|
|
|
21065
21067
|
enum: ["upload", "recorded"],
|
|
21066
21068
|
type: "string",
|
|
21067
21069
|
label: "Content media type",
|
|
21068
|
-
description: "How the
|
|
21070
|
+
description: "How the node media was provided"
|
|
21069
21071
|
}
|
|
21070
21072
|
}
|
|
21071
21073
|
},
|
|
@@ -21129,8 +21131,8 @@ var NODE_TYPES = {
|
|
|
21129
21131
|
shorthand: "Scale",
|
|
21130
21132
|
icon: "BarChart3",
|
|
21131
21133
|
color: "#DBEAFE",
|
|
21132
|
-
description: "Numerical rating or scale
|
|
21133
|
-
category: "
|
|
21134
|
+
description: "Numerical rating or scale node (1-10, etc.)",
|
|
21135
|
+
category: "input",
|
|
21134
21136
|
sort_order: 3,
|
|
21135
21137
|
has_options: false,
|
|
21136
21138
|
is_terminal: false,
|
|
@@ -21205,7 +21207,7 @@ var NODE_TYPES = {
|
|
|
21205
21207
|
}
|
|
21206
21208
|
}
|
|
21207
21209
|
],
|
|
21208
|
-
description: "Booking provider configuration (one provider per
|
|
21210
|
+
description: "Booking provider configuration (one provider per node)"
|
|
21209
21211
|
},
|
|
21210
21212
|
response_schema: {
|
|
21211
21213
|
type: "object",
|
|
@@ -21399,7 +21401,7 @@ var NODE_TYPES = {
|
|
|
21399
21401
|
size: { type: "integer", minimum: 1, description: "File size in bytes" },
|
|
21400
21402
|
mime_type: { type: "string", description: "File MIME type" },
|
|
21401
21403
|
uploaded_at: { type: "string", format: "date-time", description: "ISO timestamp of upload completion" },
|
|
21402
|
-
storage_path: { type: "string", description: "Full storage path: workspace_id/form_id/
|
|
21404
|
+
storage_path: { type: "string", description: "Full storage path: workspace_id/form_id/node_id/uuid.ext" }
|
|
21403
21405
|
}
|
|
21404
21406
|
},
|
|
21405
21407
|
minItems: 1,
|
|
@@ -21496,7 +21498,7 @@ var NODE_TYPES = {
|
|
|
21496
21498
|
icon: "CircleCheck",
|
|
21497
21499
|
color: "#D1FAE5",
|
|
21498
21500
|
description: "Two-option choice - yes/no, true/false, or this vs that",
|
|
21499
|
-
category: "
|
|
21501
|
+
category: "input",
|
|
21500
21502
|
sort_order: 1.5,
|
|
21501
21503
|
has_options: true,
|
|
21502
21504
|
min_options: 2,
|
|
@@ -21534,7 +21536,7 @@ var NODE_TYPES = {
|
|
|
21534
21536
|
enum: ["upload", "recorded"],
|
|
21535
21537
|
type: "string",
|
|
21536
21538
|
label: "Content media type",
|
|
21537
|
-
description: "How the
|
|
21539
|
+
description: "How the node media was provided"
|
|
21538
21540
|
}
|
|
21539
21541
|
}
|
|
21540
21542
|
},
|
|
@@ -21558,7 +21560,7 @@ var NODE_TYPES = {
|
|
|
21558
21560
|
icon: "RectangleHorizontal",
|
|
21559
21561
|
color: "#DBEAFE",
|
|
21560
21562
|
description: "Simple button for acknowledgment or navigation",
|
|
21561
|
-
category: "
|
|
21563
|
+
category: "input",
|
|
21562
21564
|
sort_order: 3,
|
|
21563
21565
|
has_options: true,
|
|
21564
21566
|
min_options: 1,
|
|
@@ -21795,7 +21797,7 @@ var NODE_TYPES = {
|
|
|
21795
21797
|
output_schema: null
|
|
21796
21798
|
},
|
|
21797
21799
|
end_screen: {
|
|
21798
|
-
label: "
|
|
21800
|
+
label: "Ending",
|
|
21799
21801
|
shorthand: "End",
|
|
21800
21802
|
icon: "Flag",
|
|
21801
21803
|
color: "#FEE2E2",
|
|
@@ -21807,7 +21809,7 @@ var NODE_TYPES = {
|
|
|
21807
21809
|
show_nav_bar: false,
|
|
21808
21810
|
loading: "eager",
|
|
21809
21811
|
supports_prompt: false,
|
|
21810
|
-
supports_media:
|
|
21812
|
+
supports_media: false,
|
|
21811
21813
|
is_system: false,
|
|
21812
21814
|
is_active: true,
|
|
21813
21815
|
default_config: null,
|
|
@@ -22235,6 +22237,7 @@ async function callApi(path, options = {}) {
|
|
|
22235
22237
|
headers["Authorization"] = `Bearer ${INTERNAL_SECRET}`;
|
|
22236
22238
|
headers["X-Mcp-User"] = mcpAuth.user_id;
|
|
22237
22239
|
headers["X-Mcp-Workspace"] = mcpAuth.workspace_id;
|
|
22240
|
+
if (mcpAuth.tool_name) headers["X-Mcp-Tool"] = mcpAuth.tool_name;
|
|
22238
22241
|
} else if (_apiKey) {
|
|
22239
22242
|
headers["Authorization"] = `Bearer ${_apiKey}`;
|
|
22240
22243
|
}
|
|
@@ -22277,7 +22280,13 @@ async function callInternalApi(path, options = {}) {
|
|
|
22277
22280
|
const headers = {
|
|
22278
22281
|
"Content-Type": "application/json"
|
|
22279
22282
|
};
|
|
22280
|
-
|
|
22283
|
+
const mcpAuth = getMcpAuth();
|
|
22284
|
+
if (mcpAuth && INTERNAL_SECRET) {
|
|
22285
|
+
headers["Authorization"] = `Bearer ${INTERNAL_SECRET}`;
|
|
22286
|
+
headers["X-Mcp-User"] = mcpAuth.user_id;
|
|
22287
|
+
headers["X-Mcp-Workspace"] = mcpAuth.workspace_id;
|
|
22288
|
+
if (mcpAuth.tool_name) headers["X-Mcp-Tool"] = mcpAuth.tool_name;
|
|
22289
|
+
} else if (_apiKey) {
|
|
22281
22290
|
headers["Authorization"] = `Bearer ${_apiKey}`;
|
|
22282
22291
|
} else if (INTERNAL_SECRET) {
|
|
22283
22292
|
headers["Authorization"] = `Bearer ${INTERNAL_SECRET}`;
|
|
@@ -22338,7 +22347,7 @@ All type definitions and config schemas are derived from @vid-master/config (ans
|
|
|
22338
22347
|
Example: A form that asks a question, collects contact info, then finishes:
|
|
22339
22348
|
{
|
|
22340
22349
|
title: "Quick Survey",
|
|
22341
|
-
|
|
22350
|
+
nodes: [
|
|
22342
22351
|
{ type: "open", prompt: "What's your biggest challenge?" },
|
|
22343
22352
|
{ type: "contact", prompt: "Leave your details", config: { fields: [{ id: "first_name", required: true }, { id: "email", required: true }] } },
|
|
22344
22353
|
{ type: "end_screen", prompt: "Thanks for your response!" }
|
|
@@ -22346,11 +22355,11 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
22346
22355
|
}`,
|
|
22347
22356
|
inputSchema: {
|
|
22348
22357
|
title: external_exports.string().describe("Form title"),
|
|
22349
|
-
|
|
22358
|
+
nodes: external_exports.array(NodeSchema).min(1).describe("Ordered list of nodes/steps for the form"),
|
|
22350
22359
|
show_step_counter: external_exports.boolean().optional().describe("Show step counter (e.g. '1/5'). Set true for quizzes."),
|
|
22351
22360
|
disable_back_navigation: external_exports.boolean().optional().describe("Prevent going back. Set true for quizzes."),
|
|
22352
|
-
primary_color: external_exports.string().optional().describe("Primary/brand color
|
|
22353
|
-
background_color: external_exports.string().optional().describe("Background color
|
|
22361
|
+
primary_color: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Primary/brand color as 6-digit hex (e.g. '#FF5500'). Used for buttons and accents."),
|
|
22362
|
+
background_color: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Background color as 6-digit hex (e.g. '#1A1A2E')."),
|
|
22354
22363
|
font_family: external_exports.string().optional().describe("Font family name (e.g. 'Inter', 'Roboto', 'Playfair Display')."),
|
|
22355
22364
|
embed_autoplay: external_exports.boolean().optional().describe("Auto-play video when embedded (default: false). When off, embeds show a thumbnail + play button."),
|
|
22356
22365
|
tags: external_exports.array(external_exports.string()).optional().describe("Tags for indexing (e.g. ['quiz', 'trivia', 'arsenal']). Include format, genre, and topics.")
|
|
@@ -22362,7 +22371,7 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
22362
22371
|
openWorldHint: true
|
|
22363
22372
|
}
|
|
22364
22373
|
},
|
|
22365
|
-
async ({ title,
|
|
22374
|
+
async ({ title, nodes, show_step_counter, disable_back_navigation, primary_color, background_color, font_family, embed_autoplay, tags }) => {
|
|
22366
22375
|
let planContext = null;
|
|
22367
22376
|
const meResult = await callApi("/me", { method: "GET" });
|
|
22368
22377
|
if (!meResult.ok) {
|
|
@@ -22382,10 +22391,10 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
22382
22391
|
plan_name: me.plan?.name ?? "Free",
|
|
22383
22392
|
node_limit: me.plan?.node_limit ?? null
|
|
22384
22393
|
};
|
|
22385
|
-
const contentCount =
|
|
22394
|
+
const contentCount = nodes.filter((q) => q.type !== "end_screen").length;
|
|
22386
22395
|
if (planContext.node_limit !== null && contentCount > planContext.node_limit) {
|
|
22387
22396
|
const upgradeUrl = `${BUSINESS.urls.dashboard}/billing`;
|
|
22388
|
-
const message = planContext.auth_mode === "oauth" ? `Your '${planContext.workspace_name}' workspace is on the ${planContext.plan_name} plan, capped at ${planContext.node_limit}
|
|
22397
|
+
const message = planContext.auth_mode === "oauth" ? `Your '${planContext.workspace_name}' workspace is on the ${planContext.plan_name} plan, capped at ${planContext.node_limit} nodes per form. You asked for ${contentCount}. Either rerun with ${planContext.node_limit} nodes or upgrade at ${upgradeUrl}.` : `Anonymous sessions are capped at ${planContext.node_limit} nodes per form (${planContext.plan_name} plan). You asked for ${contentCount}. Either rerun with ${planContext.node_limit} nodes, or connect your Clipform account in claude.ai \u2192 Settings \u2192 Connectors so forms land in your workspace with your real plan limits.`;
|
|
22389
22398
|
return errorResult(message);
|
|
22390
22399
|
}
|
|
22391
22400
|
const createResult = await callApi("/forms", {
|
|
@@ -22411,29 +22420,13 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
22411
22420
|
body: settingsBody
|
|
22412
22421
|
});
|
|
22413
22422
|
}
|
|
22414
|
-
for (const q of
|
|
22415
|
-
if (q.type === "end_screen") {
|
|
22416
|
-
const getResult = await callApi(`/forms/${formId}`, {
|
|
22417
|
-
method: "GET"
|
|
22418
|
-
});
|
|
22419
|
-
if (getResult.ok) {
|
|
22420
|
-
const questions_list = getResult.data.questions;
|
|
22421
|
-
const endScreen = questions_list?.find((qq) => qq.type === "end_screen");
|
|
22422
|
-
if (endScreen) {
|
|
22423
|
-
await callApi(`/forms/${formId}/nodes/${endScreen.id}`, {
|
|
22424
|
-
method: "PATCH",
|
|
22425
|
-
body: { prompt: q.prompt, ...q.config ? { config: q.config } : {} }
|
|
22426
|
-
});
|
|
22427
|
-
continue;
|
|
22428
|
-
}
|
|
22429
|
-
}
|
|
22430
|
-
}
|
|
22423
|
+
for (const q of nodes) {
|
|
22431
22424
|
const addResult = await callApi(`/forms/${formId}/nodes`, {
|
|
22432
22425
|
method: "POST",
|
|
22433
|
-
body: {
|
|
22426
|
+
body: { node: q }
|
|
22434
22427
|
});
|
|
22435
22428
|
if (!addResult.ok) {
|
|
22436
|
-
return errorResult(`Failed to add
|
|
22429
|
+
return errorResult(`Failed to add node "${q.prompt}": ${addResult.error}`);
|
|
22437
22430
|
}
|
|
22438
22431
|
}
|
|
22439
22432
|
await callApi(`/forms/${formId}`, {
|
|
@@ -22450,7 +22443,7 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
22450
22443
|
`Form created successfully!`,
|
|
22451
22444
|
``,
|
|
22452
22445
|
`Title: ${title}`,
|
|
22453
|
-
`
|
|
22446
|
+
`Nodes: ${nodes.length}`,
|
|
22454
22447
|
`Form ID: ${formId}`,
|
|
22455
22448
|
``,
|
|
22456
22449
|
`FORM URL (share this with respondents): ${data.viewer_url}`
|
|
@@ -22464,7 +22457,7 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
22464
22457
|
`Pass form_id on follow-up tools (get_form, add_node, upload_node_media, etc.).`
|
|
22465
22458
|
);
|
|
22466
22459
|
if (planContext) {
|
|
22467
|
-
const limitNote = planContext.node_limit === null ? "unlimited
|
|
22460
|
+
const limitNote = planContext.node_limit === null ? "unlimited nodes" : `up to ${planContext.node_limit} nodes per form`;
|
|
22468
22461
|
if (planContext.auth_mode === "oauth") {
|
|
22469
22462
|
lines.push(
|
|
22470
22463
|
``,
|
|
@@ -22549,7 +22542,7 @@ function registerListFormsTool(server) {
|
|
|
22549
22542
|
|
|
22550
22543
|
// src/lib/format-form.ts
|
|
22551
22544
|
function formatFormState(data) {
|
|
22552
|
-
const
|
|
22545
|
+
const nodes = data.nodes;
|
|
22553
22546
|
const lines = [
|
|
22554
22547
|
`Form: ${data.title}`,
|
|
22555
22548
|
`Form ID: ${data.form_id}`,
|
|
@@ -22557,8 +22550,8 @@ function formatFormState(data) {
|
|
|
22557
22550
|
``,
|
|
22558
22551
|
`Nodes (in order):`
|
|
22559
22552
|
];
|
|
22560
|
-
for (let i = 0; i <
|
|
22561
|
-
const q =
|
|
22553
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
22554
|
+
const q = nodes[i];
|
|
22562
22555
|
lines.push(` ${i + 1}. [${q.type}] ${q.prompt || "(no prompt)"}`);
|
|
22563
22556
|
lines.push(` Node ID: ${q.id}`);
|
|
22564
22557
|
if (q.required) lines.push(` Required: yes`);
|
|
@@ -22585,7 +22578,7 @@ function registerGetFormTool(server) {
|
|
|
22585
22578
|
"clipform_get_form",
|
|
22586
22579
|
{
|
|
22587
22580
|
title: "Get Clipform",
|
|
22588
|
-
description: `Retrieve a form's details including all
|
|
22581
|
+
description: `Retrieve a form's details including all nodes in sequential order. Use this to see the current state of a form before making changes.`,
|
|
22589
22582
|
inputSchema: {
|
|
22590
22583
|
form_id: external_exports.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)")
|
|
22591
22584
|
},
|
|
@@ -22620,8 +22613,8 @@ function registerUpdateFormTool(server) {
|
|
|
22620
22613
|
show_step_counter: external_exports.boolean().optional().describe("Show step counter (e.g. '1/5'). Recommended for quizzes."),
|
|
22621
22614
|
disable_back_navigation: external_exports.boolean().optional().describe("Prevent respondents from going back. Recommended for quizzes."),
|
|
22622
22615
|
total_steps: external_exports.number().nullable().optional().describe("Override the total step count shown in the step counter. Set null to auto-calculate."),
|
|
22623
|
-
primary_color: external_exports.string().optional().describe("Primary/brand color
|
|
22624
|
-
background_color: external_exports.string().optional().describe("Background color
|
|
22616
|
+
primary_color: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Primary/brand color as 6-digit hex (e.g. '#FF5500'). Used for buttons and accents."),
|
|
22617
|
+
background_color: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Background color as 6-digit hex (e.g. '#1A1A2E')."),
|
|
22625
22618
|
font_family: external_exports.string().optional().describe("Font family name (e.g. 'Inter', 'Roboto', 'Playfair Display')."),
|
|
22626
22619
|
embed_autoplay: external_exports.boolean().optional().describe("Auto-play video when embedded (default: false). When off, embeds show a thumbnail + play button."),
|
|
22627
22620
|
description: external_exports.string().nullable().optional().describe("SEO description (meta description, og:description). Set null to clear."),
|
|
@@ -22716,7 +22709,7 @@ function registerDeleteFormTool(server) {
|
|
|
22716
22709
|
"clipform_delete_form",
|
|
22717
22710
|
{
|
|
22718
22711
|
title: "Delete Clipform",
|
|
22719
|
-
description: `Permanently delete an unclaimed form and all its
|
|
22712
|
+
description: `Permanently delete an unclaimed form and all its nodes. This cannot be undone. Only works on forms that haven't been claimed yet.`,
|
|
22720
22713
|
inputSchema: {
|
|
22721
22714
|
form_id: external_exports.string().uuid().describe("The form UUID to delete (returned by clipform_create_form, not the short share_id from the URL)")
|
|
22722
22715
|
},
|
|
@@ -22752,7 +22745,7 @@ ${NODE_TYPES_DESCRIPTION}
|
|
|
22752
22745
|
All type definitions and config schemas are derived from @vid-master/config (answer-types).`,
|
|
22753
22746
|
inputSchema: {
|
|
22754
22747
|
form_id: external_exports.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
22755
|
-
|
|
22748
|
+
node: NodeSchema.describe("The node to add"),
|
|
22756
22749
|
after_node_id: external_exports.string().optional().describe(
|
|
22757
22750
|
"Insert after this node ID. Omit to append before the end screen."
|
|
22758
22751
|
)
|
|
@@ -22764,8 +22757,8 @@ All type definitions and config schemas are derived from @vid-master/config (ans
|
|
|
22764
22757
|
openWorldHint: true
|
|
22765
22758
|
}
|
|
22766
22759
|
},
|
|
22767
|
-
async ({ form_id,
|
|
22768
|
-
const body = {
|
|
22760
|
+
async ({ form_id, node, after_node_id }) => {
|
|
22761
|
+
const body = { node };
|
|
22769
22762
|
if (after_node_id) body.after_node_id = after_node_id;
|
|
22770
22763
|
const result = await callApi(`/forms/${form_id}/nodes`, {
|
|
22771
22764
|
method: "POST",
|
|
@@ -22777,8 +22770,8 @@ All type definitions and config schemas are derived from @vid-master/config (ans
|
|
|
22777
22770
|
const confirmMsg = [
|
|
22778
22771
|
`Node added successfully!`,
|
|
22779
22772
|
`Node ID: ${result.data.node_id}`,
|
|
22780
|
-
`Type: ${
|
|
22781
|
-
`Prompt: ${
|
|
22773
|
+
`Type: ${node.type}`,
|
|
22774
|
+
`Prompt: ${node.prompt}`
|
|
22782
22775
|
].join("\n");
|
|
22783
22776
|
const formState = await fetchAndFormatFormState(form_id);
|
|
22784
22777
|
return textResult(formState ? `${confirmMsg}
|
|
@@ -22800,13 +22793,13 @@ function registerUpdateNodeTool(server) {
|
|
|
22800
22793
|
inputSchema: {
|
|
22801
22794
|
form_id: external_exports.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
22802
22795
|
node_id: external_exports.string().describe("The node ID to update"),
|
|
22803
|
-
prompt: external_exports.string().optional().describe("New
|
|
22804
|
-
label: external_exports.string().optional().describe("Short label for the
|
|
22805
|
-
type: external_exports.enum(ACTIVE_NODE_TYPES).optional().describe("Change the
|
|
22796
|
+
prompt: external_exports.string().optional().describe("New node prompt text"),
|
|
22797
|
+
label: external_exports.string().optional().describe("Short label for the node (used in logic builder)"),
|
|
22798
|
+
type: external_exports.enum(ACTIVE_NODE_TYPES).optional().describe("Change the node type"),
|
|
22806
22799
|
required: external_exports.boolean().optional().describe("Whether an answer is required"),
|
|
22807
22800
|
config: external_exports.record(external_exports.unknown()).optional().describe(CONFIG_DESCRIPTION),
|
|
22808
22801
|
options: external_exports.array(OptionSchema).optional().describe(
|
|
22809
|
-
"Replace all options (for choice
|
|
22802
|
+
"Replace all options (for choice nodes). Omit to keep existing options."
|
|
22810
22803
|
)
|
|
22811
22804
|
},
|
|
22812
22805
|
annotations: {
|
|
@@ -22917,7 +22910,7 @@ var MediaItemSchema = external_exports.object({
|
|
|
22917
22910
|
).optional().describe("Per-word timestamps within the segment")
|
|
22918
22911
|
})
|
|
22919
22912
|
).optional().describe("Word-level captions from clipform_generate_tts. Always include when uploading narrated video - pass the full objects including 'words' so per-word highlighting works."),
|
|
22920
|
-
show_captions: external_exports.boolean().optional().default(true).describe("Display captions/subtitles on the
|
|
22913
|
+
show_captions: external_exports.boolean().optional().default(true).describe("Display captions/subtitles on the node")
|
|
22921
22914
|
});
|
|
22922
22915
|
function registerUploadNodeMediaTool(server) {
|
|
22923
22916
|
server.registerTool(
|
|
@@ -23416,8 +23409,8 @@ var v4_default = v4;
|
|
|
23416
23409
|
var jobs = /* @__PURE__ */ new Map();
|
|
23417
23410
|
var MAX_AGE_MS = 30 * 60 * 1e3;
|
|
23418
23411
|
var RENDER_TIMING = {
|
|
23419
|
-
expectedRange: "15-
|
|
23420
|
-
pollDelay: "~
|
|
23412
|
+
expectedRange: "15-120 seconds",
|
|
23413
|
+
pollDelay: "~15 seconds"
|
|
23421
23414
|
};
|
|
23422
23415
|
function createJob(tool) {
|
|
23423
23416
|
const job = {
|
|
@@ -23503,7 +23496,7 @@ You are the director. Every stylistic choice below is yours - defaults exist for
|
|
|
23503
23496
|
1. Source images (use clipform_search_media with kind: "image"). Prefer portrait sources for 9:16 output; landscape works too via blur-pad fallback.
|
|
23504
23497
|
2. Produce narration audio (clipform_generate_tts).
|
|
23505
23498
|
3. Call this tool with images + audio_url + your creative direction.
|
|
23506
|
-
4. Attach the returned public URL to a
|
|
23499
|
+
4. Attach the returned public URL to a node via clipform_upload_media with media_type "video".
|
|
23507
23500
|
|
|
23508
23501
|
## Image framing (per-image)
|
|
23509
23502
|
|
|
@@ -24615,9 +24608,9 @@ Each question is a micro variable-reward event - the same dopamine loop that kee
|
|
|
24615
24608
|
|
|
24616
24609
|
For numeric questions (population, speed, weight), scale the real answer by random multipliers (0.3x to 3x) rounded to the same magnitude. Makes wrong answers plausible but clearly different.
|
|
24617
24610
|
|
|
24618
|
-
## Color Brain Questions (
|
|
24611
|
+
## Color Brain Questions (ColorCards composition)
|
|
24619
24612
|
|
|
24620
|
-
Inspired by the Color Brain board game - every answer is identified by its colours. Show flat colour chips, ask "what has these colours?". Use the \`
|
|
24613
|
+
Inspired by the Color Brain board game - every answer is identified by its colours. Show flat colour chips, ask "what has these colours?". Use the \`ColorCards\` composition for the question card.
|
|
24621
24614
|
|
|
24622
24615
|
**Colour palette constraint:** Swatches are solid flat chips. Only use clearly distinguishable basic colours: red, blue, green, yellow, white, black, orange, purple, pink, brown, grey. No navy vs blue, no teal vs cyan - they look the same as flat chips. The skill is picking subjects where a combo of basic colours is unique enough to identify.
|
|
24623
24616
|
|
|
@@ -25003,6 +24996,14 @@ function createServer() {
|
|
|
25003
24996
|
name: "clipform-mcp-server",
|
|
25004
24997
|
version: MCP_VERSION
|
|
25005
24998
|
});
|
|
24999
|
+
const _registerTool = server.registerTool.bind(server);
|
|
25000
|
+
server.registerTool = (name, config2, handler) => {
|
|
25001
|
+
return _registerTool(
|
|
25002
|
+
name,
|
|
25003
|
+
config2,
|
|
25004
|
+
(...args) => runWithMcpTool(name, () => handler(...args))
|
|
25005
|
+
);
|
|
25006
|
+
};
|
|
25006
25007
|
registerCreateFormTool(server);
|
|
25007
25008
|
registerListFormsTool(server);
|
|
25008
25009
|
registerGetFormTool(server);
|
|
@@ -25039,4 +25040,4 @@ export {
|
|
|
25039
25040
|
setApiKey,
|
|
25040
25041
|
createServer
|
|
25041
25042
|
};
|
|
25042
|
-
//# sourceMappingURL=chunk-
|
|
25043
|
+
//# sourceMappingURL=chunk-2SPXROLZ.js.map
|