@clipform/mcp-server 1.8.1 → 1.9.1

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-ESDD3WVD.js +24686 -0
  4. package/dist/chunk-ESDD3WVD.js.map +1 -0
  5. package/dist/chunk-YEDU3G7I.js +48 -0
  6. package/dist/chunk-YEDU3G7I.js.map +1 -0
  7. package/dist/index.js +108 -11
  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 +7 -8
  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,48 +0,0 @@
1
- import { z } from "zod";
2
- import { NodeSchema, NODE_TYPES_DESCRIPTION } from "../lib/schemas.js";
3
- import { callApi, errorResult, textResult } from "../lib/api-client.js";
4
- import { fetchAndFormatFormState } from "../lib/format-form.js";
5
- export function registerAddNodeTool(server) {
6
- server.registerTool("clipform_add_node", {
7
- title: "Add Node",
8
- description: `Add a new node to an existing form. By default, the node is inserted before the end screen (appended to the end of the flow). Use after_node_id to insert at a specific position.
9
-
10
- ${NODE_TYPES_DESCRIPTION}
11
-
12
- All type definitions and config schemas are derived from @vid-master/config (answer-types).`,
13
- inputSchema: {
14
- form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
15
- question: NodeSchema.describe("The node to add"),
16
- after_node_id: z
17
- .string()
18
- .optional()
19
- .describe("Insert after this node ID. Omit to append before the end screen."),
20
- },
21
- annotations: {
22
- readOnlyHint: false,
23
- destructiveHint: false,
24
- idempotentHint: false,
25
- openWorldHint: true,
26
- },
27
- }, async ({ form_id, question, after_node_id }) => {
28
- const body = { question };
29
- if (after_node_id)
30
- body.after_node_id = after_node_id;
31
- const result = await callApi(`/forms/${form_id}/nodes`, {
32
- method: "POST",
33
- body,
34
- });
35
- if (!result.ok) {
36
- return errorResult(result.error);
37
- }
38
- const confirmMsg = [
39
- `Node added successfully!`,
40
- `Node ID: ${result.data.node_id}`,
41
- `Type: ${question.type}`,
42
- `Prompt: ${question.prompt}`,
43
- ].join("\n");
44
- const formState = await fetchAndFormatFormState(form_id);
45
- return textResult(formState ? `${confirmMsg}\n\n---\n\n${formState}` : confirmMsg);
46
- });
47
- }
48
- //# sourceMappingURL=add-node.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-node.js","sourceRoot":"","sources":["../../src/tools/add-node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE;;EAEjB,sBAAsB;;4FAEoE;QACtF,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAChD,aAAa,EAAE,CAAC;iBACb,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,kEAAkE,CACnE;SACJ;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,EAAE;QAC7C,MAAM,IAAI,GAA4B,EAAE,QAAQ,EAAE,CAAC;QACnD,IAAI,aAAa;YAAE,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QAEtD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,OAAO,QAAQ,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,IAAI;SACL,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,UAAU,GAAG;YACjB,0BAA0B;YAC1B,YAAY,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;YACjC,SAAS,QAAQ,CAAC,IAAI,EAAE;YACxB,WAAW,QAAQ,CAAC,MAAM,EAAE;SAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,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 registerAttachNodeAudioTool(server: McpServer): void;
@@ -1,35 +0,0 @@
1
- import { z } from "zod";
2
- import { callApi, errorResult, textResult } from "../lib/api-client.js";
3
- export function registerAttachNodeAudioTool(server) {
4
- server.registerTool("clipform_attach_audio", {
5
- title: "Attach Audio to Node",
6
- description: `Attach a sound effect or audio file to a node with existing media (stills only). The audio auto-plays once when a respondent reaches this node. Provide a public URL to the audio file (WAV, MP3, or OGG). The node must already have media uploaded (use clipform_upload_node_media first).`,
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
10
- .string()
11
- .describe("The node ID (must already have media attached)"),
12
- url: z
13
- .string()
14
- .url()
15
- .describe("Public URL to the audio file (WAV, MP3, or OGG)"),
16
- },
17
- annotations: {
18
- readOnlyHint: false,
19
- destructiveHint: false,
20
- idempotentHint: true,
21
- openWorldHint: true,
22
- },
23
- }, async ({ form_id, node_id, url }) => {
24
- const result = await callApi(`/forms/${form_id}/nodes/${node_id}/audio`, {
25
- method: "PUT",
26
- body: { url },
27
- });
28
- if (!result.ok) {
29
- return errorResult(result.error);
30
- }
31
- return textResult(`Audio attached to node ${node_id}.\n` +
32
- `Audio path: ${result.data.audio_storage_path}`);
33
- });
34
- }
35
- //# sourceMappingURL=attach-node-audio.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"attach-node-audio.js","sourceRoot":"","sources":["../../src/tools/attach-node-audio.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,uBAAuB,EACvB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,8RAA8R;QAC3S,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,CAAC,gDAAgD,CAAC;YAC7D,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,CAAC,iDAAiD,CAAC;SAC/D;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,UAAU,OAAO,QAAQ,EAC1C;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,EAAE,GAAG,EAAE;SACd,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CACf,0BAA0B,OAAO,KAAK;YACpC,eAAe,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAClD,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerCheckRenderTool(server: McpServer): void;
@@ -1,47 +0,0 @@
1
- import { z } from "zod";
2
- import { errorResult, textResult } from "../lib/api-client.js";
3
- import { getJob, pruneJobs, RENDER_TIMING } from "../lib/render-jobs.js";
4
- export function registerCheckRenderTool(server) {
5
- server.registerTool("clipform_check_render", {
6
- title: "Check Render Status",
7
- description: `Check the status of a render job started by clipform_generate_video, clipform_generate_slideshow, or clipform_render_composition.
8
-
9
- Returns the current status and, when complete, the output URL. If still rendering, wait ${RENDER_TIMING.pollDelay} before checking again.`,
10
- inputSchema: {
11
- job_id: z.string().uuid().describe("The job ID returned by the render tool"),
12
- },
13
- annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
14
- }, async ({ job_id }) => {
15
- pruneJobs();
16
- const job = getJob(job_id);
17
- if (!job) {
18
- return errorResult(`No render job found with ID ${job_id}. Jobs expire after 30 minutes.`);
19
- }
20
- if (job.status === "rendering") {
21
- const elapsed = Math.round((Date.now() - job.createdAt) / 1000);
22
- return textResult([
23
- `Status: rendering (${elapsed}s elapsed)`,
24
- `Tool: ${job.tool}`,
25
- ``,
26
- `Still in progress. Check again in ${RENDER_TIMING.pollDelay}.`,
27
- ].join("\n"));
28
- }
29
- if (job.status === "failed") {
30
- return errorResult(`Render failed: ${job.error}`);
31
- }
32
- const data = job.result;
33
- return textResult([
34
- `Status: complete`,
35
- `Tool: ${job.tool}`,
36
- ``,
37
- ...(data.public_url ? [`Public URL: ${data.public_url}`] : []),
38
- ...(data.storage_path ? [`Storage path: ${data.storage_path}`] : []),
39
- ...(data.duration_seconds ? [`Duration: ${data.duration_seconds}s`] : []),
40
- ...(data.outputPath ? [`Output: ${data.outputPath}`] : []),
41
- ...(data.format ? [`Format: ${data.format}`] : []),
42
- ``,
43
- `Use clipform_upload_node_media with the public URL to attach this video to a node.`,
44
- ].join("\n"));
45
- });
46
- }
47
- //# sourceMappingURL=check-render.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"check-render.js","sourceRoot":"","sources":["../../src/tools/check-render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE;;0FAEuE,aAAa,CAAC,SAAS,yBAAyB;QACpI,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;SAC7E;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KACxG,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,SAAS,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAE3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,WAAW,CAAC,+BAA+B,MAAM,iCAAiC,CAAC,CAAC;QAC7F,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;YAChE,OAAO,UAAU,CACf;gBACE,sBAAsB,OAAO,YAAY;gBACzC,SAAS,GAAG,CAAC,IAAI,EAAE;gBACnB,EAAE;gBACF,qCAAqC,aAAa,CAAC,SAAS,GAAG;aAChE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC,kBAAkB,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,MAAa,CAAC;QAC/B,OAAO,UAAU,CACf;YACE,kBAAkB;YAClB,SAAS,GAAG,CAAC,IAAI,EAAE;YACnB,EAAE;YACF,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,EAAE;YACF,oFAAoF;SACrF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerCreateFormTool(server: McpServer): void;
@@ -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;