@clipform/mcp-server 2.6.0 → 2.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/caps-DBnfcEyJ.d.ts +20 -0
- package/dist/{chunk-L3DIBX4G.js → chunk-A5RVUIGS.js} +17 -7
- package/dist/chunk-A5RVUIGS.js.map +1 -0
- package/dist/{chunk-YAI5LQPF.js → chunk-O35IVA4L.js} +142 -9
- package/dist/chunk-O35IVA4L.js.map +1 -0
- package/dist/{chunk-WMLM53A3.js → chunk-QZO6MGNN.js} +310 -162
- package/dist/{chunk-WMLM53A3.js.map → chunk-QZO6MGNN.js.map} +1 -1
- package/dist/{chunk-44FHF2MF.js → chunk-ZOBK6CK7.js} +269 -45
- package/dist/chunk-ZOBK6CK7.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/instrument.d.ts +42 -0
- package/dist/instrument.js +5296 -0
- package/dist/instrument.js.map +1 -0
- package/dist/prompts.d.ts +3 -2
- package/dist/prompts.js +2 -2
- package/dist/resources.d.ts +3 -1
- package/dist/resources.js +2 -2
- package/dist/server.d.ts +12 -1
- package/dist/server.js +6 -4
- package/package.json +6 -1
- package/dist/chunk-44FHF2MF.js.map +0 -1
- package/dist/chunk-L3DIBX4G.js.map +0 -1
- package/dist/chunk-YAI5LQPF.js.map +0 -1
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ Your MCP client lists these automatically on connect (via `tools/list`). Full re
|
|
|
71
71
|
| `clipform_update_form` | Update a form's title, publish status, settings, or tags. |
|
|
72
72
|
| `clipform_delete_form` | Move a form and all its nodes to the trash. |
|
|
73
73
|
| `clipform_get_results` | View response counts, choice/action answer breakdowns, and recent open-text answers for a form. |
|
|
74
|
+
| `clipform_get_responses` | List a Clipform form's individual responses (submissions) with time filtering - complements clipform_get_results (aggregates). |
|
|
74
75
|
| `clipform_add_node` | Add a new node to an existing form. |
|
|
75
76
|
| `clipform_update_node` | Update one or more existing nodes' text, type, config, or options. |
|
|
76
77
|
| `clipform_delete_node` | Delete a node from a form. |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a connected surface can actually do, derived from the connect-time
|
|
3
|
+
* toolset filter (#3309) so the guidance layers (server instructions, prompt
|
|
4
|
+
* recipes, `clipform_get_workflow`, craft guides) never reference a tool the
|
|
5
|
+
* surface doesn't register (#3681).
|
|
6
|
+
*
|
|
7
|
+
* The Claude Connectors Directory surface (`mcp.clipform.io/forms`) is
|
|
8
|
+
* account + forms only: no media generation and no research helpers. A
|
|
9
|
+
* workflow that still says "call clipform_generate_tts" there sends the model
|
|
10
|
+
* at a tool that doesn't exist, which shows up in review as failed tool
|
|
11
|
+
* calls. Every guidance producer takes a ServerCaps and gates on it.
|
|
12
|
+
*/
|
|
13
|
+
interface ServerCaps {
|
|
14
|
+
/** Narration, video, image, music, render, and asset tools are registered. */
|
|
15
|
+
media: boolean;
|
|
16
|
+
/** News lookup and the generation audit log are registered. */
|
|
17
|
+
research: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type { ServerCaps as S };
|
|
@@ -2,9 +2,10 @@ import {
|
|
|
2
2
|
ALL_VARIANTS,
|
|
3
3
|
FORM_TYPES,
|
|
4
4
|
FORM_TYPE_KEYS,
|
|
5
|
+
FULL_CAPS,
|
|
5
6
|
callApi,
|
|
6
7
|
getSessionContext
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-O35IVA4L.js";
|
|
8
9
|
|
|
9
10
|
// src/lib/guides.ts
|
|
10
11
|
var guidesPromise = null;
|
|
@@ -42,6 +43,14 @@ function guideFallbackText(uri) {
|
|
|
42
43
|
`forms tight - every question must earn its place.`
|
|
43
44
|
].join("\n");
|
|
44
45
|
}
|
|
46
|
+
function applyCapsToGuide(text, caps) {
|
|
47
|
+
if (caps.media) return text;
|
|
48
|
+
return [
|
|
49
|
+
"> **This connection exposes form-building tools only** - no narration, video, image, or music tools. Where this guide mentions narration, media, or rendering, skip that part and carry the same craft into the written question text.",
|
|
50
|
+
"",
|
|
51
|
+
text
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
45
54
|
|
|
46
55
|
// src/resources.ts
|
|
47
56
|
var GUIDE_TYPES = FORM_TYPE_KEYS;
|
|
@@ -62,10 +71,10 @@ function getGuideUri(type, variant) {
|
|
|
62
71
|
}
|
|
63
72
|
return `clipform://guides/${type}`;
|
|
64
73
|
}
|
|
65
|
-
async function readGuide(uri) {
|
|
66
|
-
return await fetchGuideText(uri) ?? guideFallbackText(uri);
|
|
74
|
+
async function readGuide(uri, caps) {
|
|
75
|
+
return applyCapsToGuide(await fetchGuideText(uri) ?? guideFallbackText(uri), caps);
|
|
67
76
|
}
|
|
68
|
-
function registerResources(server) {
|
|
77
|
+
function registerResources(server, caps = FULL_CAPS) {
|
|
69
78
|
for (const type of GUIDE_TYPES) {
|
|
70
79
|
server.registerResource(
|
|
71
80
|
`guide-${type}`,
|
|
@@ -79,7 +88,7 @@ function registerResources(server) {
|
|
|
79
88
|
contents: [{
|
|
80
89
|
uri: getGuideUri(type),
|
|
81
90
|
mimeType: "text/markdown",
|
|
82
|
-
text: await readGuide(getGuideUri(type))
|
|
91
|
+
text: await readGuide(getGuideUri(type), caps)
|
|
83
92
|
}]
|
|
84
93
|
})
|
|
85
94
|
);
|
|
@@ -97,7 +106,7 @@ function registerResources(server) {
|
|
|
97
106
|
contents: [{
|
|
98
107
|
uri: getGuideUri("quiz", variant),
|
|
99
108
|
mimeType: "text/markdown",
|
|
100
|
-
text: await readGuide(getGuideUri("quiz", variant))
|
|
109
|
+
text: await readGuide(getGuideUri("quiz", variant), caps)
|
|
101
110
|
}]
|
|
102
111
|
})
|
|
103
112
|
);
|
|
@@ -128,9 +137,10 @@ function registerResources(server) {
|
|
|
128
137
|
export {
|
|
129
138
|
fetchGuideText,
|
|
130
139
|
guideFallbackText,
|
|
140
|
+
applyCapsToGuide,
|
|
131
141
|
GUIDE_TYPES,
|
|
132
142
|
QUIZ_VARIANTS,
|
|
133
143
|
getGuideUri,
|
|
134
144
|
registerResources
|
|
135
145
|
};
|
|
136
|
-
//# sourceMappingURL=chunk-
|
|
146
|
+
//# sourceMappingURL=chunk-A5RVUIGS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/guides.ts","../src/resources.ts"],"sourcesContent":["import { callApi } from \"./api-client.js\";\nimport type { ServerCaps } from \"./caps.js\";\n\n/**\n * Craft guide bodies live server-side (#470) - the npm package is a shim\n * that fetches them at runtime instead of bundling them in the tarball.\n * One fetch per process (all ~30KB of guides in a single response), cached;\n * a failed fetch is NOT cached so the next read retries.\n */\n\nexport interface RemoteGuide {\n type: string;\n variant: string | null;\n uri: string;\n mimeType: string;\n text: string;\n}\n\nlet guidesPromise: Promise<Map<string, RemoteGuide>> | null = null;\n\nasync function loadGuides(): Promise<Map<string, RemoteGuide>> {\n const result = await callApi(\"/internal/mcp/guides\", { method: \"GET\" });\n if (!result.ok) {\n throw new Error(`Failed to load guides: ${result.error}`);\n }\n const guides = (result.data as { guides?: RemoteGuide[] }).guides ?? [];\n return new Map(guides.map((g) => [g.uri, g]));\n}\n\n/** Fetch a guide body by its clipform:// URI. Returns null when unavailable. */\nexport async function fetchGuideText(uri: string): Promise<string | null> {\n if (!guidesPromise) {\n guidesPromise = loadGuides();\n }\n try {\n const guides = await guidesPromise;\n return guides.get(uri)?.text ?? null;\n } catch (err) {\n guidesPromise = null; // don't cache failures - retry on the next read\n // Loud, not silent: a misconfigured API_URL/key otherwise degrades every\n // guide to the stub with nothing in the logs.\n console.error(`[guides] Failed to fetch ${uri}: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n}\n\n/** Shown in place of a guide when the API is unreachable or unauthenticated. */\nexport function guideFallbackText(uri: string): string {\n return [\n `# Guide unavailable`,\n ``,\n `The craft guide (${uri}) could not be loaded from the Clipform API.`,\n `Guides are served at runtime and need a reachable API with a valid key -`,\n `check API_URL and CLIPFORM_API_KEY, then try again.`,\n ``,\n `General principles in the meantime: write narration for the ear (short,`,\n `conversational), never reveal answers in narration or media, and keep`,\n `forms tight - every question must earn its place.`,\n ].join(\"\\n\");\n}\n\n/**\n * Craft guide bodies are written for the full tool surface and mention the\n * narration/video tools by name. On a surface that doesn't register them\n * (the Claude Connectors Directory resource, #3681) prefix the guide with a\n * note so the model doesn't chase tools it can't call. The body itself is\n * untouched - the craft (question design, pacing) is the same either way.\n */\nexport function applyCapsToGuide(text: string, caps: ServerCaps): string {\n if (caps.media) return text;\n return [\n \"> **This connection exposes form-building tools only** - no narration, video, image, or music tools. Where this guide mentions narration, media, or rendering, skip that part and carry the same craft into the written question text.\",\n \"\",\n text,\n ].join(\"\\n\");\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { getSessionContext } from \"./lib/session-context.js\";\nimport { FORM_TYPE_KEYS, FORM_TYPES, ALL_VARIANTS } from \"@vid-master/config\";\n\nexport const GUIDE_TYPES = FORM_TYPE_KEYS as readonly string[] as readonly [string, ...string[]];\nexport type GuideType = (typeof FORM_TYPE_KEYS)[number];\n\nexport const QUIZ_VARIANTS = ALL_VARIANTS as readonly string[] as readonly [string, ...string[]];\nexport type QuizVariant = (typeof ALL_VARIANTS)[number];\n// Guide BODIES are not bundled here (#470): the npm tarball ships only this\n// registration metadata. Text is fetched from the API at runtime - see\n// lib/guides.ts (cached per process, stub fallback when unreachable).\nimport { fetchGuideText, guideFallbackText, applyCapsToGuide } from \"./lib/guides.js\";\nimport { FULL_CAPS, type ServerCaps } from \"./lib/caps.js\";\n\nconst GUIDE_DESCRIPTIONS: Record<GuideType, string> = {\n \"quiz\": \"Craft knowledge for writing engaging quizzes - difficulty curves, question psychology, narration style, scoring\",\n \"survey\": \"Craft knowledge for feedback surveys, NPS, and research forms - brevity, rating scales, respondent fatigue\",\n \"interview\": \"Craft knowledge for building interview forms - warm-up pacing, open questions, consent, video responses\",\n \"funnel\": \"Craft knowledge for lead qualification funnels - planned feature, conditional routing coming soon\",\n \"testimonial\": \"Craft knowledge for collecting testimonials and customer stories on video - storytelling prompts, comfort techniques, consent\",\n \"application\": \"Craft knowledge for application and evaluation forms - multi-section structure, video responses for behavioural questions, screening\",\n \"booking\": \"Craft knowledge for event registration and booking forms - minimal friction, video welcome, confirmation flow\",\n};\n\n// Sourced from config (single source of truth) so the agent-facing resource\n// descriptions can't drift from FORM_TYPES.quiz.variant_descriptions (#2534,\n// the exact pair packages/config/CLAUDE.md warns about).\nconst QUIZ_VARIANT_DESCRIPTIONS = FORM_TYPES.quiz.variant_descriptions;\n\nexport function getGuideUri(type: GuideType, variant?: QuizVariant): string {\n if (type === \"quiz\" && variant) {\n return `clipform://guides/quiz/${variant}`;\n }\n return `clipform://guides/${type}`;\n}\n\nasync function readGuide(uri: string, caps: ServerCaps): Promise<string> {\n return applyCapsToGuide((await fetchGuideText(uri)) ?? guideFallbackText(uri), caps);\n}\n\nexport function registerResources(server: McpServer, caps: ServerCaps = FULL_CAPS) {\n for (const type of GUIDE_TYPES) {\n server.registerResource(\n `guide-${type}`,\n getGuideUri(type),\n {\n description: GUIDE_DESCRIPTIONS[type],\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\" as const], priority: 0.8 },\n },\n async () => ({\n contents: [{\n uri: getGuideUri(type),\n mimeType: \"text/markdown\",\n text: await readGuide(getGuideUri(type), caps),\n }],\n }),\n );\n }\n\n for (const variant of QUIZ_VARIANTS) {\n server.registerResource(\n `guide-quiz-${variant}`,\n getGuideUri(\"quiz\", variant),\n {\n description: QUIZ_VARIANT_DESCRIPTIONS[variant],\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\" as const], priority: 0.8 },\n },\n async () => ({\n contents: [{\n uri: getGuideUri(\"quiz\", variant),\n mimeType: \"text/markdown\",\n text: await readGuide(getGuideUri(\"quiz\", variant), caps),\n }],\n }),\n );\n }\n\n server.registerResource(\n \"context-session\",\n \"clipform://context/session\",\n {\n description:\n \"Current session info: auth mode, workspace name, plan name, and node/form limits. Read this before planning content to know your constraints.\",\n mimeType: \"text/markdown\",\n annotations: { audience: [\"assistant\"], priority: 1.0 },\n },\n async () => {\n const text = await getSessionContext();\n return {\n contents: [\n {\n uri: \"clipform://context/session\",\n mimeType: \"text/markdown\",\n text: text || \"Session context unavailable - API may not be reachable.\",\n },\n ],\n };\n }\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -567,6 +567,80 @@ for (const [key, f] of Object.entries(FEATURES)) {
|
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
}
|
|
570
|
+
var FEATURE_FLAGS = {
|
|
571
|
+
get ENABLE_BRANCHING() {
|
|
572
|
+
return FEATURES.branching.enabled;
|
|
573
|
+
},
|
|
574
|
+
get ENABLE_CUSTOM_SCORES() {
|
|
575
|
+
return FEATURES.custom_scores.enabled;
|
|
576
|
+
},
|
|
577
|
+
get ENABLE_TEXT_RESPONSE() {
|
|
578
|
+
return FEATURES.text_response.enabled;
|
|
579
|
+
},
|
|
580
|
+
get ENABLE_MULTI_SELECT() {
|
|
581
|
+
return FEATURES.multi_select.enabled;
|
|
582
|
+
},
|
|
583
|
+
get INLINE_EMBED() {
|
|
584
|
+
return FEATURES.embed_inline.enabled;
|
|
585
|
+
},
|
|
586
|
+
get WIDGET_EMBED() {
|
|
587
|
+
return FEATURES.embed_widget.enabled;
|
|
588
|
+
},
|
|
589
|
+
get WEBHOOKS() {
|
|
590
|
+
return FEATURES.webhooks.enabled;
|
|
591
|
+
},
|
|
592
|
+
get INTEGRATIONS() {
|
|
593
|
+
return Object.entries(FEATURES).some(([k, f]) => k.startsWith("integration_") && f.enabled);
|
|
594
|
+
},
|
|
595
|
+
get CUSTOM_FONTS() {
|
|
596
|
+
return FEATURES.custom_fonts.enabled;
|
|
597
|
+
},
|
|
598
|
+
get TRACKED_LINKS() {
|
|
599
|
+
return FEATURES.tracked_links.enabled;
|
|
600
|
+
},
|
|
601
|
+
get DYNAMIC_LINK() {
|
|
602
|
+
return FEATURES.dynamic_link.enabled;
|
|
603
|
+
},
|
|
604
|
+
get CUSTOM_DOMAINS() {
|
|
605
|
+
return FEATURES.custom_domains.enabled;
|
|
606
|
+
},
|
|
607
|
+
get BRANDED_QR() {
|
|
608
|
+
return FEATURES.branded_qr.enabled;
|
|
609
|
+
},
|
|
610
|
+
get EMAIL_SHARE() {
|
|
611
|
+
return FEATURES.email_share.enabled;
|
|
612
|
+
},
|
|
613
|
+
get SHARE_NODE() {
|
|
614
|
+
return FEATURES.share_node.enabled;
|
|
615
|
+
},
|
|
616
|
+
get BRAND_NAME() {
|
|
617
|
+
return FEATURES.brand_name.enabled;
|
|
618
|
+
},
|
|
619
|
+
get CSV_EXPORT() {
|
|
620
|
+
return FEATURES.csv_export.enabled;
|
|
621
|
+
},
|
|
622
|
+
get ALLOW_RESUME() {
|
|
623
|
+
return FEATURES.allow_resume.enabled;
|
|
624
|
+
},
|
|
625
|
+
get UTM_ANALYTICS() {
|
|
626
|
+
return FEATURES.utm_tracking.enabled;
|
|
627
|
+
},
|
|
628
|
+
get API_KEYS() {
|
|
629
|
+
return FEATURES.api_keys.enabled;
|
|
630
|
+
},
|
|
631
|
+
get NOTIFICATIONS() {
|
|
632
|
+
return FEATURES.notifications.enabled;
|
|
633
|
+
},
|
|
634
|
+
get IMPORT_TYPEFORM() {
|
|
635
|
+
return FEATURES.import_typeform.enabled;
|
|
636
|
+
},
|
|
637
|
+
get IMPORT_TALLY() {
|
|
638
|
+
return FEATURES.import_tally.enabled;
|
|
639
|
+
},
|
|
640
|
+
get PUBLIC_RESULTS() {
|
|
641
|
+
return FEATURES.public_results.enabled;
|
|
642
|
+
}
|
|
643
|
+
};
|
|
570
644
|
|
|
571
645
|
// ../config/node-types.js
|
|
572
646
|
var RESPONSE_FORMATS = ["text", "audio", "video"];
|
|
@@ -1099,7 +1173,7 @@ var NODE_TYPES = {
|
|
|
1099
1173
|
label: "File Upload",
|
|
1100
1174
|
shorthand: "Upload",
|
|
1101
1175
|
icon: "Upload",
|
|
1102
|
-
color: "#
|
|
1176
|
+
color: "#ECFCCB",
|
|
1103
1177
|
description: "Collect file uploads from respondents",
|
|
1104
1178
|
category: "input",
|
|
1105
1179
|
sort_order: 6,
|
|
@@ -1599,7 +1673,7 @@ var NODE_TYPES = {
|
|
|
1599
1673
|
color: "#DBEAFE",
|
|
1600
1674
|
description: "Simple button for acknowledgment or navigation",
|
|
1601
1675
|
category: "input",
|
|
1602
|
-
sort_order: 3,
|
|
1676
|
+
sort_order: 3.5,
|
|
1603
1677
|
has_options: true,
|
|
1604
1678
|
min_options: 1,
|
|
1605
1679
|
max_options: 1,
|
|
@@ -2133,6 +2207,47 @@ var FORM_TYPES = {
|
|
|
2133
2207
|
variant_guide_uris: {},
|
|
2134
2208
|
variant_descriptions: {},
|
|
2135
2209
|
prompt: { name: "create-booking", title: "Create a Booking Form", description: "Build an event registration or booking form with a personal video welcome" }
|
|
2210
|
+
},
|
|
2211
|
+
intake: {
|
|
2212
|
+
label: "Client Intake",
|
|
2213
|
+
description: "Client intake and onboarding form for a service business",
|
|
2214
|
+
sort_order: 8,
|
|
2215
|
+
category: "collection",
|
|
2216
|
+
aliases: ["client-intake", "onboarding", "enquiry", "inquiry", "new-client"],
|
|
2217
|
+
variants: [],
|
|
2218
|
+
required_features: [],
|
|
2219
|
+
required_node_types: ["details", "open", "end_screen"],
|
|
2220
|
+
default_media_style: "video",
|
|
2221
|
+
guide_uri: "clipform://guides/intake",
|
|
2222
|
+
guide_description: "Craft knowledge for client intake and onboarding forms - a warm welcome, minimal contact capture, a video-first question about what the client needs, and a clear next step",
|
|
2223
|
+
discovery: [
|
|
2224
|
+
{ key: "use_case", question: "What kind of business or service? (massage, coaching, personal training, agency)", fallback: "General client intake", mode: "all" },
|
|
2225
|
+
{ key: "response_format", question: "How should people answer the open question? (video, audio, text, all)", fallback: "All formats", mode: "full" }
|
|
2226
|
+
],
|
|
2227
|
+
variant_discovery: {},
|
|
2228
|
+
variant_guide_uris: {},
|
|
2229
|
+
variant_descriptions: {},
|
|
2230
|
+
prompt: { name: "create-intake", title: "Create a Client Intake Form", description: "Build a warm client intake or onboarding form that captures contact details and what the client needs" }
|
|
2231
|
+
},
|
|
2232
|
+
"lead-capture": {
|
|
2233
|
+
label: "Lead Capture",
|
|
2234
|
+
description: "Linear lead capture or enquiry form - turn interest into a contact with minimal friction",
|
|
2235
|
+
sort_order: 9,
|
|
2236
|
+
category: "collection",
|
|
2237
|
+
aliases: ["lead", "lead-form", "enquiry-form", "waitlist", "get-a-quote"],
|
|
2238
|
+
variants: [],
|
|
2239
|
+
required_features: [],
|
|
2240
|
+
required_node_types: ["details", "end_screen"],
|
|
2241
|
+
default_media_style: "text",
|
|
2242
|
+
guide_uri: "clipform://guides/lead-capture",
|
|
2243
|
+
guide_description: "Craft knowledge for linear lead capture and enquiry forms - minimal friction, a light qualifier only if it routes follow-up, and a clear next step (no branching, no scoring)",
|
|
2244
|
+
discovery: [
|
|
2245
|
+
{ key: "use_case", question: "What are you capturing leads for? (a service, a product, a waitlist, a quote)", fallback: "General enquiries", mode: "all" }
|
|
2246
|
+
],
|
|
2247
|
+
variant_discovery: {},
|
|
2248
|
+
variant_guide_uris: {},
|
|
2249
|
+
variant_descriptions: {},
|
|
2250
|
+
prompt: { name: "create-lead-capture", title: "Create a Lead Capture Form", description: "Build a short lead capture or enquiry form that turns interest into a contact" }
|
|
2136
2251
|
}
|
|
2137
2252
|
};
|
|
2138
2253
|
for (const def of Object.values(FORM_TYPES)) {
|
|
@@ -2183,7 +2298,9 @@ var HELP_TOPICS = {
|
|
|
2183
2298
|
emailShare: { path: "/help/sharing", anchor: "share-by-email" },
|
|
2184
2299
|
publicResults: { path: "/help/public-results", anchor: null },
|
|
2185
2300
|
trash: { path: "/help/managing-forms", anchor: "trash" },
|
|
2186
|
-
agreementVersions: { path: "/help/responses", anchor: "agreement-versions" }
|
|
2301
|
+
agreementVersions: { path: "/help/responses", anchor: "agreement-versions" },
|
|
2302
|
+
customDomains: { path: "/help/domains", anchor: null },
|
|
2303
|
+
customPath: { path: "/help/links", anchor: "custom-path-on-your-domain" }
|
|
2187
2304
|
};
|
|
2188
2305
|
function buildHelpLinks(docsBaseUrl) {
|
|
2189
2306
|
const links = {};
|
|
@@ -2576,7 +2693,8 @@ var MCP_TOOL_TOOLSETS = {
|
|
|
2576
2693
|
clipform_delete_form: "account",
|
|
2577
2694
|
clipform_whoami: "account",
|
|
2578
2695
|
clipform_get_results: "account",
|
|
2579
|
-
|
|
2696
|
+
clipform_get_responses: "account",
|
|
2697
|
+
// forms: form/node structure + craft guidance used while building.
|
|
2580
2698
|
clipform_create_form: "forms",
|
|
2581
2699
|
clipform_import_form: "forms",
|
|
2582
2700
|
clipform_add_node: "forms",
|
|
@@ -2586,10 +2704,12 @@ var MCP_TOOL_TOOLSETS = {
|
|
|
2586
2704
|
clipform_set_logic: "forms",
|
|
2587
2705
|
clipform_get_guide: "forms",
|
|
2588
2706
|
clipform_get_workflow: "forms",
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
clipform_log_generation: "
|
|
2592
|
-
// media: creative/render/asset tools.
|
|
2707
|
+
// research: third-party content lookup + generation-workflow audit.
|
|
2708
|
+
clipform_search_news: "research",
|
|
2709
|
+
clipform_log_generation: "research",
|
|
2710
|
+
// media: creative/render/asset tools. fetch_boundary only feeds the Map
|
|
2711
|
+
// composition's `boundary` prop, so it lives with the render tools.
|
|
2712
|
+
clipform_fetch_boundary: "media",
|
|
2593
2713
|
clipform_generate_tts: "media",
|
|
2594
2714
|
clipform_generate_video: "media",
|
|
2595
2715
|
clipform_render_composition: "media",
|
|
@@ -2607,6 +2727,16 @@ var MCP_TOOL_TOOLSETS = {
|
|
|
2607
2727
|
clipform_list_video_templates: "media"
|
|
2608
2728
|
};
|
|
2609
2729
|
|
|
2730
|
+
// src/lib/caps.ts
|
|
2731
|
+
var FULL_CAPS = Object.freeze({ media: true, research: true });
|
|
2732
|
+
function capsFromToolsets(toolsets) {
|
|
2733
|
+
if (toolsets === void 0) return FULL_CAPS;
|
|
2734
|
+
return {
|
|
2735
|
+
media: toolsets.includes("media"),
|
|
2736
|
+
research: toolsets.includes("research")
|
|
2737
|
+
};
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2610
2740
|
// src/lib/api-client.ts
|
|
2611
2741
|
function getApiBaseUrl() {
|
|
2612
2742
|
const url = process.env.API_URL;
|
|
@@ -2791,6 +2921,7 @@ async function getSessionContext() {
|
|
|
2791
2921
|
}
|
|
2792
2922
|
|
|
2793
2923
|
export {
|
|
2924
|
+
FEATURE_FLAGS,
|
|
2794
2925
|
NODE_TYPES,
|
|
2795
2926
|
ACTIVE_NODE_TYPES,
|
|
2796
2927
|
NON_COUNTABLE_TYPES,
|
|
@@ -2811,6 +2942,8 @@ export {
|
|
|
2811
2942
|
exposedCompositionIds,
|
|
2812
2943
|
MCP_TOOL_TIERS,
|
|
2813
2944
|
MCP_TOOL_TOOLSETS,
|
|
2945
|
+
FULL_CAPS,
|
|
2946
|
+
capsFromToolsets,
|
|
2814
2947
|
callApi,
|
|
2815
2948
|
errorResult,
|
|
2816
2949
|
textResult,
|
|
@@ -2818,4 +2951,4 @@ export {
|
|
|
2818
2951
|
getSessionContextWithAuth,
|
|
2819
2952
|
getSessionContext
|
|
2820
2953
|
};
|
|
2821
|
-
//# sourceMappingURL=chunk-
|
|
2954
|
+
//# sourceMappingURL=chunk-O35IVA4L.js.map
|