@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
package/dist/prompts.js DELETED
@@ -1,272 +0,0 @@
1
- import { getSessionContext } from "./lib/session-context.js";
2
- export function registerPrompts(server) {
3
- server.registerPrompt("create-quiz", {
4
- title: "Create a Quiz",
5
- description: "Build a scored knowledge quiz with narrated video questions",
6
- }, async () => {
7
- const sessionContext = await getSessionContext();
8
- return {
9
- messages: [
10
- {
11
- role: "user",
12
- content: {
13
- type: "text",
14
- text: "I want to create a quiz. What's the best approach?",
15
- },
16
- },
17
- {
18
- role: "assistant",
19
- content: {
20
- type: "text",
21
- text: `${sessionContext ? sessionContext + "\n\n" : ""}Here's how to build a great quiz with Clipform. Read the quiz writing guide (clipform://guides/quiz) for detailed craft knowledge on question design, difficulty curves, and narration style.
22
-
23
- ## Workflow
24
-
25
- 1. **Research** the topic - find surprising facts, common misconceptions, myth-busters
26
- 2. **Write questions** - follow the difficulty curve (easy start, hard middle, satisfying end). Target 5-8 questions.
27
- 3. **Create the form** with clipform_create_form:
28
- - show_step_counter: true
29
- - disable_back_navigation: true
30
- 4. **Add questions** with clipform_add_node (type: "choice"):
31
- - config: { choice: { show_answer_feedback: true } }
32
- - randomise_options: true in config
33
- - score: 1 on correct option, score: 0 on wrong
34
- - 3-4 wrong answers per question
35
- 5. **Generate narration** with clipform_generate_tts for each question. Tease the question - do NOT reveal the answer or read options aloud. Keep each narration 5-15 seconds.
36
- 6. **Build video** for each question:
37
- - clipform_search_media (kind: "image") - 3 images per question
38
- - clipform_generate_video - creates Ken Burns video synced to audio
39
- 7. **Attach media** with clipform_upload_node_media. Include captions, set show_captions: true.
40
- 8. **Update end screen** with clipform_update_node - EVERY quiz must have:
41
- - show_score: true, icon: "trophy"
42
- - show_share_button: true (drives virality)
43
- - cta_type: "restart", cta_text: a short challenge like "Beat your score?" or "Try again?"
44
- - score_ranges with personalised title + message per tier. Write these in the quiz's voice - short, punchy, and specific to the topic (not generic "Good job!"). Example for a geography quiz:
45
- \`\`\`json
46
- { "min": 0, "max": 2, "title": "Lost Tourist", "message": "You might need a map - and a compass." },
47
- { "min": 3, "max": 5, "title": "Frequent Flyer", "message": "Not bad! You know your way around." },
48
- { "min": 6, "max": 8, "title": "World Explorer", "message": "Impressive - you really know your stuff." }
49
- \`\`\`
50
- 9. **Publish** with clipform_update_form
51
- 10. **Tag the form** - pass tags: one format (quiz/survey/interview/feedback/lead-gen), one genre (trivia/personality/nps/poll/testimonial), and 2-3 topic words
52
- 11. **Log** with clipform_log_generation (sources, images, attributions)
53
-
54
- ## Before building, ask
55
-
56
- 1. How many questions?
57
- 2. Media style: text only, still images, or slideshow video with narration?
58
- 3. Any topic or style preferences?`,
59
- },
60
- },
61
- ],
62
- };
63
- });
64
- server.registerPrompt("create-personality-quiz", {
65
- title: "Create a Personality Quiz",
66
- description: "Build a 'Which X are you?' personality quiz with category-based scoring and outcome screens",
67
- }, async () => {
68
- const sessionContext = await getSessionContext();
69
- return {
70
- messages: [
71
- {
72
- role: "user",
73
- content: {
74
- type: "text",
75
- text: "I want to create a personality quiz. What's the best approach?",
76
- },
77
- },
78
- {
79
- role: "assistant",
80
- content: {
81
- type: "text",
82
- text: `${sessionContext ? sessionContext + "\n\n" : ""}Here's how to build a personality quiz with Clipform. Read the personality quiz guide (clipform://guides/personality-quiz) for craft knowledge on category design, option weighting, and outcome writing.
83
-
84
- ## How it differs from a knowledge quiz
85
-
86
- There are NO correct answers. Each option maps to one or more outcome categories via \`scores\` (not \`score\`). The winning category at the end determines which result screen the respondent sees.
87
-
88
- ## Workflow
89
-
90
- 1. **Define 3-5 outcome categories** - these are the "personalities" (e.g. "Creative", "Analytical", "Leader", "Collaborator"). More than 5 gets muddy.
91
- 2. **Write questions** - each question should feel revealing but fun. Target 5-8 questions.
92
- 3. **Create the form** with clipform_create_form:
93
- - show_step_counter: true
94
- - disable_back_navigation: true
95
- 4. **Add questions** with clipform_add_node (type: "choice"):
96
- - config: { choice: { show_answer_feedback: false } } (no right/wrong!)
97
- - Do NOT set randomise_options (option order matters for personality quizzes - lead with the most appealing)
98
- - Each option gets \`scores: { "CategoryA": 2, "CategoryB": 1 }\` - weight towards relevant categories
99
- - Every option should score in at least one category (no dead options)
100
- 5. **Generate narration** with clipform_generate_tts - conversational, reflective tone. "What does this say about you?" not "Do you know the answer?"
101
- 6. **Build video** + **attach media** (same as knowledge quiz workflow)
102
- 7. **Update end screen** with clipform_update_node - EVERY personality quiz must have:
103
- - show_score: false, icon: "star"
104
- - show_share_button: true (personality results are inherently shareable - "I got X, what did you get?")
105
- - cta_type: "restart", cta_text: "Find out again?" or "Take it again?"
106
- - scoring_results (NOT score_ranges) with a result per category. Write the title as an identity reveal ("You're a Creative!") and the message as a short, flattering description that makes people want to share it. Be specific to the quiz theme, not generic. Example:
107
- \`\`\`json
108
- {
109
- "show_score": false,
110
- "icon": "star",
111
- "show_share_button": true,
112
- "cta_type": "restart",
113
- "cta_text": "Retake quiz",
114
- "scoring_results": [
115
- { "category": "Creative", "title": "You're a Creative!", "message": "You see the world through colour and possibility. Where others see problems, you see raw material." },
116
- { "category": "Analytical", "title": "You're an Analyst!", "message": "You don't guess - you figure it out. Your superpower is turning chaos into clarity." }
117
- ]
118
- }
119
- \`\`\`
120
- 8. **Publish** with clipform_update_form
121
- 9. **Tag the form** - pass tags: one format (quiz/survey/interview/feedback/lead-gen), one genre (trivia/personality/nps/poll/testimonial), and 2-3 topic words
122
- 10. **Log** with clipform_log_generation
123
-
124
- ## Before building, ask
125
-
126
- 1. What are the possible outcomes/personalities? (3-5 categories)
127
- 2. What's the theme? ("Which city are you?", "What's your work style?", "Which character are you?")
128
- 3. Media style: text only, still images, or slideshow video with narration?`,
129
- },
130
- },
131
- ],
132
- };
133
- });
134
- server.registerPrompt("create-interview", {
135
- title: "Create an Interview",
136
- description: "Build a form to collect testimonials, case studies, async video interviews, or journalist responses",
137
- }, async () => {
138
- const sessionContext = await getSessionContext();
139
- return {
140
- messages: [
141
- {
142
- role: "user",
143
- content: {
144
- type: "text",
145
- text: "I want to collect responses or testimonials from people. What's the best approach?",
146
- },
147
- },
148
- {
149
- role: "assistant",
150
- content: {
151
- type: "text",
152
- text: `${sessionContext ? sessionContext + "\n\n" : ""}Here's how to build an interview or testimonial form with Clipform. Read the interview guide (clipform://guides/interview) for detailed craft knowledge on question design and pacing.
153
-
154
- ## Workflow
155
-
156
- 1. **Identify the ask** - what do you need from respondents? Testimonial, case study, expert comment, job application?
157
- 2. **Create the form** with clipform_create_form:
158
- - show_step_counter: true
159
- - disable_back_navigation: false
160
- 3. **Add a warm-up question** - something easy: "Tell us your name and role" (type: "open")
161
- 4. **Add core questions** (type: "open") - 2-3 max, one topic per question. Enable text + audio + video responses.
162
- 5. **Add contact collection** (type: "contact") - first name + email minimum
163
- 6. **Add consent** if needed - "I agree that my response may be used in [context]"
164
- 7. **Update end screen** - set expectations: "Thanks! We'll be in touch."
165
- 8. **Optional: add narration** - warm, inviting tone. "We'd love to hear your story..."
166
- 9. **Publish** with clipform_update_form
167
- 10. **Tag the form** - pass tags: one format (quiz/survey/interview/feedback/lead-gen), one genre (trivia/personality/nps/poll/testimonial), and 2-3 topic words
168
-
169
- ## Before building, ask
170
-
171
- 1. What are you collecting? (testimonial, case study, interview, application)
172
- 2. Should respondents reply with video, audio, text, or all three?
173
- 3. Do you need a consent statement?`,
174
- },
175
- },
176
- ],
177
- };
178
- });
179
- server.registerPrompt("create-survey", {
180
- title: "Create a Survey",
181
- description: "Build a feedback survey, NPS form, or research questionnaire",
182
- }, async () => {
183
- const sessionContext = await getSessionContext();
184
- return {
185
- messages: [
186
- {
187
- role: "user",
188
- content: {
189
- type: "text",
190
- text: "I want to collect feedback or run a survey. What's the best approach?",
191
- },
192
- },
193
- {
194
- role: "assistant",
195
- content: {
196
- type: "text",
197
- text: `${sessionContext ? sessionContext + "\n\n" : ""}Here's how to build a survey with Clipform. Read the survey guide (clipform://guides/survey) for craft knowledge on question design and reducing respondent fatigue.
198
-
199
- ## Workflow
200
-
201
- 1. **Define the key metric** - what's the one number you care about? (NPS, satisfaction, likelihood to recommend)
202
- 2. **Create the form** with clipform_create_form:
203
- - show_step_counter: true
204
- - disable_back_navigation: false
205
- 3. **Add key metric question first** (type: "choice" or "rating") - put it first while attention is highest
206
- 4. **Add one "why?" follow-up** (type: "open") - "What's the main reason for your score?"
207
- 5. **Add 2-3 specific questions** (type: "choice") - only ask what you'll act on
208
- 6. **Contact** (optional) - only if you need to follow up. Many surveys work better anonymous.
209
- 7. **Update end screen** - "Thanks for your feedback!"
210
- 8. **Publish** with clipform_update_form
211
- 9. **Tag the form** - pass tags: one format (quiz/survey/interview/feedback/lead-gen), one genre (trivia/personality/nps/poll/testimonial), and 2-3 topic words
212
-
213
- ## Key rule: 5 questions max. Every extra question costs completions.
214
-
215
- ## Before building, ask
216
-
217
- 1. What feedback are you collecting? (NPS, satisfaction, event feedback, product research)
218
- 2. Anonymous or identified?
219
- 3. Any specific areas you want to ask about?`,
220
- },
221
- },
222
- ],
223
- };
224
- });
225
- server.registerPrompt("create-funnel", {
226
- title: "Create a Funnel",
227
- description: "Build a lead qualification funnel or product recommendation quiz with branching logic",
228
- }, async () => {
229
- const sessionContext = await getSessionContext();
230
- return {
231
- messages: [
232
- {
233
- role: "user",
234
- content: {
235
- type: "text",
236
- text: "I want to qualify leads or recommend products based on answers. What's the best approach?",
237
- },
238
- },
239
- {
240
- role: "assistant",
241
- content: {
242
- type: "text",
243
- text: `${sessionContext ? sessionContext + "\n\n" : ""}Here's how to build a qualification funnel with Clipform. Read the funnel guide (clipform://guides/funnel) for craft knowledge on branching logic and conversion.
244
-
245
- ## Workflow
246
-
247
- 1. **Define outcomes** - what segments or recommendations exist? (e.g., Basic/Pro/Enterprise, or product categories)
248
- 2. **Create the form** with clipform_create_form:
249
- - show_step_counter: false (funnels feel shorter without it)
250
- - disable_back_navigation: true (prevents answer shopping that breaks scoring)
251
- 3. **Add hook question** (type: "choice") - "What best describes you?" or "What are you looking for?" This segments the user.
252
- 4. **Add qualifying questions** (type: "choice") - 2-3 questions that narrow down the need. Assign scores to each option.
253
- 5. **Set branching logic** with clipform_set_logic - route based on answers
254
- 6. **Add contact capture** (type: "contact") - name, email, phone. Place AFTER qualifying questions.
255
- 7. **Update end screen** with score_ranges for personalised outcomes: "Based on your answers, we recommend..."
256
- 8. **Publish** with clipform_update_form
257
- 9. **Tag the form** - pass tags: one format (quiz/survey/interview/feedback/lead-gen), one genre (trivia/personality/nps/poll/testimonial), and 2-3 topic words
258
-
259
- ## Key rule: 3-5 questions max. Every extra step loses leads.
260
-
261
- ## Before building, ask
262
-
263
- 1. What outcomes are you routing to? (products, plans, team members, messages)
264
- 2. What criteria determine the routing?
265
- 3. Do you need contact capture?`,
266
- },
267
- },
268
- ],
269
- };
270
- });
271
- }
272
- //# sourceMappingURL=prompts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,cAAc,CACnB,aAAa,EACb;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,6DAA6D;KAC3E,EACD,KAAK,IAAI,EAAE;QACT,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACjD,OAAO;YACP,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,oDAAoD;qBAC3D;iBACF;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAqC/B;qBACxB;iBACF;aACF;SACF,CAAC;IACF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,yBAAyB,EACzB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EAAE,6FAA6F;KAC3G,EACD,KAAK,IAAI,EAAE;QACT,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACjD,OAAO;YACP,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,gEAAgE;qBACvE;iBACF;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EA8CU;qBACjE;iBACF;aACF;SACF,CAAC;IACF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,qGAAqG;KACxG,EACD,KAAK,IAAI,EAAE;QACT,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACjD,OAAO;YACP,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,oFAAoF;qBAC3F;iBACF;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;oCAqB9B;qBACzB;iBACF;aACF;SACF,CAAC;IACF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,eAAe,EACf;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,8DAA8D;KACjE,EACD,KAAK,IAAI,EAAE;QACT,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACjD,OAAO;YACP,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,uEAAuE;qBAC9E;iBACF;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;6CAsBrB;qBAClC;iBACF;aACF;SACF,CAAC;IACF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,eAAe,EACf;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,uFAAuF;KAC1F,EACD,KAAK,IAAI,EAAE;QACT,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACjD,OAAO;YACP,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,2FAA2F;qBAClG;iBACF;gBACD;oBACE,IAAI,EAAE,WAAoB;oBAC1B,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;gCAsBlC;qBACrB;iBACF;aACF;SACF,CAAC;IACF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerResources(server: McpServer): void;
package/dist/resources.js DELETED
@@ -1,336 +0,0 @@
1
- import { getSessionContext } from "./lib/session-context.js";
2
- const WRITING_PRINCIPLES = `## Writing Principles
3
-
4
- - **Write for the ear.** Narration is spoken aloud. Short sentences. Natural rhythm.
5
- - **Research before writing.** Find 2-3 genuinely interesting facts per topic. Generic content doesn't hold attention.
6
- - **Conversational, not encyclopaedic.** "Here's what's wild about this..." not "The subject is characterized by..."
7
- - **Cut ruthlessly.** Every word must earn its place.
8
- - **Never reveal answers in narration.** The user picks from options - narration teases and builds intrigue.
9
- - **Don't read answer options aloud.** The viewer can see them on screen.
10
-
11
- ## Narration Tips
12
-
13
- - Tease the topic, don't summarise it
14
- - Give one interesting fact that makes the user curious
15
- - 5-15 seconds per question narration
16
- - If TTS comes back too long, trim the copy and regenerate
17
-
18
- ## Research
19
-
20
- Search for the specific subject, not generic terms ("komodo dragon habitat" not "reptile"). Cross-reference facts - quiz answers must be correct. Look for the surprising angle: what would make someone say "wait, really?"
21
-
22
- For timeless topics (history, geography, science), write from your own knowledge. For anything recent or uncertain, use web search or clipform_search_news. If neither is available, refuse rather than fabricate.`;
23
- const MEDIA_WORKFLOW = `## Media Workflow
24
-
25
- 1. **clipform_generate_tts** - narration audio (returns word-level captions)
26
- 2. **clipform_search_media** (kind: "image") - find 3 images per question
27
- 3. **clipform_generate_video** - Ken Burns video from images + audio
28
- 4. **clipform_upload_node_media** - attach video with captions (set show_captions: true)
29
-
30
- **Image selection:**
31
- - ONLY use URLs from clipform_search_media results
32
- - Search for the specific subject, not generic terms
33
- - Pick visually distinct images (different angles, colors, subjects)
34
- - Landscape images work best for pan effects
35
-
36
- **Slideshow defaults:**
37
- - 3 images per question, random_effects: true
38
- - transition: { type: "fade", duration: 1 }
39
- - Auto focal point detection, eased motion, and cinematic vignette are built in`;
40
- export function registerResources(server) {
41
- server.registerResource("guide-quiz", "clipform://guides/quiz", {
42
- description: "Craft knowledge for writing engaging quizzes - difficulty curves, question psychology, narration style, scoring",
43
- mimeType: "text/markdown",
44
- }, async () => ({
45
- contents: [
46
- {
47
- uri: "clipform://guides/quiz",
48
- mimeType: "text/markdown",
49
- text: `# Quiz Writing Guide
50
-
51
- ## Psychology
52
-
53
- Each question is a micro variable-reward event - the same dopamine loop that keeps people watching. Once someone answers 2-3 questions, sunk cost kicks in and they finish. Viewers mentally compete, then want to compare scores.
54
-
55
- **Target 50-60% correct.** Too easy = no challenge. Too hard = people feel stupid and won't share.
56
-
57
- ## Difficulty Curve
58
-
59
- | Position | Difficulty | Purpose |
60
- |----------|-----------|---------|
61
- | Q1-Q2 | Easy (80%+ get right) | Build confidence and commitment |
62
- | Q3-Q5 | Medium | Peak engagement |
63
- | Q6-Q8 | Hard (include one "gotcha") | The "everyone gets this wrong" moment |
64
- | Q9-Q10 | One hard, one satisfying medium | End on a smart feeling, not defeat |
65
-
66
- ## Question Design
67
-
68
- - **Myth-busters**: "Sushi means raw fish - True or False?" (False - it means seasoned rice)
69
- - **Sounds fake but true**: counterintuitive correct answers make people rewatch
70
- - **Common misconceptions**: "Capital of Australia?" (not Sydney - Canberra)
71
- - Under 12-15 words per question for mobile readability
72
- - Trigger gut reactions, not deep thinking
73
-
74
- ## Wrong Answer Generation
75
-
76
- 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.
77
-
78
- ## Narration Style
79
-
80
- You're a quiz master, not a question reader. Each question's narration should:
81
-
82
- 1. **Tease** - set the scene, build intrigue ("This one catches everyone out")
83
- 2. **Give context** - one interesting fact that makes the question richer
84
- 3. **Pose the question** - "So here's the question..."
85
-
86
- **Don't say:**
87
- - "You either know it or you don't" (meaningless filler)
88
- - "This is a really hard one" on every question (loses impact)
89
- - "Welcome to my quiz" / "Hey guys" (wastes time, skip to Q1)
90
-
91
- ${WRITING_PRINCIPLES}
92
-
93
- ${MEDIA_WORKFLOW}`,
94
- },
95
- ],
96
- }));
97
- server.registerResource("guide-personality-quiz", "clipform://guides/personality-quiz", {
98
- description: "Craft knowledge for building personality quizzes - category design, option weighting, outcome writing, no right/wrong answers",
99
- mimeType: "text/markdown",
100
- }, async () => ({
101
- contents: [
102
- {
103
- uri: "clipform://guides/personality-quiz",
104
- mimeType: "text/markdown",
105
- text: `# Personality Quiz Guide
106
-
107
- ## How it works
108
-
109
- Personality quizzes use **category-based scoring** (the \`scores\` field on options) instead of right/wrong scoring. Each option distributes points across outcome categories. The category with the highest total at the end determines the result.
110
-
111
- ## Category Design
112
-
113
- - **3-5 categories** is the sweet spot. Fewer feels too binary, more feels random.
114
- - Categories should be **distinct but equally appealing**. Nobody wants to get the "bad" result.
115
- - Name them after the outcome, not the trait: "Explorer" not "Adventurous", "The Architect" not "Organised".
116
-
117
- ## Option Weighting
118
-
119
- Each option scores into one or more categories:
120
-
121
- \`\`\`json
122
- { "scores": { "Explorer": 3, "Homebody": 0, "Foodie": 1 } }
123
- \`\`\`
124
-
125
- Guidelines:
126
- - **Primary category**: 2-3 points (this is the option's "home" category)
127
- - **Secondary**: 1 point (slight lean towards another category)
128
- - **Unrelated**: 0 (omit or set to 0)
129
- - **Knockout**: -1 (use sparingly - strongly rules out a category)
130
- - Every option should score positively in at least one category
131
- - Avoid giving every option the same spread - it makes results feel random
132
-
133
- ## Question Design
134
-
135
- - Questions should feel **personally revealing** but low-stakes: "Pick your ideal Saturday morning" not "What's your biggest weakness?"
136
- - Scenario-based questions work better than abstract preference questions
137
- - Each question should meaningfully differentiate between categories
138
- - Avoid questions where all options clearly map to one obvious personality
139
-
140
- ## Outcome Screens
141
-
142
- Each category needs a \`scoring_results\` entry on the end screen:
143
-
144
- - **Title**: "You're a [Category]!" - celebratory, not clinical
145
- - **Message**: 2-3 sentences that feel like a personalised insight. Reference specific traits the quiz measured.
146
- - **Optional CTA**: link to relevant content, product, or next step
147
-
148
- ## Narration Style
149
-
150
- Reflective and curious, not quizmaster-y:
151
- - "This one says a lot about you..."
152
- - "There's no wrong answer here - go with your gut"
153
- - "What does your choice reveal?"
154
-
155
- Do NOT say "let's see if you get this right" - there is no right answer.
156
-
157
- ${WRITING_PRINCIPLES}
158
-
159
- ${MEDIA_WORKFLOW}`,
160
- },
161
- ],
162
- }));
163
- server.registerResource("guide-interview", "clipform://guides/interview", {
164
- description: "Craft knowledge for building interview and testimonial collection forms - warm-up pacing, open questions, consent, video responses",
165
- mimeType: "text/markdown",
166
- }, async () => ({
167
- contents: [
168
- {
169
- uri: "clipform://guides/interview",
170
- mimeType: "text/markdown",
171
- text: `# Interview & Testimonial Guide
172
-
173
- ## Purpose
174
-
175
- Collect responses from people - testimonials, case studies, journalist callouts, async video interviews, candidate screening. The common thread: you're asking someone to respond on camera or in their own words.
176
-
177
- ## Structure
178
-
179
- 1. **Warm-up question** - something easy and low-stakes to get them comfortable. "Tell us your name and what you do" or "What's your role?"
180
- 2. **Core questions** - the real ask. Open-ended, one topic per question. Don't over-split - 2-3 core questions max.
181
- 3. **Follow-up** (optional) - "Anything else you'd like to add?" catches things you didn't think to ask.
182
- 4. **Contact collection** - first name + email minimum. Add phone/company if relevant.
183
- 5. **Consent** - "I agree that my response may be used in [context]." Always include for testimonials and media.
184
- 6. **End screen** - set expectations: "Thanks! We'll be in touch if we'd like to take things further."
185
-
186
- ## Question Design
187
-
188
- - **Open-ended by default.** Use "open" type with text + audio + video response enabled. Let the respondent choose their format.
189
- - **One topic per question.** "Tell us about your experience AND what you'd change" is two questions.
190
- - **Prompt, don't interrogate.** "What surprised you most about working with us?" beats "Rate your satisfaction."
191
- - **Keep it short.** 3-5 questions total. Every extra question loses respondents.
192
-
193
- ## Narration for Interviews
194
-
195
- Warmer and more personal than quiz narration. You're inviting someone to share, not testing them.
196
-
197
- - "We'd love to hear your story..."
198
- - "Take your time with this one - there's no wrong answer"
199
- - Keep narration under 10 seconds - the respondent's answer is the content, not yours
200
-
201
- ## Settings
202
-
203
- - disable_back_navigation: false (let people review their answers)
204
- - show_step_counter: true (so they know how much is left)
205
-
206
- ${WRITING_PRINCIPLES}
207
-
208
- ${MEDIA_WORKFLOW}`,
209
- },
210
- ],
211
- }));
212
- server.registerResource("guide-survey", "clipform://guides/survey", {
213
- description: "Craft knowledge for feedback surveys, NPS, and research forms - brevity, rating scales, respondent fatigue",
214
- mimeType: "text/markdown",
215
- }, async () => ({
216
- contents: [
217
- {
218
- uri: "clipform://guides/survey",
219
- mimeType: "text/markdown",
220
- text: `# Survey & Feedback Guide
221
-
222
- ## Purpose
223
-
224
- Collect structured feedback - NPS, customer satisfaction, product research, post-event feedback. The goal is clean, analysable data with minimal respondent fatigue.
225
-
226
- ## Structure
227
-
228
- Surveys should be ruthlessly short. Every extra question costs you completions.
229
-
230
- 1. **Key metric** - the one number you care about (NPS, satisfaction rating, likelihood to recommend). Put it first while attention is highest.
231
- 2. **Follow-up** - one open-ended "why?" question. "What's the main reason for your score?" This is where the insight lives.
232
- 3. **Specific questions** (optional) - 2-3 targeted choice questions on specific areas. Don't fish - only ask what you'll act on.
233
- 4. **Contact** (optional) - only if you need to follow up. Many surveys are better anonymous.
234
- 5. **End screen** - "Thanks for your feedback!" Keep it simple.
235
-
236
- ## Question Design
237
-
238
- - **Choice questions for data, open questions for insight.** Don't use open-ended where a rating scale would do, and don't use ratings where you need to understand why.
239
- - **Balanced scales.** Equal positive and negative options. "Excellent / Good / Fair / Poor" not "Amazing / Great / Good / OK / Bad."
240
- - **No leading questions.** "How much did you enjoy...?" assumes they enjoyed it.
241
- - **5 questions max.** If you need more, you're running research, not a survey - split it up.
242
-
243
- ## Narration for Surveys
244
-
245
- Optional - many surveys work fine as text only. If using narration:
246
-
247
- - Keep it brief (5-8 seconds). "We'd love your quick feedback on..."
248
- - Don't narrate every question - just the opener to set the tone
249
- - Friendly but efficient. Respect their time.
250
-
251
- ## Settings
252
-
253
- - disable_back_navigation: false
254
- - show_step_counter: true (shows progress, reduces abandonment)
255
-
256
- ${WRITING_PRINCIPLES}`,
257
- },
258
- ],
259
- }));
260
- server.registerResource("guide-funnel", "clipform://guides/funnel", {
261
- description: "Craft knowledge for lead qualification funnels and product recommendation quizzes - branching logic, progressive profiling, conversion",
262
- mimeType: "text/markdown",
263
- }, async () => ({
264
- contents: [
265
- {
266
- uri: "clipform://guides/funnel",
267
- mimeType: "text/markdown",
268
- text: `# Lead Qualification & Product Recommendation Guide
269
-
270
- ## Purpose
271
-
272
- Route people to the right outcome based on their answers. Lead qualification scores and segments prospects. Product recommendation guides users to the right product. Both use branching logic to personalise the journey.
273
-
274
- ## Structure
275
-
276
- 1. **Hook question** - immediately relevant, low friction. "What are you looking for?" or "What best describes you?" This segments the user and determines the branch.
277
- 2. **Qualifying questions** - 2-3 questions that narrow down the need. Each answer can branch to a different path.
278
- 3. **Contact capture** - name, email, phone. Place AFTER qualifying questions so they've invested before you ask for details.
279
- 4. **Outcome screen** - personalised end screen based on their answers. Use score_ranges or branching logic to show different messages.
280
-
281
- ## Question Design
282
-
283
- - **Progressive profiling.** Start broad, get specific. Don't ask for budget on question 1.
284
- - **Every question must earn its place.** If the answer doesn't change the outcome or routing, cut the question.
285
- - **Choice questions, not open-ended.** You need structured data to route and score. Save open-ended for "anything else?"
286
- - **3-5 questions max.** Every extra step loses leads. The funnel is leaky by nature - keep it tight.
287
-
288
- ## Branching Logic
289
-
290
- Use clipform_set_logic to route based on answers:
291
-
292
- - **Segment early.** Q1 answer determines which Q2 they see.
293
- - **Converge at capture.** All branches should reach the contact collection step.
294
- - **Different outcomes for different segments.** The end screen should feel personalised: "Based on your answers, we recommend..." not a generic "Thanks!"
295
-
296
- ## Scoring for Product Recommendation
297
-
298
- - Assign scores to each option based on which product/outcome it points to
299
- - Use score_ranges on the end screen to show different recommendations
300
- - Example: score 0-3 = "Basic plan", 4-6 = "Pro plan", 7+ = "Enterprise - let's talk"
301
-
302
- ## Narration for Funnels
303
-
304
- Short and action-oriented. You're guiding, not teaching.
305
-
306
- - "Let's find the right fit for you..."
307
- - "Just a couple of quick questions..."
308
- - Keep total narration under 30 seconds across the whole funnel
309
-
310
- ## Settings
311
-
312
- - disable_back_navigation: true (prevent answer shopping that breaks scoring)
313
- - show_step_counter: false (funnels feel shorter without a counter)
314
-
315
- ${WRITING_PRINCIPLES}`,
316
- },
317
- ],
318
- }));
319
- server.registerResource("context-session", "clipform://context/session", {
320
- description: "Current session info: auth mode, workspace, plan tier, node limits, feature flags. Read this before planning content to know your constraints.",
321
- mimeType: "text/markdown",
322
- annotations: { audience: ["assistant"], priority: 1.0 },
323
- }, async () => {
324
- const text = await getSessionContext();
325
- return {
326
- contents: [
327
- {
328
- uri: "clipform://context/session",
329
- mimeType: "text/markdown",
330
- text: text || "Session context unavailable - API may not be reachable.",
331
- },
332
- ],
333
- };
334
- });
335
- }
336
- //# sourceMappingURL=resources.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function createServer(): McpServer;
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerAddNodeTool(server: McpServer): void;