@clipform/mcp-server 1.8.1 → 1.9.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.
Files changed (118) hide show
  1. package/dist/auth-context.js +9 -0
  2. package/dist/auth-context.js.map +1 -0
  3. package/dist/chunk-BWCZX7XY.js +3824 -0
  4. package/dist/chunk-BWCZX7XY.js.map +1 -0
  5. package/dist/chunk-MYWOSQ66.js +15 -0
  6. package/dist/chunk-MYWOSQ66.js.map +1 -0
  7. package/dist/index.js +15 -10
  8. package/dist/index.js.map +1 -1
  9. package/dist/server.js +7 -74
  10. package/dist/server.js.map +1 -1
  11. package/package.json +5 -4
  12. package/dist/__tests__/api-parity.test.d.ts +0 -1
  13. package/dist/__tests__/api-parity.test.js +0 -157
  14. package/dist/__tests__/api-parity.test.js.map +0 -1
  15. package/dist/__tests__/config-sync.test.d.ts +0 -1
  16. package/dist/__tests__/config-sync.test.js +0 -16
  17. package/dist/__tests__/config-sync.test.js.map +0 -1
  18. package/dist/index.d.ts +0 -2
  19. package/dist/lib/api-client.d.ts +0 -35
  20. package/dist/lib/api-client.js +0 -126
  21. package/dist/lib/api-client.js.map +0 -1
  22. package/dist/lib/auth-context.d.ts +0 -17
  23. package/dist/lib/auth-context.js +0 -9
  24. package/dist/lib/auth-context.js.map +0 -1
  25. package/dist/lib/config.d.ts +0 -23
  26. package/dist/lib/config.js +0 -6
  27. package/dist/lib/config.js.map +0 -1
  28. package/dist/lib/format-form.d.ts +0 -2
  29. package/dist/lib/format-form.js +0 -32
  30. package/dist/lib/format-form.js.map +0 -1
  31. package/dist/lib/render-jobs.d.ts +0 -17
  32. package/dist/lib/render-jobs.js +0 -44
  33. package/dist/lib/render-jobs.js.map +0 -1
  34. package/dist/lib/schemas.d.ts +0 -64
  35. package/dist/lib/schemas.js +0 -140
  36. package/dist/lib/schemas.js.map +0 -1
  37. package/dist/lib/session-context.d.ts +0 -1
  38. package/dist/lib/session-context.js +0 -38
  39. package/dist/lib/session-context.js.map +0 -1
  40. package/dist/prompts.d.ts +0 -2
  41. package/dist/prompts.js +0 -272
  42. package/dist/prompts.js.map +0 -1
  43. package/dist/resources.d.ts +0 -2
  44. package/dist/resources.js +0 -336
  45. package/dist/resources.js.map +0 -1
  46. package/dist/server.d.ts +0 -2
  47. package/dist/tools/add-node.d.ts +0 -2
  48. package/dist/tools/add-node.js +0 -48
  49. package/dist/tools/add-node.js.map +0 -1
  50. package/dist/tools/attach-node-audio.d.ts +0 -2
  51. package/dist/tools/attach-node-audio.js +0 -35
  52. package/dist/tools/attach-node-audio.js.map +0 -1
  53. package/dist/tools/check-render.d.ts +0 -2
  54. package/dist/tools/check-render.js +0 -47
  55. package/dist/tools/check-render.js.map +0 -1
  56. package/dist/tools/create-form.d.ts +0 -2
  57. package/dist/tools/create-form.js +0 -199
  58. package/dist/tools/create-form.js.map +0 -1
  59. package/dist/tools/delete-form.d.ts +0 -2
  60. package/dist/tools/delete-form.js +0 -26
  61. package/dist/tools/delete-form.js.map +0 -1
  62. package/dist/tools/delete-node-media.d.ts +0 -2
  63. package/dist/tools/delete-node-media.js +0 -25
  64. package/dist/tools/delete-node-media.js.map +0 -1
  65. package/dist/tools/delete-node.d.ts +0 -2
  66. package/dist/tools/delete-node.js +0 -28
  67. package/dist/tools/delete-node.js.map +0 -1
  68. package/dist/tools/generate-slideshow.d.ts +0 -2
  69. package/dist/tools/generate-slideshow.js +0 -155
  70. package/dist/tools/generate-slideshow.js.map +0 -1
  71. package/dist/tools/generate-tts.d.ts +0 -2
  72. package/dist/tools/generate-tts.js +0 -73
  73. package/dist/tools/generate-tts.js.map +0 -1
  74. package/dist/tools/generate-video.d.ts +0 -2
  75. package/dist/tools/generate-video.js +0 -119
  76. package/dist/tools/generate-video.js.map +0 -1
  77. package/dist/tools/get-form.d.ts +0 -2
  78. package/dist/tools/get-form.js +0 -25
  79. package/dist/tools/get-form.js.map +0 -1
  80. package/dist/tools/get-node-media.d.ts +0 -2
  81. package/dist/tools/get-node-media.js +0 -35
  82. package/dist/tools/get-node-media.js.map +0 -1
  83. package/dist/tools/list-assets.d.ts +0 -2
  84. package/dist/tools/list-assets.js +0 -45
  85. package/dist/tools/list-assets.js.map +0 -1
  86. package/dist/tools/list-compositions.d.ts +0 -2
  87. package/dist/tools/list-compositions.js +0 -34
  88. package/dist/tools/list-compositions.js.map +0 -1
  89. package/dist/tools/list-forms.d.ts +0 -2
  90. package/dist/tools/list-forms.js +0 -86
  91. package/dist/tools/list-forms.js.map +0 -1
  92. package/dist/tools/log-generation.d.ts +0 -2
  93. package/dist/tools/log-generation.js +0 -33
  94. package/dist/tools/log-generation.js.map +0 -1
  95. package/dist/tools/render-composition.d.ts +0 -2
  96. package/dist/tools/render-composition.js +0 -50
  97. package/dist/tools/render-composition.js.map +0 -1
  98. package/dist/tools/search-media.d.ts +0 -2
  99. package/dist/tools/search-media.js +0 -40
  100. package/dist/tools/search-media.js.map +0 -1
  101. package/dist/tools/search-music.d.ts +0 -2
  102. package/dist/tools/search-music.js +0 -40
  103. package/dist/tools/search-music.js.map +0 -1
  104. package/dist/tools/search-news.d.ts +0 -2
  105. package/dist/tools/search-news.js +0 -47
  106. package/dist/tools/search-news.js.map +0 -1
  107. package/dist/tools/set-node-logic.d.ts +0 -2
  108. package/dist/tools/set-node-logic.js +0 -54
  109. package/dist/tools/set-node-logic.js.map +0 -1
  110. package/dist/tools/update-form.d.ts +0 -2
  111. package/dist/tools/update-form.js +0 -155
  112. package/dist/tools/update-form.js.map +0 -1
  113. package/dist/tools/update-node.d.ts +0 -2
  114. package/dist/tools/update-node.js +0 -70
  115. package/dist/tools/update-node.js.map +0 -1
  116. package/dist/tools/upload-node-media.d.ts +0 -2
  117. package/dist/tools/upload-node-media.js +0 -105
  118. package/dist/tools/upload-node-media.js.map +0 -1
@@ -1,199 +0,0 @@
1
- import { z } from "zod";
2
- import { BUSINESS } from "@vid-master/config";
3
- import { NodeSchema, NODE_TYPES_DESCRIPTION, } from "../lib/schemas.js";
4
- import { callApi, errorResult, textResult } from "../lib/api-client.js";
5
- export function registerCreateFormTool(server) {
6
- server.registerTool("clipform_create_form", {
7
- title: "Create Clipform",
8
- 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.
9
-
10
- ${NODE_TYPES_DESCRIPTION}
11
-
12
- 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.
13
-
14
- Example: A form that asks a question, collects contact info, then finishes:
15
- {
16
- title: "Quick Survey",
17
- questions: [
18
- { type: "open", prompt: "What's your biggest challenge?" },
19
- { type: "contact", prompt: "Leave your details", config: { fields: [{ id: "first_name", required: true }, { id: "email", required: true }] } },
20
- { type: "end_screen", prompt: "Thanks for your response!" }
21
- ]
22
- }`,
23
- inputSchema: {
24
- title: z.string().describe("Form title"),
25
- questions: z
26
- .array(NodeSchema)
27
- .min(1)
28
- .describe("Ordered list of questions/steps"),
29
- show_step_counter: z
30
- .boolean()
31
- .optional()
32
- .describe("Show step counter (e.g. '1/5'). Set true for quizzes."),
33
- disable_back_navigation: z
34
- .boolean()
35
- .optional()
36
- .describe("Prevent going back. Set true for quizzes."),
37
- primary_color: z
38
- .string()
39
- .optional()
40
- .describe("Primary/brand color (hex or CSS color). Used for buttons and accents."),
41
- background_color: z
42
- .string()
43
- .optional()
44
- .describe("Background color (hex, rgba, or CSS color)."),
45
- font_family: z
46
- .string()
47
- .optional()
48
- .describe("Font family name (e.g. 'Inter', 'Roboto', 'Playfair Display')."),
49
- embed_autoplay: z
50
- .boolean()
51
- .optional()
52
- .describe("Auto-play video when embedded (default: false). When off, embeds show a thumbnail + play button."),
53
- tags: z
54
- .array(z.string())
55
- .optional()
56
- .describe("Tags for indexing (e.g. ['quiz', 'trivia', 'arsenal']). Include format, genre, and topics."),
57
- },
58
- annotations: {
59
- readOnlyHint: false,
60
- destructiveHint: false,
61
- idempotentHint: false,
62
- openWorldHint: true,
63
- },
64
- }, async ({ title, questions, show_step_counter, disable_back_navigation, primary_color, background_color, font_family, embed_autoplay, tags }) => {
65
- // 0. Pre-flight: resolve the caller's plan and reject up-front if the
66
- // requested question count exceeds it. Without this we'd build a
67
- // scaffold + N-1 questions, then 403 on the Nth, leaving an orphan.
68
- // /v1/me is the single source for plan info; PLAN_LIMITS lives in
69
- // @vid-master/config and is read there. The MCP tool is intentionally
70
- // thin and never duplicates limit numbers.
71
- let planContext = null;
72
- const meResult = await callApi("/me", { method: "GET" });
73
- if (!meResult.ok) {
74
- return errorResult(`Unable to determine workspace: ${meResult.error}`);
75
- }
76
- const me = meResult.data;
77
- const workspaceId = me.workspace?.id ?? null;
78
- if (!workspaceId) {
79
- return errorResult("No workspace available. Connect your Clipform account in claude.ai → Settings → Connectors, or ensure MCP_WORKSPACE_ID is configured for anonymous mode.");
80
- }
81
- planContext = {
82
- auth_mode: me.auth_mode,
83
- workspace_id: workspaceId,
84
- workspace_name: me.workspace?.name ?? null,
85
- plan_name: me.plan?.name ?? "Free",
86
- node_limit: me.plan?.node_limit ?? null,
87
- };
88
- // questions includes any end_screen the user supplied; the scaffold
89
- // already has one so we count "real" content nodes only.
90
- const contentCount = questions.filter((q) => q.type !== "end_screen").length;
91
- if (planContext.node_limit !== null && contentCount > planContext.node_limit) {
92
- const upgradeUrl = `${BUSINESS.urls.dashboard}/billing`;
93
- const message = planContext.auth_mode === "oauth"
94
- ? `Your '${planContext.workspace_name}' workspace is on the ${planContext.plan_name} plan, capped at ${planContext.node_limit} questions per form. You asked for ${contentCount}. Either rerun with ${planContext.node_limit} questions or upgrade at ${upgradeUrl}.`
95
- : `Anonymous sessions are capped at ${planContext.node_limit} questions per form (${planContext.plan_name} plan). You asked for ${contentCount}. Either rerun with ${planContext.node_limit} questions, or connect your Clipform account in claude.ai → Settings → Connectors so forms land in your workspace with your real plan limits.`;
96
- return errorResult(message);
97
- }
98
- // 1. Create bare scaffold
99
- const createResult = await callApi("/forms", {
100
- method: "POST",
101
- body: { title, workspace_id: workspaceId },
102
- });
103
- if (!createResult.ok) {
104
- return errorResult(createResult.error);
105
- }
106
- const { data } = createResult;
107
- const formId = data.form_id;
108
- const claimUrl = data.claim_url ?? undefined;
109
- // 2. Apply form settings and theme if provided
110
- const settingsBody = {};
111
- if (show_step_counter !== undefined)
112
- settingsBody.show_step_counter = show_step_counter;
113
- if (disable_back_navigation !== undefined)
114
- settingsBody.disable_back_navigation = disable_back_navigation;
115
- if (primary_color !== undefined)
116
- settingsBody.primary_color = primary_color;
117
- if (background_color !== undefined)
118
- settingsBody.background_color = background_color;
119
- if (font_family !== undefined)
120
- settingsBody.font_family = font_family;
121
- if (embed_autoplay !== undefined)
122
- settingsBody.embed_autoplay = embed_autoplay;
123
- if (Object.keys(settingsBody).length > 0) {
124
- await callApi(`/forms/${formId}`, {
125
- method: "PATCH",
126
- body: settingsBody,
127
- });
128
- }
129
- // 3. Add each question via the add-question endpoint
130
- for (const q of questions) {
131
- // If it's an end_screen, update the default one instead of adding another
132
- if (q.type === "end_screen") {
133
- // The scaffold already has an end_screen — find it and update its prompt
134
- const getResult = await callApi(`/forms/${formId}`, {
135
- method: "GET",
136
- });
137
- if (getResult.ok) {
138
- const questions_list = getResult.data.questions;
139
- const endScreen = questions_list?.find((qq) => qq.type === "end_screen");
140
- if (endScreen) {
141
- await callApi(`/forms/${formId}/nodes/${endScreen.id}`, {
142
- method: "PATCH",
143
- body: { prompt: q.prompt, ...(q.config ? { config: q.config } : {}) },
144
- });
145
- continue;
146
- }
147
- }
148
- // Fallback: add it normally if we couldn't find the default
149
- }
150
- const addResult = await callApi(`/forms/${formId}/nodes`, {
151
- method: "POST",
152
- body: { question: q },
153
- });
154
- if (!addResult.ok) {
155
- return errorResult(`Failed to add question "${q.prompt}": ${addResult.error}`);
156
- }
157
- }
158
- // 4. Publish the form
159
- await callApi(`/forms/${formId}`, {
160
- method: "PATCH",
161
- body: { is_published: true },
162
- });
163
- // 5. Tag the form (best-effort)
164
- if (tags && tags.length > 0) {
165
- await callApi(`/forms/${formId}/tags`, {
166
- method: "PUT",
167
- body: { tags },
168
- });
169
- }
170
- const lines = [
171
- `Form created successfully!`,
172
- ``,
173
- `Title: ${title}`,
174
- `Questions: ${questions.length}`,
175
- `Form ID: ${formId}`,
176
- ``,
177
- `FORM URL (share this with respondents): ${data.viewer_url}`,
178
- ];
179
- if (claimUrl) {
180
- lines.push(`CLAIM URL (transfer ownership to your account): ${claimUrl}`);
181
- }
182
- lines.push(``, `IMPORTANT: Always show the user the exact URLs above — do not rewrite or modify them.`, `Pass form_id on follow-up tools (get_form, add_node, upload_node_media, etc.).`);
183
- // One-line plan/auth summary so the model can mention it ONCE and not
184
- // re-prompt on every follow-up call.
185
- if (planContext) {
186
- const limitNote = planContext.node_limit === null
187
- ? "unlimited questions"
188
- : `up to ${planContext.node_limit} questions per form`;
189
- if (planContext.auth_mode === "oauth") {
190
- lines.push(``, `Plan: ${planContext.plan_name} (${limitNote}) in workspace '${planContext.workspace_name}'.`);
191
- }
192
- else {
193
- lines.push(``, `Plan: anonymous ${planContext.plan_name} (${limitNote}). Mention this once: the user can connect their Clipform account in claude.ai → Settings → Connectors → ${BUSINESS.urls.mcp} so future forms land directly in their workspace - do not repeat on follow-up calls.`);
194
- }
195
- }
196
- return textResult(lines.join("\n"));
197
- });
198
- }
199
- //# sourceMappingURL=create-form.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-form.js","sourceRoot":"","sources":["../../src/tools/create-form.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerDeleteFormTool(server: McpServer): void;
@@ -1,26 +0,0 @@
1
- import { z } from "zod";
2
- import { callApi, errorResult, textResult } from "../lib/api-client.js";
3
- export function registerDeleteFormTool(server) {
4
- server.registerTool("clipform_delete_form", {
5
- title: "Delete Clipform",
6
- description: `Permanently delete an unclaimed form and all its questions. This cannot be undone. Only works on forms that haven't been claimed yet.`,
7
- inputSchema: {
8
- form_id: z.string().uuid().describe("The form UUID to delete (returned by clipform_create_form, not the short share_id from the URL)"),
9
- },
10
- annotations: {
11
- readOnlyHint: false,
12
- destructiveHint: true,
13
- idempotentHint: false,
14
- openWorldHint: true,
15
- },
16
- }, async ({ form_id }) => {
17
- const result = await callApi(`/forms/${form_id}`, {
18
- method: "DELETE",
19
- });
20
- if (!result.ok) {
21
- return errorResult(result.error);
22
- }
23
- return textResult(`Form ${form_id} has been permanently deleted.`);
24
- });
25
- }
26
- //# sourceMappingURL=delete-form.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"delete-form.js","sourceRoot":"","sources":["../../src/tools/delete-form.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,uIAAuI;QACpJ,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,iGAAiG,CAAC;SACvI;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,OAAO,EAAE,EAAE;YAChD,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CAAC,QAAQ,OAAO,gCAAgC,CAAC,CAAC;IACrE,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerDeleteNodeMediaTool(server: McpServer): void;
@@ -1,25 +0,0 @@
1
- import { z } from "zod";
2
- import { callApi, errorResult, textResult } from "../lib/api-client.js";
3
- export function registerDeleteNodeMediaTool(server) {
4
- server.registerTool("clipform_delete_node_media", {
5
- title: "Delete Node Media",
6
- description: `Remove media from a node. Deletes the media record and cleans up external resources (Mux video asset, storage file).`,
7
- inputSchema: {
8
- form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
9
- node_id: z.string().describe("The node ID"),
10
- },
11
- annotations: {
12
- readOnlyHint: false,
13
- destructiveHint: true,
14
- idempotentHint: false,
15
- openWorldHint: true,
16
- },
17
- }, async ({ form_id, node_id }) => {
18
- const result = await callApi(`/forms/${form_id}/nodes/${node_id}/media`, { method: "DELETE" });
19
- if (!result.ok) {
20
- return errorResult(result.error);
21
- }
22
- return textResult("Media removed from node.");
23
- });
24
- }
25
- //# sourceMappingURL=delete-node-media.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"delete-node-media.js","sourceRoot":"","sources":["../../src/tools/delete-node-media.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,4BAA4B,EAC5B;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,sHAAsH;QACnI,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;SAC5C;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,UAAU,OAAO,QAAQ,EAC1C,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CAAC,0BAA0B,CAAC,CAAC;IAChD,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerDeleteNodeTool(server: McpServer): void;
@@ -1,28 +0,0 @@
1
- import { z } from "zod";
2
- import { callApi, errorResult, textResult } from "../lib/api-client.js";
3
- import { fetchAndFormatFormState } from "../lib/format-form.js";
4
- export function registerDeleteNodeTool(server) {
5
- server.registerTool("clipform_delete_node", {
6
- title: "Delete Node",
7
- description: `Delete a node from a form. The logic chain is automatically re-linked (the previous node will point to the next one). Cannot delete the start node or the last end screen.`,
8
- inputSchema: {
9
- form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
10
- node_id: z.string().describe("The node ID to delete"),
11
- },
12
- annotations: {
13
- readOnlyHint: false,
14
- destructiveHint: true,
15
- idempotentHint: false,
16
- openWorldHint: true,
17
- },
18
- }, async ({ form_id, node_id }) => {
19
- const result = await callApi(`/forms/${form_id}/nodes/${node_id}`, { method: "DELETE" });
20
- if (!result.ok) {
21
- return errorResult(result.error);
22
- }
23
- const confirmMsg = `Node ${node_id} deleted. The logic chain has been re-linked.`;
24
- const formState = await fetchAndFormatFormState(form_id);
25
- return textResult(formState ? `${confirmMsg}\n\n---\n\n${formState}` : confirmMsg);
26
- });
27
- }
28
- //# sourceMappingURL=delete-node.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"delete-node.js","sourceRoot":"","sources":["../../src/tools/delete-node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,4KAA4K;QACzL,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;SACtD;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,UAAU,OAAO,EAAE,EACpC,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,OAAO,+CAA+C,CAAC;QAClF,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACrF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerGenerateSlideshowTool(server: McpServer): void;
@@ -1,155 +0,0 @@
1
- import { z } from "zod";
2
- import { callInternalApi, textResult } from "../lib/api-client.js";
3
- import { createJob, completeJob, failJob, RENDER_TIMING } from "../lib/render-jobs.js";
4
- // Style knobs - mirror packages/remotion/src/compositions/slideshow/KenBurnsImage.tsx.
5
- // Every field optional; unset fields fall back to library defaults (which shift
6
- // automatically between 'cover' and 'blur-pad' fit modes).
7
- const slideshowStyleSchema = z.object({
8
- preset: z.enum(["cinematic", "dramatic", "calm", "documentary", "dreamy", "moody"]).optional().describe("Named shortcut applied before per-field overrides. cinematic = defaults; dramatic = big zoom, wider pan, ease-out, stronger vignette; calm = minimal motion, linear, no vignette; documentary = near-static, no pan; dreamy = bright heavy blur-pad, soft vignette, gentle zoom; moody = desaturated low-key blur-pad, strong vignette. Set any other field to override individual knobs on top of the preset."),
9
- zoom: z.object({
10
- from: z.number().optional().describe("Starting scale for zoom-in / ending scale for zoom-out. Default 1.0."),
11
- to: z.number().optional().describe("Ending scale for zoom-in / starting scale for zoom-out. Default 1.3 (cover) / 1.15 (blur-pad)."),
12
- }).optional().describe("Zoom range. Lower 'to' (e.g. 1.05) for near-static cinematography; higher (e.g. 1.4) for dramatic push-in."),
13
- pan: z.object({
14
- range: z.number().optional().describe("Pan drift as fraction of viewport on each side. Default 0.05 (cover) / 0.03 (blur-pad). 0.08+ feels like sweeping."),
15
- scale: z.number().optional().describe("Baseline scale during pan effects. Must exceed 1 + 2×range so edges never show. Default 1.12 / 1.08."),
16
- }).optional(),
17
- zoomPan: z.object({
18
- from: z.number().optional(),
19
- to: z.number().optional(),
20
- rangeFraction: z.number().optional().describe("Multiplier on pan.range for zoom-in-pan-* effects. Default 0.5."),
21
- }).optional(),
22
- easing: z.enum(["ease-in-out", "ease-in", "ease-out", "linear"]).optional().describe("Motion curve. 'ease-in-out' = cinematic default. 'linear' = mechanical/deliberate. 'ease-out' = fast-start slow-finish, good for reveals."),
23
- blurPad: z.object({
24
- blurPx: z.number().optional().describe("Blur strength on the background layer. Default 40. 60+ for heavy dreamy effect, 20 for just-barely."),
25
- brightness: z.number().optional().describe("Background brightness multiplier. Default 0.55 (dimmed). Raise to 0.8+ for a brighter bed; lower for moodier."),
26
- saturate: z.number().optional().describe("Background saturation. Default 1.15. Lower (0.6) for desaturated/muted bg; higher for vivid."),
27
- overscale: z.number().optional().describe("Background overscale to hide blur edges. Default 1.12."),
28
- foregroundScale: z.number().optional().describe("Gentle crop on the contain-fit sharp layer. Default 1.0 (pure contain). 1.2 reduces letterbox by accepting mild crop."),
29
- }).optional().describe("Styling for the blurred-letterbox layer. Only applies when fit resolves to 'blur-pad' (landscape source in portrait viewport)."),
30
- vignette: z.union([
31
- z.literal(false),
32
- z.object({
33
- opacity: z.number().optional().describe("Edge darkness opacity, 0-1. Default 0.35 (cover) / 0.4 (blur-pad)."),
34
- innerRadiusPercent: z.number().optional().describe("Where darkening starts, 0 = center, 100 = edge. Default 50-55."),
35
- }),
36
- ]).optional().describe("Edge darkening for cinematic framing. Pass false to disable."),
37
- backgroundColor: z.string().optional().describe("Hex color behind the image frame. Default '#000'."),
38
- autoBlurPadThreshold: z.number().optional().describe("When fit='auto', trigger blur-pad if aspectRatio > this value. Default 1.1."),
39
- }).describe("Creative style overrides. Every field optional - unset inherits defaults.");
40
- export function registerGenerateSlideshowTool(server) {
41
- server.registerTool("clipform_generate_slideshow", {
42
- title: "Generate Slideshow",
43
- description: `**Deprecated: prefer clipform_generate_video** which supports both images and video clips.
44
-
45
- Generate a slideshow video from images and audio. Creates a 9:16 (720x1280) video with smooth pan/zoom effects (Ken Burns style), eased motion, and crossfade transitions, synced to the audio duration. Uploaded to storage; returns a public URL.
46
-
47
- You are the director. Every stylistic choice below is yours - defaults exist for convenience but override anything that fits your creative vision.
48
-
49
- ## Workflow
50
-
51
- 1. Source images (use clipform_search_media with kind: "image"). Prefer portrait sources for 9:16 output; landscape works too via blur-pad fallback.
52
- 2. Produce narration audio (clipform_generate_tts).
53
- 3. Call this tool with images + audio_url + your creative direction.
54
- 4. Attach the returned public URL to a question via clipform_upload_media with media_type "video".
55
-
56
- ## Image framing (per-image)
57
-
58
- - **aspect_ratio** (width/height): pass through from the image source so the composition can auto-pick framing. Landscape images with no aspect_ratio will cover-crop and may pixelate.
59
- - **fit**: 'cover' (fill frame, crop), 'blur-pad' (sharp contained foreground + blurred cover background for landscape sources), 'auto' (default: cover for portrait, blur-pad for landscape > 1.1:1).
60
- - **style**: per-image creative overrides (see Style Knobs below).
61
-
62
- ## Effects
63
-
64
- zoom-in, zoom-out, pan-left, pan-right, pan-up, pan-down, zoom-in-pan-left, zoom-in-pan-right, random, static. Set 'random' or pass random_effects: true to shuffle per image.
65
-
66
- ## Transitions
67
-
68
- fade (default), slide, wipe. Legacy names (fadeblack, slideleft, etc.) also work. duration is in seconds.
69
-
70
- ## Style presets (fastest path)
71
-
72
- Pick one as a starting point via \`style.preset\` (per-image) or \`default_style.preset\` (global). Override individual knobs on top.
73
-
74
- - **cinematic** - the default feel. Smooth ease-in-out, zoom 1.0→1.3, subtle pan, subtle vignette.
75
- - **dramatic** - zoom 1.0→1.4, ease-out, wider pan (0.07), strong vignette. Good for big-reveal content, competitions, climactic moments.
76
- - **calm** - zoom 1.0→1.08, linear easing, no vignette. Reflective topics, wellness, educational explainers.
77
- - **documentary** - near-static (zoom 1.0→1.05, tiny pan, no vignette). Talking-heads-style context shots, historical photos.
78
- - **dreamy** - heavy blur-pad (blurPx 60, brightness 0.75), soft vignette. Aspirational, romantic, nostalgic.
79
- - **moody** - desaturated blur-pad (brightness 0.35, saturate 0.7), strong vignette, dark wrapper color. Crime, mystery, somber topics.
80
-
81
- Per-image preset wins over default_style preset. Per-field overrides (zoom, pan, etc.) merge on top of whichever preset is active.
82
-
83
- ## Style Knobs (per-image via images[i].style, or global via default_style)
84
-
85
- - **zoom**: { from, to } - push-in/pull-out range. Cinematic default 1.0→1.3. Drop to 1.0→1.05 for near-static; push to 1.0→1.4 for dramatic.
86
- - **pan**: { range, scale } - drift magnitude. 0.03 subtle, 0.05 default, 0.08+ sweeping.
87
- - **easing**: 'ease-in-out' (default, cinematic) | 'ease-in' (accelerate) | 'ease-out' (decelerate, good for reveals) | 'linear' (mechanical).
88
- - **blurPad**: { blurPx, brightness, saturate, overscale, foregroundScale } - only applies when blur-pad fit is active. Heavier blurPx (60) + lower brightness (0.35) for moody; foregroundScale: 1.2 to reduce letterbox at the cost of mild crop.
89
- - **vignette**: false to disable, or { opacity, innerRadiusPercent }. Stronger vignette (opacity 0.6) for dramatic focus; disable for bright, flat looks.
90
- - **backgroundColor**: hex color shown behind the image frame (default '#000').
91
- - **autoBlurPadThreshold**: when fit='auto', images wider than this ratio get blur-pad. Default 1.1.
92
-
93
- ## Global options
94
-
95
- - **default_style**: style applied to every image unless the image overrides per-field. Per-image style merges over default_style at the field level.
96
- - **background_color**: viewport wrapper color, visible during cross-fades.
97
- - **random_effects**: shuffles effects across images when true.
98
-
99
- ## Creative guidance
100
-
101
- - For the same 5-image quiz slideshow, vary the effects (one zoom-in on the opener, pan-left on a cityscape, zoom-out on the closer) rather than random_effects: true, unless you want the dice-roll.
102
- - Quiet/reflective topics: slow easing ('linear'), tight zoom (1.0→1.08), no vignette.
103
- - Energetic topics: punchy zoom (1.0→1.35), ease-out, wider pan.
104
- - Mixed orientation sets: rely on fit: 'auto' + pass aspect_ratio per image. The composition will cover-crop portraits and blur-pad landscapes without more work.`,
105
- inputSchema: {
106
- images: z.array(z.object({
107
- url: z.string().url().describe("Image URL"),
108
- effect: z.string().optional().describe("Ken Burns effect name (see description). Pass 'random' to shuffle this image only."),
109
- aspect_ratio: z.number().positive().optional().describe("Source image width / height. Enables auto blur-pad for landscape images in the 9:16 viewport."),
110
- fit: z.enum(["cover", "blur-pad", "auto"]).optional().describe("Framing mode. 'auto' (default) picks cover for portrait, blur-pad for landscape."),
111
- style: slideshowStyleSchema.optional(),
112
- })).min(1).max(20).describe("Images for the slideshow (1-20)"),
113
- audio_url: z.string().url().describe("URL of the audio track (mp3/wav). Slideshow duration matches audio duration."),
114
- random_effects: z.boolean().optional().default(true).describe("Shuffle effects across all images (default: true). Set false when specifying effects explicitly per-image."),
115
- transition: z.object({
116
- type: z.string().optional().default("fade").describe("Transition type: fade (default), slide, wipe."),
117
- duration: z.number().optional().default(1).describe("Transition duration in seconds (default: 1)."),
118
- }).optional().describe("Transition between images."),
119
- default_style: slideshowStyleSchema.optional().describe("Style applied to every image unless overridden per-image."),
120
- background_color: z.string().optional().describe("Viewport background color behind all images (default '#000')."),
121
- },
122
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
123
- }, async ({ images, audio_url, random_effects, transition, default_style, background_color }) => {
124
- const workspace_id = process.env.MCP_WORKSPACE_ID;
125
- const job = createJob("clipform_generate_slideshow");
126
- callInternalApi("/internal/slideshow", {
127
- body: {
128
- images,
129
- audio_url,
130
- random_effects: random_effects ?? true,
131
- transition: transition ?? { type: "fade", duration: 1 },
132
- default_style,
133
- background_color,
134
- workspace_id,
135
- },
136
- }).then((result) => {
137
- if (!result.ok) {
138
- failJob(job.id, result.error);
139
- }
140
- else {
141
- completeJob(job.id, result.data);
142
- }
143
- }).catch((err) => {
144
- failJob(job.id, err instanceof Error ? err.message : String(err));
145
- });
146
- return textResult([
147
- `Slideshow render started (${images.length} image${images.length > 1 ? "s" : ""}).`,
148
- ``,
149
- `Job ID: ${job.id}`,
150
- ``,
151
- `Renders typically take ${RENDER_TIMING.expectedRange}. Use clipform_check_render with this job ID to check status.`,
152
- ].join("\n"));
153
- });
154
- }
155
- //# sourceMappingURL=generate-slideshow.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-slideshow.js","sourceRoot":"","sources":["../../src/tools/generate-slideshow.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerGenerateTtsTool(server: McpServer): void;
@@ -1,73 +0,0 @@
1
- import { z } from "zod";
2
- import { callInternalApi, errorResult, textResult } from "../lib/api-client.js";
3
- const TtsItemSchema = z.object({
4
- text: z.string().min(1).max(5000).describe("Narration text"),
5
- voice: z
6
- .enum(["ryan", "sonia", "andrew", "ava", "guy"])
7
- .optional()
8
- .default("ryan")
9
- .describe("TTS voice (default: ryan)"),
10
- });
11
- export function registerGenerateTtsTool(server) {
12
- server.registerTool("clipform_generate_tts", {
13
- title: "Generate Text-to-Speech",
14
- description: `Generate narration audio from text using Edge TTS (free) with ElevenLabs fallback. Pass one item or many (max 10) - multiple items run in parallel.
15
-
16
- Workflow:
17
- 1. Generate TTS audio with this tool
18
- 2. Search for images with clipform_search_media (kind: "image")
19
- 3. Create a slideshow with clipform_generate_slideshow (pass the audio URL + image URLs)
20
- 4. Attach the video to a node with clipform_upload_node_media
21
-
22
- Available voices: ryan (British male, default), sonia (British female), andrew (American male), ava (American female), guy (American male casual).
23
-
24
- Returns audio URL and word-level captions per item.`,
25
- inputSchema: {
26
- items: z
27
- .array(TtsItemSchema)
28
- .min(1)
29
- .max(10)
30
- .describe("One or more TTS items to generate"),
31
- },
32
- annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
33
- }, async ({ items }) => {
34
- const workspace_id = process.env.MCP_WORKSPACE_ID;
35
- const results = await Promise.allSettled(items.map((item) => callInternalApi("/internal/tts", {
36
- body: { text: item.text, voice: item.voice, workspace_id },
37
- })));
38
- const lines = [];
39
- let successCount = 0;
40
- for (let i = 0; i < results.length; i++) {
41
- const r = results[i];
42
- if (items.length > 1)
43
- lines.push(`--- Item ${i + 1} ---`);
44
- if (r.status === "fulfilled" && r.value.ok) {
45
- successCount++;
46
- const data = r.value.data;
47
- lines.push(`Voice: ${data.voice}`);
48
- lines.push(`Audio URL: ${data.audioUrl}`);
49
- lines.push(`Storage path: ${data.storagePath}`);
50
- lines.push(`Captions: ${JSON.stringify(data.captions)}`);
51
- }
52
- else {
53
- const error = r.status === "rejected"
54
- ? r.reason?.message || String(r.reason)
55
- : r.value.error;
56
- const status = r.status === "fulfilled" ? r.value.status : 0;
57
- const hint = status === 500 || status === 0
58
- ? " (transient - retrying may help)"
59
- : "";
60
- lines.push(`FAILED: ${error}${hint}`);
61
- }
62
- lines.push("");
63
- }
64
- if (items.length > 1) {
65
- lines.unshift(`TTS: ${successCount}/${items.length} succeeded\n`);
66
- }
67
- lines.push(`IMPORTANT: When uploading the final video with clipform_upload_node_media, pass the COMPLETE Captions JSON above as the "captions" parameter — including the "words" arrays inside each segment. Do NOT strip or simplify the JSON. The viewer needs word-level timing data to display captions.`);
68
- if (successCount === 0)
69
- return errorResult(lines.join("\n"));
70
- return textResult(lines.join("\n"));
71
- });
72
- }
73
- //# sourceMappingURL=generate-tts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-tts.js","sourceRoot":"","sources":["../../src/tools/generate-tts.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerGenerateVideoTool(server: McpServer): void;