@kolbo/mcp 1.86.0 → 1.86.4

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.
@@ -247,6 +247,21 @@ function registerProjectTools(server, client) {
247
247
  }
248
248
  );
249
249
 
250
+ // ─── duplicate_project ─────────────────────────────────────
251
+ server.tool(
252
+ 'duplicate_project',
253
+ 'Duplicate one of YOUR OWN projects into a new project you own. Use for a variant of an existing body of work ("make a Hebrew version of this", "branch this campaign") and BEFORE publishing a project publicly — duplicate it, strip what should stay private, and share the copy. Copies the cast (Visual DNAs, moodboards, palette), uploaded media, every tool session with its generations, Flow canvases, and — unlike a public fork — your AI Docs. Third-party stock and failed runs are kept too, since the copy never leaves your account. NOT copied: project context files, the derived AI profile, and chat sessions. In-flight generations are skipped (their provider job belongs to the original). Plan project limits apply.',
254
+ {
255
+ project_id: z.string().describe('ObjectId of a project you own, from list_projects.')
256
+ },
257
+ async ({ project_id }) => {
258
+ const result = await client.post(`/v1/projects/${encodeURIComponent(project_id)}/duplicate`, {});
259
+ const data = result.data || result;
260
+ const open_url = buildProjectUrl(data.projectId);
261
+ return { content: [{ type: 'text', text: JSON.stringify({ ...data, open_url, _hint: 'Use this NEW projectId as project_id for work on the copy. `stats.notCopied` lists what did not travel — say so rather than letting the user discover it.' }, null, 2) }] };
262
+ }
263
+ );
264
+
250
265
  // ─── get_project ───────────────────────────────────────────
251
266
  server.tool(
252
267
  'get_project',