lotux-mcp 0.8.0 → 0.10.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.
Files changed (3) hide show
  1. package/README.md +2 -1
  2. package/index.mjs +31 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -64,7 +64,8 @@ Restart Claude, then try: *"list my LOTUX brands"*.
64
64
  | `iterate_concept` | Spawn a variation ({root}_Var{n}), the same as the app's Iterate button |
65
65
  | `list_kb_*` / `get_kb_doc` / `create_kb_doc` / `update_kb_doc` | Kennisbank pages |
66
66
  | `content_options` / `create_flywheel` / `update_flywheel` / `list_flywheels` / `get_flywheel` | Content flywheels (Marketing → Content, agency-only): one long-form video. Start with `content_options`; give flywheels a `key` so re-runs reuse them |
67
- | `push_assets` / `add_asset` / `get_asset` / `list_assets` / `update_asset` / `set_asset_status` / `add_comment` / `delete_asset` | Content assets, upserted on their `key`. Statuses: scripting → production → post_production → to_review → revisions → approved → live. Content you write lands in `to_review`; Claude can't set revisions, approve or mark live; deleting signed-off work needs `force` |
67
+ | `push_assets` / `add_asset` / `get_asset` / `list_assets` / `update_asset` / `set_asset_status` / `add_comment` / `delete_asset` | Content assets, upserted on their `key`. Statuses: scripting → production → post_production → to_review → revisions → approved → live. Content you write lands in `to_review`; Claude can't set revisions, approve or mark live; deleting signed-off work needs `force`. Each asset carries `raw_footage_url` (raw files folder) and `final_asset_url` (the export — a change sends it to review), plus its content ID (`code`) and `name` = `"<code> - <title>"`; pass `code` instead of `asset_id` anywhere |
68
+ | `get_setup_checks` / `set_setup_check` | A flywheel's setup checklist (Instagram auto-replies, setter replies, reel covers, YouTube, Klaviyo flow) — tick a step by `check_key` after doing it |
68
69
 
69
70
  Beats (`add_beat`, `update_beat`, `delete_beat`, `set_beat_translation`, `add_language`) were
70
71
  retired in Sep 2026 — scripts are documents now. Calling one returns a message pointing at the
package/index.mjs CHANGED
@@ -52,7 +52,7 @@ const ok = (result) => ({
52
52
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
53
53
  });
54
54
 
55
- const server = new McpServer({ name: "lotux", version: "0.8.0" });
55
+ const server = new McpServer({ name: "lotux", version: "0.10.0" });
56
56
 
57
57
  // ── Reads ─────────────────────────────────────────────────────────────────────
58
58
 
@@ -481,6 +481,7 @@ const flywheelRef = {
481
481
  };
482
482
  const assetRef = {
483
483
  asset_id: z.string().optional(),
484
+ code: z.union([z.string(), z.number()]).optional().describe('The content ID ("57") instead of asset_id'),
484
485
  key: z.string().optional().describe("The asset's key — with flywheel_id or flywheel_key — instead of asset_id"),
485
486
  ...flywheelRef,
486
487
  };
@@ -503,8 +504,11 @@ const assetFields = {
503
504
  body: z.string().optional().describe("Markdown content. long_form: YouTube description + chapters"),
504
505
  attachments: z.array(attachment).optional().describe("Replaces all links (Figma, Drive, Dropbox…)"),
505
506
  cover_url: z.string().optional().describe("long_form: thumbnail · clip / creator_video: reel cover"),
507
+ raw_footage_url: z.string().optional().describe("Folder with the raw footage this piece is cut from (Dropbox / Drive). Several assets may share one"),
508
+ final_asset_url: z.string().optional().describe("The exported deliverable (file or folder link). Signed off with the asset"),
506
509
  published_url: z.string().optional(),
507
510
  notes: z.string().optional(),
511
+ klaviyo_message_id: z.string().optional().describe("Email cards: the Klaviyo flow message id this card became (after the flow is built)"),
508
512
  };
509
513
 
510
514
  server.tool(
@@ -547,6 +551,8 @@ server.tool(
547
551
  transcript: z.string().optional(),
548
552
  notes: z.string().optional(),
549
553
  new_key: z.string().optional().describe("Give the flywheel a (new) key"),
554
+ klaviyo_flow_id: z.string().optional().describe("The Klaviyo flow built for this video (LM · <key>) — ticks the Klaviyo flow setup check"),
555
+ klaviyo_campaign_id: z.string().optional().describe("The Klaviyo keep-warm campaign — ticks the keep-warm setup check"),
550
556
  account_id: z.string().optional(),
551
557
  },
552
558
  async (args) => ok(await rpc("update_flywheel", args))
@@ -578,7 +584,7 @@ server.tool(
578
584
 
579
585
  server.tool(
580
586
  "push_assets",
581
- "Push many assets into a flywheel in one call (max 100). Each item is upserted on its `key`: new keys are created (asset_type + title required), existing keys are updated with only the fields you send. Content lands in to_review. Returns counts + per-item { key, id, created, status, link, warnings } or { key, error }.",
587
+ "Push many assets into a flywheel in one call (max 100). Each item is upserted on its `key`: new keys are created (asset_type + title required), existing keys are updated with only the fields you send. Content lands in to_review. Every piece gets a content ID; its name is \"<code> - <title>\" (use it for file names). Returns counts + per-item { key, id, code, name, created, status, link, warnings } or { key, error }.",
582
588
  {
583
589
  ...flywheelRef,
584
590
  assets: z.array(z.object({ key: z.string().optional(), ...assetFields })).max(100),
@@ -601,7 +607,7 @@ server.tool(
601
607
 
602
608
  server.tool(
603
609
  "get_asset",
604
- "One asset in full — body, attachments, cover/thumbnail, resolved link, warnings — plus its activity (status changes and comments, newest first). Use it to read what a human asked to change.",
610
+ "One asset in full — body, attachments, cover/thumbnail, raw footage + final asset links, resolved link, warnings — plus its activity (status changes and comments, newest first). Use it to read what a human asked to change.",
605
611
  { ...assetRef, account_id: z.string().optional() },
606
612
  async (args) => ok(await rpc("get_asset", args))
607
613
  );
@@ -612,6 +618,7 @@ server.tool(
612
618
  {
613
619
  ...flywheelRef,
614
620
  key: z.string().optional(),
621
+ code: z.union([z.string(), z.number()]).optional().describe('A content ID ("57")'),
615
622
  asset_type: z.array(z.enum(ASSET_TYPES)).optional(),
616
623
  status: z.array(z.enum(STATUSES)).optional(),
617
624
  platform: z.array(z.enum(PLATFORMS)).optional().describe("Matches the main platform or a cross-post"),
@@ -629,7 +636,7 @@ server.tool(
629
636
 
630
637
  server.tool(
631
638
  "update_asset",
632
- "Update an asset by asset_id (or flywheel + key). Changing body, attachments or cover_url moves it to to_review (even if it was approved) so a human signs it off. Omitted fields are left unchanged.",
639
+ "Update an asset by asset_id (or flywheel + key). Changing body, attachments, cover_url or final_asset_url moves it to to_review (even if it was approved) so a human signs it off. Omitted fields are left unchanged.",
633
640
  {
634
641
  ...assetRef,
635
642
  ...assetFields,
@@ -666,6 +673,26 @@ server.tool(
666
673
  async (args) => ok(await rpc("delete_asset", args))
667
674
  );
668
675
 
676
+ server.tool(
677
+ "get_setup_checks",
678
+ "A flywheel's setup checklist: the steps outside LOTUX (Instagram auto-reply per lead-magnet DM keyword, setter saved reply per booking keyword, reel covers, YouTube scheduling, the Klaviyo flow + keep-warm campaign). Each with check_key, status (open / done / n_a), due date, owner, and whether LOTUX ticks it itself (auto).",
679
+ { ...flywheelRef, account_id: z.string().optional() },
680
+ async (args) => ok(await rpc("get_setup_checks", args))
681
+ );
682
+
683
+ server.tool(
684
+ "set_setup_check",
685
+ "Tick a setup step after you did it (e.g. check_key \"dm-keyword:EXIT\" once the Instagram auto-reply is set up AND tested). status done / open / n_a, plus an optional note. Auto checks (klaviyo-*) tick themselves. Logged as done by Claude.",
686
+ {
687
+ ...flywheelRef,
688
+ check_key: z.string().describe('From get_setup_checks, e.g. "dm-keyword:EXIT", "reel-covers", "youtube"'),
689
+ status: z.enum(["open", "done", "n_a"]).optional(),
690
+ note: z.string().optional(),
691
+ account_id: z.string().optional(),
692
+ },
693
+ async (args) => ok(await rpc("set_setup_check", args))
694
+ );
695
+
669
696
  async function main() {
670
697
  const transport = new StdioServerTransport();
671
698
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lotux-mcp",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "description": "Local MCP server that lets Claude create LOTUX concepts (fetch brand-DB entities, create concepts, fill scripts + copy). Talks to the LOTUX app with a personal token; no business logic or secrets live here.",
6
6
  "bin": {