lotux-mcp 0.25.0 → 0.27.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/package.json +1 -1
- package/tools.mjs +23 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lotux-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.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": {
|
package/tools.mjs
CHANGED
|
@@ -75,7 +75,7 @@ export function registerTools(server, rpc) {
|
|
|
75
75
|
|
|
76
76
|
server.tool(
|
|
77
77
|
"plan_items",
|
|
78
|
-
"Plan 1–60 items on ONE person's calendar on a date. With start_time they run back to back, each as long as that person's HR output allows (40 h ÷ weekly output; tasks 1 h); without start_time they land all-day. The person becomes the
|
|
78
|
+
"Plan 1–60 items on ONE person's calendar on a date. With start_time they run back to back, each as long as that person's HR output allows (40 h ÷ weekly output; tasks 1 h); without start_time they land all-day. The person becomes the maker (post: video editor on video concepts, static designer on statics) or media buyer (go_live); on a task they are added to the assignees. Planning concept blocks needs Creative edit rights. More than 10 items → returns a PREVIEW only and changes nothing: show the list, ask for a yes, then call apply_planning_preview. Never deletes anything.",
|
|
79
79
|
{
|
|
80
80
|
person: z.string().describe("id, name or 'me'"),
|
|
81
81
|
items: PLAN_ITEMS,
|
|
@@ -227,7 +227,7 @@ export function registerTools(server, rpc) {
|
|
|
227
227
|
|
|
228
228
|
server.tool(
|
|
229
229
|
"claim_work",
|
|
230
|
-
"Claim a piece of work before writing files for it. kind: concept (ref = concept id; prep / edit / revise / re-render one concept; 6 h), inventory (the brand's inventory run; 6 h), brand_shared (files several concepts of the brand use: logos, shared media, shared code; 15 min), house_rules (the shared house rules or style spec, agency-wide; 15 min). Returns {ok: true, claim_id, expires_at} or {ok: false, held_by, since, expires_at} when someone else holds it: then don't write, ask or wait. A concept claim warns when you're not its editor and sets you as
|
|
230
|
+
"Claim a piece of work before writing files for it. kind: concept (ref = concept id; prep / edit / revise / re-render one concept; 6 h), inventory (the brand's inventory run; 6 h), brand_shared (files several concepts of the brand use: logos, shared media, shared code; 15 min), house_rules (the shared house rules or style spec, agency-wide; 15 min). Returns {ok: true, claim_id, expires_at} or {ok: false, held_by, since, expires_at} when someone else holds it: then don't write, ask or wait. A concept claim warns when you're not its maker (video editor on video, static designer otherwise) and sets you as maker when it has none.",
|
|
231
231
|
{
|
|
232
232
|
account_id: z.string().describe("Brand id from list_brands (house_rules: any brand of the agency, or the agency)"),
|
|
233
233
|
kind: z.enum(["concept", "inventory", "brand_shared", "house_rules"]),
|
|
@@ -373,7 +373,7 @@ export function registerTools(server, rpc) {
|
|
|
373
373
|
|
|
374
374
|
server.tool(
|
|
375
375
|
"list_members",
|
|
376
|
-
"List the agency team members (id + name) assignable to a concept's roles. Use the ids with set_concept_fields (strategist_id, copy_checker_id, editor_id, media_buyer_id, final_check_id).",
|
|
376
|
+
"List the agency team members (id + name) assignable to a concept's roles. Use the ids with set_concept_fields (strategist_id, copy_checker_id, editor_id = video editor, designer_id = static designer, media_buyer_id, final_check_id).",
|
|
377
377
|
{ account_id: z.string().describe("Brand id from list_brands") },
|
|
378
378
|
async ({ account_id }) => ok(await rpc("list_members", { account_id }))
|
|
379
379
|
);
|
|
@@ -403,7 +403,7 @@ export function registerTools(server, rpc) {
|
|
|
403
403
|
|
|
404
404
|
server.tool(
|
|
405
405
|
"set_concept_fields",
|
|
406
|
-
"Update fields on an existing concept — including renaming it via title. Any omitted field is left unchanged; the id arrays, when given, replace the full set of links. Assign team roles by passing a person id from list_members into strategist_id / copy_checker_id / editor_id / media_buyer_id / final_check_id.",
|
|
406
|
+
"Update fields on an existing concept — including renaming it via title. Any omitted field is left unchanged; the id arrays, when given, replace the full set of links. Assign team roles by passing a person id from list_members into strategist_id / copy_checker_id / editor_id (video editor) / designer_id (static designer) / media_buyer_id / final_check_id.",
|
|
407
407
|
{
|
|
408
408
|
concept_id: z.string(),
|
|
409
409
|
title: z.string().optional().describe("Rename the concept (blank is ignored — title is required)"),
|
|
@@ -443,7 +443,8 @@ export function registerTools(server, rpc) {
|
|
|
443
443
|
// Team roles — pass a member id from list_members.
|
|
444
444
|
strategist_id: z.string().optional().describe("Member id from list_members"),
|
|
445
445
|
copy_checker_id: z.string().optional().describe("Member id from list_members"),
|
|
446
|
-
editor_id: z.string().optional().describe("
|
|
446
|
+
editor_id: z.string().optional().describe("Video editor: member id from list_members"),
|
|
447
|
+
designer_id: z.string().optional().describe("Static designer: member id from list_members"),
|
|
447
448
|
media_buyer_id: z.string().optional().describe("Member id from list_members"),
|
|
448
449
|
final_check_id: z.string().optional().describe("Member id from list_members"),
|
|
449
450
|
},
|
|
@@ -701,6 +702,15 @@ export function registerTools(server, rpc) {
|
|
|
701
702
|
|
|
702
703
|
// ── Kennisbank (knowledge base) ─────────────────────────────────────────────────
|
|
703
704
|
|
|
705
|
+
// How a Second Brain page's markdown is laid out — the app renders these.
|
|
706
|
+
const KB_FORMAT =
|
|
707
|
+
" Page markdown supports, besides normal markdown (headings, lists, tables, --- dividers, images): " +
|
|
708
|
+
"fenced blocks the app renders as page blocks — ```cards (one card per line: Label | Title | Text), " +
|
|
709
|
+
"```stats (Value | Label | Note), ```steps (Title | Text), ```callout (first line = title, the rest = body), " +
|
|
710
|
+
"```buttons (Label | link), ```mermaid (a Mermaid diagram). Any of those may start with a line " +
|
|
711
|
+
"`tone: gray|yellow|blue|green|red|purple|ink` for its colour. Link to another page with a normal markdown link " +
|
|
712
|
+
"to /brain/second-brain?ws=<workspace id>&doc=<page id>.";
|
|
713
|
+
|
|
704
714
|
server.tool(
|
|
705
715
|
"list_kb_workspaces",
|
|
706
716
|
"List the Kennisbank (knowledge base) workspaces you can access — markdown docs the team and AI share. Returns id, name, visibility. Use a workspace id with list_kb_docs / create_kb_doc. Only each workspace's \"Exposed to MCP\" section is visible to the MCP; the rest is the team's own notes.",
|
|
@@ -710,37 +720,41 @@ export function registerTools(server, rpc) {
|
|
|
710
720
|
|
|
711
721
|
server.tool(
|
|
712
722
|
"list_kb_docs",
|
|
713
|
-
"List the pages in a Kennisbank workspace's \"Exposed to MCP\" section (id, title, folder path inside the section; \"\" = its top level). Pages outside the section are not listed. Use a doc id with get_kb_doc.",
|
|
723
|
+
"List the pages in a Kennisbank workspace's \"Exposed to MCP\" section (id, title, folder path inside the section; \"\" = its top level; tags; date). Pages outside the section are not listed. Use a doc id with get_kb_doc.",
|
|
714
724
|
{ workspace_id: z.string().describe("Workspace id from list_kb_workspaces") },
|
|
715
725
|
async ({ workspace_id }) => ok(await rpc("list_kb_docs", { workspace_id }))
|
|
716
726
|
);
|
|
717
727
|
|
|
718
728
|
server.tool(
|
|
719
729
|
"get_kb_doc",
|
|
720
|
-
"Read one Kennisbank page
|
|
730
|
+
"Read one Kennisbank page by id: title, author, date, tags, full markdown content and linked_pages (the pages it links to; a linked page outside an \"Exposed to MCP\" section shows only its id with exposed: false). Only pages in the \"Exposed to MCP\" section can be read." + KB_FORMAT,
|
|
721
731
|
{ doc_id: z.string() },
|
|
722
732
|
async ({ doc_id }) => ok(await rpc("get_kb_doc", { doc_id }))
|
|
723
733
|
);
|
|
724
734
|
|
|
725
735
|
server.tool(
|
|
726
736
|
"create_kb_doc",
|
|
727
|
-
"Create a new markdown page in a Kennisbank workspace's \"Exposed to MCP\" section. Returns the new doc id. content is markdown; folder_id is optional (top of the section if omitted) and must be a folder from list_kb_folders.",
|
|
737
|
+
"Create a new markdown page in a Kennisbank workspace's \"Exposed to MCP\" section. Returns the new doc id. content is markdown; folder_id is optional (top of the section if omitted) and must be a folder from list_kb_folders. You become the page's author." + KB_FORMAT,
|
|
728
738
|
{
|
|
729
739
|
workspace_id: z.string().describe("Workspace id from list_kb_workspaces"),
|
|
730
740
|
title: z.string(),
|
|
731
741
|
content: z.string().optional().describe("Markdown body"),
|
|
732
742
|
folder_id: z.string().optional(),
|
|
743
|
+
tags: z.array(z.string()).optional().describe("Page tags"),
|
|
744
|
+
date: z.string().optional().describe("Page date, YYYY-MM-DD (default: today)"),
|
|
733
745
|
},
|
|
734
746
|
async (args) => ok(await rpc("create_kb_doc", args))
|
|
735
747
|
);
|
|
736
748
|
|
|
737
749
|
server.tool(
|
|
738
750
|
"update_kb_doc",
|
|
739
|
-
"Update a Kennisbank page's title and/or
|
|
751
|
+
"Update a Kennisbank page's title, markdown content, tags and/or date (pages in the \"Exposed to MCP\" section only). Omitted fields are left unchanged." + KB_FORMAT,
|
|
740
752
|
{
|
|
741
753
|
doc_id: z.string(),
|
|
742
754
|
title: z.string().optional(),
|
|
743
755
|
content: z.string().optional().describe("Markdown body (replaces the page content)"),
|
|
756
|
+
tags: z.array(z.string()).optional().describe("Replaces the page's tags"),
|
|
757
|
+
date: z.string().nullable().optional().describe("Page date YYYY-MM-DD; null = back to the created date"),
|
|
744
758
|
},
|
|
745
759
|
async (args) => ok(await rpc("update_kb_doc", args))
|
|
746
760
|
);
|