@clipform/mcp-server 4.3.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api-client.js +1 -1
- package/dist/{chunk-QIMA75T4.js → chunk-5JFU4OEI.js} +2 -2
- package/dist/{chunk-JY7OZS6P.js → chunk-E2T3UTF3.js} +45 -18
- package/dist/chunk-E2T3UTF3.js.map +1 -0
- package/dist/{chunk-4U4CLCYD.js → chunk-F4AFULRJ.js} +3 -3
- package/dist/{chunk-63CHR6UP.js → chunk-HWOV2WRK.js} +3 -3
- package/dist/{chunk-AEU5YBXM.js → chunk-K2JHO4A4.js} +5 -2
- package/dist/chunk-K2JHO4A4.js.map +1 -0
- package/dist/index.js +5 -5
- package/dist/prompts.js +3 -3
- package/dist/resources.js +3 -3
- package/dist/server.d.ts +7 -5
- package/dist/server.js +5 -5
- package/package.json +2 -1
- package/server.json +2 -2
- package/dist/chunk-AEU5YBXM.js.map +0 -1
- package/dist/chunk-JY7OZS6P.js.map +0 -1
- /package/dist/{chunk-QIMA75T4.js.map → chunk-5JFU4OEI.js.map} +0 -0
- /package/dist/{chunk-4U4CLCYD.js.map → chunk-F4AFULRJ.js.map} +0 -0
- /package/dist/{chunk-63CHR6UP.js.map → chunk-HWOV2WRK.js.map} +0 -0
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ Your MCP client lists these automatically on connect (via `tools/list`). Full re
|
|
|
60
60
|
| Tool | Description |
|
|
61
61
|
|------|-------------|
|
|
62
62
|
| `clipform_create_form` | Create a new Clipform (interactive video-style form). |
|
|
63
|
-
| `clipform_import_form` |
|
|
63
|
+
| `clipform_import_form` | Copies the questions from a public Google Form, Typeform, or Tally form into a new Clipform draft. |
|
|
64
64
|
| `clipform_list_forms` | List forms in your workspace with optional filtering. |
|
|
65
65
|
| `clipform_whoami` | Show the current identity: auth mode (api key, oauth, session, or anonymous), active workspace, and plan limits. |
|
|
66
66
|
| `clipform_get_form` | Retrieve a form's details including all nodes in sequential order and their routing. |
|
package/dist/api-client.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
CURRENT_PLAN_VERSIONS,
|
|
3
3
|
PLAN_LIMITS,
|
|
4
4
|
callApi
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-K2JHO4A4.js";
|
|
6
6
|
import {
|
|
7
7
|
getMcpAuth
|
|
8
8
|
} from "./chunk-BV3KA6HC.js";
|
|
@@ -123,4 +123,4 @@ export {
|
|
|
123
123
|
getSessionContextWithAuth,
|
|
124
124
|
getSessionContext
|
|
125
125
|
};
|
|
126
|
-
//# sourceMappingURL=chunk-
|
|
126
|
+
//# sourceMappingURL=chunk-5JFU4OEI.js.map
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
union,
|
|
30
30
|
unknown,
|
|
31
31
|
url
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-HWOV2WRK.js";
|
|
33
33
|
import {
|
|
34
34
|
GUIDE_TYPES,
|
|
35
35
|
QUIZ_VARIANTS,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
getGuideUri,
|
|
39
39
|
guideFallbackText,
|
|
40
40
|
registerResources
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-F4AFULRJ.js";
|
|
42
42
|
import {
|
|
43
43
|
ANON_PREVIEW_LINK_LABEL,
|
|
44
44
|
ANON_PREVIEW_NOTICE,
|
|
@@ -50,11 +50,12 @@ import {
|
|
|
50
50
|
capsFromToolsets,
|
|
51
51
|
isPreviewViewerUrl,
|
|
52
52
|
withAdoptedNotice
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-5JFU4OEI.js";
|
|
54
54
|
import {
|
|
55
55
|
ACTIVE_NODE_TYPES,
|
|
56
56
|
CONTACT_FIELDS,
|
|
57
57
|
FEATURE_FLAGS,
|
|
58
|
+
FORM_TYPES_LIST,
|
|
58
59
|
FORM_TYPE_ALIASES,
|
|
59
60
|
MCP_ANON_PUBLISH_GATE,
|
|
60
61
|
MCP_TOOL_SECURITY,
|
|
@@ -74,7 +75,7 @@ import {
|
|
|
74
75
|
stripGatedConfigKeys,
|
|
75
76
|
structuredResult,
|
|
76
77
|
textResult
|
|
77
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-K2JHO4A4.js";
|
|
78
79
|
import {
|
|
79
80
|
getMcpAuth,
|
|
80
81
|
runWithMcpAuth,
|
|
@@ -16080,7 +16081,20 @@ import { readFileSync } from "fs";
|
|
|
16080
16081
|
import { dirname, join } from "path";
|
|
16081
16082
|
import { fileURLToPath } from "url";
|
|
16082
16083
|
|
|
16084
|
+
// src/lib/job-copy.ts
|
|
16085
|
+
var ACTIVE_JOB_LABELS = FORM_TYPES_LIST.filter(
|
|
16086
|
+
(t) => t.is_active
|
|
16087
|
+
).map((t) => t.label.toLowerCase());
|
|
16088
|
+
function joinJobs(labels, conjunction = "and") {
|
|
16089
|
+
if (labels.length <= 2) return labels.join(` ${conjunction} `);
|
|
16090
|
+
return `${labels.slice(0, -1).join(", ")}, ${conjunction} ${labels[labels.length - 1]}`;
|
|
16091
|
+
}
|
|
16092
|
+
var ACTIVE_JOBS_PHRASE = joinJobs(ACTIVE_JOB_LABELS);
|
|
16093
|
+
var IMPORT_FORM_LEAD = "Copies the questions from a public Google Form, Typeform, or Tally form into a new Clipform draft. The source form and its responses stay where they are.";
|
|
16094
|
+
var INSTRUCTIONS_LEAD = `Clipform builds interactive video-style forms that other people fill in, with their answers (video, audio, or text) stored for the owner to read back: ${ACTIVE_JOBS_PHRASE}. Drafting questions as text to review or paste is a chat task, not a Clipform build.`;
|
|
16095
|
+
|
|
16083
16096
|
// src/lib/onboarding-copy.ts
|
|
16097
|
+
var STARTERS = ACTIVE_JOB_LABELS.join(", ");
|
|
16084
16098
|
var ONBOARDING_OFFER_CONTROL_VARIANT = "control";
|
|
16085
16099
|
var ONBOARDING_OFFER_COPY = {
|
|
16086
16100
|
// #4089 review: this cohort has already completed OAuth to connect - they
|
|
@@ -16089,12 +16103,12 @@ var ONBOARDING_OFFER_COPY = {
|
|
|
16089
16103
|
// did and reads as broken. Acknowledge the connection instead, then offer
|
|
16090
16104
|
// to build. (The anonymous/no-auth entry point is a different surface,
|
|
16091
16105
|
// #4088 - not this cohort.)
|
|
16092
|
-
[ONBOARDING_OFFER_CONTROL_VARIANT]:
|
|
16106
|
+
[ONBOARDING_OFFER_CONTROL_VARIANT]: `When this is the start of a new conversation and the user has not yet said what they want to build, welcome them as someone who is now connected to Clipform and offer to build their first form together, then offer these starting points as plain text: ${STARTERS}, or something else - ask which one fits, or invite them to describe what they need instead. If the user's first message already states what they want to build, even loosely, skip that offer entirely and go straight into the brief-driven flow below.`
|
|
16093
16107
|
};
|
|
16094
16108
|
function buildOnboardingOffer(variant = ONBOARDING_OFFER_CONTROL_VARIANT) {
|
|
16095
16109
|
return ONBOARDING_OFFER_COPY[variant] ?? ONBOARDING_OFFER_COPY[ONBOARDING_OFFER_CONTROL_VARIANT];
|
|
16096
16110
|
}
|
|
16097
|
-
var ONBOARDING_OFFER_TOOL_CUE =
|
|
16111
|
+
var ONBOARDING_OFFER_TOOL_CUE = `If the user hasn't said what to build yet, offer to build their first form and suggest starting points: ${STARTERS}, or something else.`;
|
|
16098
16112
|
|
|
16099
16113
|
// src/lib/config.ts
|
|
16100
16114
|
var _endScreen = NODE_TYPES.end_screen.config_schema.properties;
|
|
@@ -16336,6 +16350,18 @@ var formIdTargetInput = external_exports.string().uuid().optional().describe(
|
|
|
16336
16350
|
"The form this is for (from clipform_create_form) - a routing hint only, to pick the right workspace. The result still lands in the workspace library, not on a node. Required on an anonymous session, or this lands in a different workspace and clipform_attach_node_media will not find it."
|
|
16337
16351
|
);
|
|
16338
16352
|
|
|
16353
|
+
// src/lib/links.ts
|
|
16354
|
+
var LINK_LABELS = {
|
|
16355
|
+
preview: "Preview your form",
|
|
16356
|
+
claim: "Sign up to keep this form (one-time link)",
|
|
16357
|
+
share: "Share link",
|
|
16358
|
+
edit: "Edit in Clipform",
|
|
16359
|
+
responses: "View responses"
|
|
16360
|
+
};
|
|
16361
|
+
function mdLink(label, url2) {
|
|
16362
|
+
return `[${label}](${url2})`;
|
|
16363
|
+
}
|
|
16364
|
+
|
|
16339
16365
|
// src/tools/create-form.ts
|
|
16340
16366
|
function registerCreateFormTool(server) {
|
|
16341
16367
|
server.registerTool(
|
|
@@ -16513,11 +16539,11 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
16513
16539
|
`Node IDs (use directly with attach_node_media / update_node - no get_form round-trip needed):`,
|
|
16514
16540
|
...createdNodes.map((n) => `- [${n.type}] "${truncate2(n.prompt)}": ${n.id}`),
|
|
16515
16541
|
``,
|
|
16516
|
-
isPreview ? `PREVIEW URL (draft - answers are not saved, only you can open this, not for respondents): ${data.viewer_url}` : `FORM URL (live - share this with respondents): ${data.viewer_url}`
|
|
16542
|
+
isPreview ? `PREVIEW URL (draft - answers are not saved, only you can open this, not for respondents): ${mdLink(LINK_LABELS.preview, String(data.viewer_url))}` : `FORM URL (live - share this with respondents): ${mdLink(LINK_LABELS.share, String(data.viewer_url))}`
|
|
16517
16543
|
];
|
|
16518
16544
|
if (formUrl) {
|
|
16519
16545
|
lines.push(
|
|
16520
|
-
isPreview ? `CLAIM URL (fallback - or open this one-time link to sign up in the browser): ${formUrl}` : `DASHBOARD URL (sign in to edit and manage): ${formUrl}`
|
|
16546
|
+
isPreview ? `CLAIM URL (fallback - or open this one-time link to sign up in the browser): ${mdLink(LINK_LABELS.claim, formUrl)}` : `DASHBOARD URL (sign in to edit and manage): ${mdLink(LINK_LABELS.edit, formUrl)}`
|
|
16521
16547
|
);
|
|
16522
16548
|
}
|
|
16523
16549
|
if (ignoredNotes.length > 0) lines.push(``, ...ignoredNotes);
|
|
@@ -16526,7 +16552,7 @@ Example: A form that asks a question, collects contact info, then finishes:
|
|
|
16526
16552
|
lines.push(
|
|
16527
16553
|
``,
|
|
16528
16554
|
isPreview ? `This form is a preview, not live. When the user says "publish it", call clipform_update_form (is_live: true); it prompts them to sign in. The PREVIEW URL never becomes public on its own.` : `The form is live and accessible at the FORM URL above. Edits and media attached AFTER this point are NOT visible to respondents until you re-send is_live: true via clipform_update_form - republishing is the expected final step of a build, never skip it after attaching media/narration.`,
|
|
16529
|
-
formUrl ? `The URLs above are exact values; constructed or guessed URLs return 404. Use the ${firstUrlLabel} URL and ${secondUrlLabel} URL as shown.` : `The ${firstUrlLabel} URL above is an exact value; constructed or guessed URLs return 404.`,
|
|
16555
|
+
formUrl ? `The URLs above are exact values; constructed or guessed URLs return 404. Use the ${firstUrlLabel} URL and ${secondUrlLabel} URL as shown, keeping each link's label rather than pasting the bare URL.` : `The ${firstUrlLabel} URL above is an exact value; constructed or guessed URLs return 404. Keep the link's label rather than pasting the bare URL.`,
|
|
16530
16556
|
`Pass form_id on follow-up tools (get_form, add_node, attach_node_media, etc.).`
|
|
16531
16557
|
);
|
|
16532
16558
|
const anonNotice = isPreview ? anonPreviewNotice() : null;
|
|
@@ -16694,7 +16720,7 @@ function registerImportFormTool(server) {
|
|
|
16694
16720
|
"clipform_import_form",
|
|
16695
16721
|
{
|
|
16696
16722
|
title: "Import Form",
|
|
16697
|
-
description:
|
|
16723
|
+
description: `${IMPORT_FORM_LEAD} Supported URLs: Google Forms (docs.google.com or forms.gle - must be shared as "Anyone with the link"), Typeform (form.typeform.com/to/...), and Tally (tally.so - must be public). The source form must be publicly accessible; a private form's questions cannot be read. The new Clipform is created as a DRAFT - review it, then republish with clipform_update_form (is_live: true) once it's ready. Some question types don't map cleanly to a Clipform node and are skipped rather than guessed at; the result always reports exactly what was imported vs skipped, and why.`,
|
|
16698
16724
|
inputSchema: external_exports.object({
|
|
16699
16725
|
workspace_id: workspaceIdInput,
|
|
16700
16726
|
url: external_exports.string().url().describe("Public URL of the Google Form, Typeform, or Tally form to import")
|
|
@@ -17006,12 +17032,12 @@ function formatFormState(data) {
|
|
|
17006
17032
|
lines.push(``, `Links (exact values - constructed or guessed URLs return 404):`);
|
|
17007
17033
|
if (urls.viewer) {
|
|
17008
17034
|
lines.push(
|
|
17009
|
-
isPreviewViewerUrl(urls.viewer) ? ` ${ANON_PREVIEW_LINK_LABEL}: ${urls.viewer}` : ` Viewer (respondent view): ${urls.viewer}`
|
|
17035
|
+
isPreviewViewerUrl(urls.viewer) ? ` ${ANON_PREVIEW_LINK_LABEL}: ${mdLink(LINK_LABELS.preview, urls.viewer)}` : ` Viewer (respondent view): ${mdLink(LINK_LABELS.share, urls.viewer)}`
|
|
17010
17036
|
);
|
|
17011
17037
|
}
|
|
17012
|
-
if (urls.builder) lines.push(` Builder: ${urls.builder}`);
|
|
17038
|
+
if (urls.builder) lines.push(` Builder: ${mdLink(LINK_LABELS.edit, urls.builder)}`);
|
|
17013
17039
|
if (urls.summary) lines.push(` Summary: ${urls.summary}`);
|
|
17014
|
-
if (urls.responses) lines.push(` Responses: ${urls.responses}`);
|
|
17040
|
+
if (urls.responses) lines.push(` Responses: ${mdLink(LINK_LABELS.responses, urls.responses)}`);
|
|
17015
17041
|
if (urls.analytics) lines.push(` Analytics: ${urls.analytics}`);
|
|
17016
17042
|
if (urls.share) lines.push(` Share: ${urls.share}`);
|
|
17017
17043
|
if (urls.embed) lines.push(` Embed: ${urls.embed}`);
|
|
@@ -17256,8 +17282,8 @@ function registerUpdateFormTool(server) {
|
|
|
17256
17282
|
if (viewerUrl) {
|
|
17257
17283
|
resultText += `
|
|
17258
17284
|
|
|
17259
|
-
Your form is live at: ${viewerUrl}
|
|
17260
|
-
Share this URL with respondents. View responses any time with clipform_get_results (form_id: ${form_id})${responsesUrl ? `, or in the dashboard: ${responsesUrl}` : ""}`;
|
|
17285
|
+
Your form is live at: ${mdLink(LINK_LABELS.share, viewerUrl)}
|
|
17286
|
+
Share this URL with respondents. View responses any time with clipform_get_results (form_id: ${form_id})${responsesUrl ? `, or in the dashboard: ${mdLink(LINK_LABELS.responses, responsesUrl)}` : ""}`;
|
|
17261
17287
|
}
|
|
17262
17288
|
}
|
|
17263
17289
|
const anonNotice = anonPreviewNotice();
|
|
@@ -20083,13 +20109,14 @@ var MCP_SERVER_CARD_IDENTITY = Object.freeze({
|
|
|
20083
20109
|
});
|
|
20084
20110
|
function buildInstructions(caps) {
|
|
20085
20111
|
return [
|
|
20112
|
+
INSTRUCTIONS_LEAD,
|
|
20086
20113
|
buildOnboardingOffer(),
|
|
20087
|
-
"
|
|
20114
|
+
"When the brief is clear, build the form directly; when it's vague, ask one or two short questions first.",
|
|
20088
20115
|
caps.media && "Prefer rich media: video over images over plain text.",
|
|
20089
20116
|
caps.media ? "Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every rendering choice - narration tone, motion preset, music, pacing. Never mix registers in one form." : "Before building, derive a register from the topic and audience (e.g. hype, playful, warm, considered, elegant, sombre); if the user states a mood explicitly, that wins. State the register once, then apply it to every question, option, and end-screen line. Never mix registers in one form.",
|
|
20090
20117
|
"At the start of a build, call clipform_get_workflow to load the recipe for the form type, and clipform_get_guide for craft detail.",
|
|
20091
20118
|
"Every *_id argument is a UUID returned by the tools - not the short share_id from a form URL.",
|
|
20092
|
-
"
|
|
20119
|
+
"Use clipform_whoami when the request is about the account itself (the active workspace, plan, or limits); building a form does not need it first.",
|
|
20093
20120
|
caps.media ? "Deleting a form moves it to the trash (restorable from the dashboard); deleting a node cannot be undone (a node deleted on a live form stays on the live form until you publish); removing media from a node only unlinks it, and the media asset stays in the library. Those tools ask the user to confirm before running." : "Deleting a form moves it to the trash (restorable from the dashboard); deleting a node cannot be undone (on a live form it stays on the live form until you publish). Those tools ask the user to confirm before running."
|
|
20094
20121
|
].filter((line) => typeof line === "string").join(" ");
|
|
20095
20122
|
}
|
|
@@ -20263,4 +20290,4 @@ export {
|
|
|
20263
20290
|
* MIT Licensed
|
|
20264
20291
|
*)
|
|
20265
20292
|
*/
|
|
20266
|
-
//# sourceMappingURL=chunk-
|
|
20293
|
+
//# sourceMappingURL=chunk-E2T3UTF3.js.map
|