@astramindapp/mcp-server 0.7.0 → 0.8.2

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/dist/server.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * Exposes the MIND knowledge graph as MCP tools that any LLM agent can use.
6
6
  * This is the universal AI memory layer.
7
7
  *
8
- * Tools (16):
8
+ * Tools (17):
9
9
  * mind_query — Semantic search across the knowledge graph
10
10
  * mind_remember — Store/manage content in the graph (auto-categorized)
11
11
  * mind_context — Get structured always-loaded context (soul/user/rules)
@@ -23,6 +23,8 @@
23
23
  * mind_notify — Notifications management
24
24
  * mind_agents — Admin-only Agent Command Center (registry, heartbeat,
25
25
  * probe, status — for Anthony's agent fleet)
26
+ * mind_accounts — Multi-MIND accounts: discover/create MINDs, manage
27
+ * owners and viewers, send invitations
26
28
  */
27
29
  Object.defineProperty(exports, "__esModule", { value: true });
28
30
  exports.createMindMcpServer = createMindMcpServer;
@@ -292,11 +294,11 @@ function createMindMcpServer(client) {
292
294
  server.tool("mind_life", "Manage goals, projects, tasks, and calendar events in MIND Life. Use for tracking work, creating action items, updating progress, completing tasks, managing calendar, and viewing stats.", {
293
295
  action: zod_1.z
294
296
  .enum([
295
- "list", "create", "update", "complete", "delete", "move", "get",
297
+ "list", "create", "update", "complete", "delete", "bulk_delete", "move", "get",
296
298
  "calendar_list", "calendar_create", "calendar_update", "calendar_delete",
297
299
  "stats",
298
300
  ])
299
- .describe("What to do: list/create/update/complete/delete/move/get items, calendar_list/calendar_create/calendar_update/calendar_delete events, stats (productivity overview)"),
301
+ .describe("What to do: list/create/update/complete/delete/bulk_delete/move/get items, calendar_list/calendar_create/calendar_update/calendar_delete events, stats (productivity overview)"),
300
302
  title: zod_1.z.string().optional().describe("Title for new items or calendar events"),
301
303
  description: zod_1.z.string().optional().describe("Description for new items"),
302
304
  status: zod_1.z
@@ -309,11 +311,12 @@ function createMindMcpServer(client) {
309
311
  .describe("Priority: low, medium, high, urgent"),
310
312
  due_date: zod_1.z.string().optional().describe("Due date in YYYY-MM-DD format"),
311
313
  item_id: zod_1.z.string().optional().describe("Item ID for update/complete/delete/move/get actions"),
314
+ item_ids: zod_1.z.array(zod_1.z.string()).optional().describe("Item IDs for bulk_delete (1–200 IDs deleted in one call)"),
312
315
  start_time: zod_1.z.string().optional().describe("Start time for calendar events (ISO 8601)"),
313
316
  end_time: zod_1.z.string().optional().describe("End time for calendar events (ISO 8601)"),
314
317
  event_id: zod_1.z.string().optional().describe("Event ID for calendar_update/calendar_delete"),
315
318
  all_day: zod_1.z.boolean().optional().describe("Whether the calendar event is all-day"),
316
- }, async ({ action, title, description, status, priority, due_date, item_id, start_time, end_time, event_id, all_day }) => {
319
+ }, async ({ action, title, description, status, priority, due_date, item_id, item_ids, start_time, end_time, event_id, all_day }) => {
317
320
  try {
318
321
  switch (action) {
319
322
  case "list": {
@@ -395,6 +398,22 @@ function createMindMcpServer(client) {
395
398
  content: [{ type: "text", text: `✅ Deleted life item ${item_id}` }],
396
399
  };
397
400
  }
401
+ case "bulk_delete": {
402
+ if (!item_ids || item_ids.length === 0) {
403
+ return {
404
+ content: [{ type: "text", text: "Error: item_ids (a non-empty array of IDs) is required for bulk_delete" }],
405
+ isError: true,
406
+ };
407
+ }
408
+ const result = await client.bulkDeleteLifeItems(item_ids);
409
+ const lines = [
410
+ `✅ Bulk delete complete — ${result.deleted_count} life item(s) deleted.`,
411
+ ];
412
+ if (result.not_found.length > 0) {
413
+ lines.push(`⚠️ ${result.not_found.length} id(s) skipped (not found / not yours): ${result.not_found.join(", ")}`);
414
+ }
415
+ return { content: [{ type: "text", text: lines.join("\n") }] };
416
+ }
398
417
  case "move": {
399
418
  if (!item_id || !status) {
400
419
  return {
@@ -512,6 +531,212 @@ function createMindMcpServer(client) {
512
531
  };
513
532
  }
514
533
  });
534
+ // ─── mind_tasks ─────────────────────────────────────────
535
+ // Site-wide tasks: assignable, completable work items that attach to a
536
+ // Life project, a CRM contact, an agent, or stand alone.
537
+ server.tool("mind_tasks", "Manage site-wide tasks in MIND — assignable, completable, reportable work items. A task can attach to a Life project (parent_type=life_item), a CRM contact (parent_type=contact), an agent (parent_type=agent), or stand alone. Assign tasks to a MIND member, an agent, or an external email. Use action=reports for completion analytics.", {
538
+ action: zod_1.z
539
+ .enum([
540
+ "list", "create", "get", "update", "complete", "reopen",
541
+ "assign", "delete", "reports",
542
+ ])
543
+ .describe("What to do: list/create/get/update/complete/reopen/assign/delete tasks, or reports (completion analytics)"),
544
+ task_id: zod_1.z.string().optional().describe("Task ID — required for get/update/complete/reopen/assign/delete"),
545
+ title: zod_1.z.string().optional().describe("Task title (required for create)"),
546
+ description: zod_1.z.string().optional().describe("Task description"),
547
+ status: zod_1.z.string().optional().describe("Filter (list) or new status: open, in_progress, blocked, done"),
548
+ priority: zod_1.z.string().optional().describe("Priority: none, low, medium, high, urgent"),
549
+ due_date: zod_1.z.string().optional().describe("Due date YYYY-MM-DD"),
550
+ parent_type: zod_1.z.string().optional().describe("Attach to: life_item, contact, agent, or none"),
551
+ parent_id: zod_1.z.string().optional().describe("ID of the parent project / contact / agent"),
552
+ assignee_type: zod_1.z.string().optional().describe("Assignee: user, agent, external, or unassigned"),
553
+ assignee_id: zod_1.z.string().optional().describe("Username, agent slug, or email of the assignee"),
554
+ dispatch_agent: zod_1.z.boolean().optional().describe("When assigning to an agent, also fire it now"),
555
+ note: zod_1.z.string().optional().describe("Completion note (for complete)"),
556
+ overdue: zod_1.z.boolean().optional().describe("List only overdue tasks"),
557
+ }, async ({ action, task_id, title, description, status, priority, due_date, parent_type, parent_id, assignee_type, assignee_id, dispatch_agent, note, overdue }) => {
558
+ try {
559
+ const fmt = (t) => `• [${t.status}] ${t.title}${t.priority && t.priority !== "none" ? ` (${t.priority})` : ""}` +
560
+ `${t.due_date ? `, due ${t.due_date}` : ""}${t.is_overdue ? " ⚠️ OVERDUE" : ""}` +
561
+ `${t.assignee_label ? `, → ${t.assignee_label}` : ""}` +
562
+ `${t.parent_label ? `, on ${t.parent_label}` : ""} — id: ${t.task_id}`;
563
+ switch (action) {
564
+ case "list": {
565
+ const params = {};
566
+ if (status)
567
+ params.status = status;
568
+ if (priority)
569
+ params.priority = priority;
570
+ if (parent_type)
571
+ params.parent_type = parent_type;
572
+ if (parent_id)
573
+ params.parent_id = parent_id;
574
+ if (assignee_type)
575
+ params.assignee_type = assignee_type;
576
+ if (assignee_id)
577
+ params.assignee_id = assignee_id;
578
+ if (overdue)
579
+ params.overdue = "true";
580
+ const result = await client.listTasks(params);
581
+ const tasks = result.tasks ?? [];
582
+ if (tasks.length === 0) {
583
+ return { content: [{ type: "text", text: "No tasks found." }] };
584
+ }
585
+ return {
586
+ content: [{
587
+ type: "text",
588
+ text: `${result.total} task(s):\n` + tasks.map(fmt).join("\n"),
589
+ }],
590
+ };
591
+ }
592
+ case "create": {
593
+ if (!title) {
594
+ return {
595
+ content: [{ type: "text", text: "Error: title is required to create a task" }],
596
+ isError: true,
597
+ };
598
+ }
599
+ const t = await client.createTask({
600
+ title, description, status, priority, due_date,
601
+ parent_type, parent_id, assignee_type, assignee_id,
602
+ dispatch_agent,
603
+ });
604
+ return {
605
+ content: [{ type: "text", text: `✅ Created task: ${fmt(t)}` }],
606
+ };
607
+ }
608
+ case "get": {
609
+ if (!task_id) {
610
+ return {
611
+ content: [{ type: "text", text: "Error: task_id is required for get" }],
612
+ isError: true,
613
+ };
614
+ }
615
+ const t = await client.getTask(task_id);
616
+ const extra = t.agent_run_status ? `\nAgent run: ${t.agent_run_status}` : "";
617
+ return {
618
+ content: [{
619
+ type: "text",
620
+ text: `${fmt(t)}${t.description ? `\n${t.description}` : ""}${extra}`,
621
+ }],
622
+ };
623
+ }
624
+ case "update": {
625
+ if (!task_id) {
626
+ return {
627
+ content: [{ type: "text", text: "Error: task_id is required for update" }],
628
+ isError: true,
629
+ };
630
+ }
631
+ const patch = {};
632
+ if (title !== undefined)
633
+ patch.title = title;
634
+ if (description !== undefined)
635
+ patch.description = description;
636
+ if (status !== undefined)
637
+ patch.status = status;
638
+ if (priority !== undefined)
639
+ patch.priority = priority;
640
+ if (due_date !== undefined)
641
+ patch.due_date = due_date;
642
+ if (parent_type !== undefined)
643
+ patch.parent_type = parent_type;
644
+ if (parent_id !== undefined)
645
+ patch.parent_id = parent_id;
646
+ const t = await client.updateTask(task_id, patch);
647
+ return {
648
+ content: [{ type: "text", text: `✅ Updated task: ${fmt(t)}` }],
649
+ };
650
+ }
651
+ case "complete": {
652
+ if (!task_id) {
653
+ return {
654
+ content: [{ type: "text", text: "Error: task_id is required for complete" }],
655
+ isError: true,
656
+ };
657
+ }
658
+ const t = await client.completeTask(task_id, true, note);
659
+ return {
660
+ content: [{ type: "text", text: `✅ Completed task: "${t.title}"` }],
661
+ };
662
+ }
663
+ case "reopen": {
664
+ if (!task_id) {
665
+ return {
666
+ content: [{ type: "text", text: "Error: task_id is required for reopen" }],
667
+ isError: true,
668
+ };
669
+ }
670
+ const t = await client.completeTask(task_id, false);
671
+ return {
672
+ content: [{ type: "text", text: `↩️ Reopened task: "${t.title}"` }],
673
+ };
674
+ }
675
+ case "assign": {
676
+ if (!task_id || !assignee_type) {
677
+ return {
678
+ content: [{ type: "text", text: "Error: task_id and assignee_type are required for assign" }],
679
+ isError: true,
680
+ };
681
+ }
682
+ const t = await client.assignTask(task_id, {
683
+ assignee_type, assignee_id, dispatch_agent: dispatch_agent ?? false,
684
+ });
685
+ return {
686
+ content: [{
687
+ type: "text",
688
+ text: `✅ Assigned "${t.title}" → ${t.assignee_label ?? t.assignee_id ?? "unassigned"}`,
689
+ }],
690
+ };
691
+ }
692
+ case "delete": {
693
+ if (!task_id) {
694
+ return {
695
+ content: [{ type: "text", text: "Error: task_id is required for delete" }],
696
+ isError: true,
697
+ };
698
+ }
699
+ await client.deleteTask(task_id);
700
+ return {
701
+ content: [{ type: "text", text: `🗑️ Deleted task ${task_id}` }],
702
+ };
703
+ }
704
+ case "reports": {
705
+ const params = {};
706
+ if (parent_type)
707
+ params.parent_type = parent_type;
708
+ if (parent_id)
709
+ params.parent_id = parent_id;
710
+ const r = await client.taskReports(params);
711
+ const lines = [
712
+ `📊 Task report (${r.total} total)`,
713
+ ` open ${r.open} · in progress ${r.in_progress} · blocked ${r.blocked} · done ${r.done}`,
714
+ ` completion rate: ${r.completion_rate}%`,
715
+ ` overdue: ${r.overdue} · due soon: ${r.due_soon} · unassigned: ${r.unassigned}`,
716
+ ` avg completion: ${r.avg_completion_days} days`,
717
+ ];
718
+ if (r.by_assignee && r.by_assignee.length) {
719
+ lines.push(" By assignee:");
720
+ for (const a of r.by_assignee.slice(0, 10)) {
721
+ lines.push(` ${a.assignee_label ?? a.assignee_id ?? "unassigned"}: ${a.done}/${a.total} done (${a.completion_rate}%)`);
722
+ }
723
+ }
724
+ return { content: [{ type: "text", text: lines.join("\n") }] };
725
+ }
726
+ default:
727
+ return {
728
+ content: [{ type: "text", text: `Unknown action: ${action}` }],
729
+ isError: true,
730
+ };
731
+ }
732
+ }
733
+ catch (err) {
734
+ return {
735
+ content: [{ type: "text", text: `mind_tasks error: ${err instanceof Error ? err.message : String(err)}` }],
736
+ isError: true,
737
+ };
738
+ }
739
+ });
515
740
  // ─── mind_crm ───────────────────────────────────────────
516
741
  // Read/write contacts, interactions, and activities.
517
742
  // Enhanced: delete, get, log_activity, list_activities.
@@ -1936,8 +2161,12 @@ function createMindMcpServer(client) {
1936
2161
  "seed_known",
1937
2162
  "set_status",
1938
2163
  "set_current_job",
2164
+ "list_invoices",
2165
+ "link_invoice",
2166
+ "unlink_invoice",
2167
+ "create_invoice",
1939
2168
  ])
1940
- .describe("Action: list (filter+stats), get (detail+recent activities), create, update (partial), delete (soft archive; pass hard=true to remove), heartbeat (push from agent runtime), probe (HTTP/OpenClaw liveness probe), log_activity (manual note), list_activities, import_from_mind (enrich from agent-identity docs), seed_known (idempotent upsert of canonical seed), set_status (shortcut update), set_current_job (shortcut update)"),
2169
+ .describe("Action: list (filter+stats), get (detail+recent activities), create, update (partial), delete (soft archive; pass hard=true to remove), heartbeat (push from agent runtime), probe (HTTP/OpenClaw liveness probe), log_activity (manual note), list_activities, import_from_mind (enrich from agent-identity docs), seed_known (idempotent upsert of canonical seed), set_status (shortcut update), set_current_job (shortcut update), list_invoices (invoices linked to an agent), link_invoice (attach an existing invoice id), unlink_invoice (detach an invoice id), create_invoice (create a new Invoice Agent draft + link it)"),
1941
2170
  slug: zod_1.z.string().optional().describe("Agent slug (lowercase, dashes). Required for get/update/delete/heartbeat/probe/activities/set_*."),
1942
2171
  // create / update fields
1943
2172
  name: zod_1.z.string().optional().describe("Display name."),
@@ -1988,8 +2217,18 @@ function createMindMcpServer(client) {
1988
2217
  limit: zod_1.z.number().optional().describe("Max activities to return for list_activities (default 50)."),
1989
2218
  // seed_known
1990
2219
  overwrite: zod_1.z.boolean().optional().describe("If true with action=seed_known, reset existing records to seed defaults."),
2220
+ // invoice linking
2221
+ invoice_id: zod_1.z.string().optional().describe("Invoice id — required for link_invoice / unlink_invoice."),
2222
+ bill_to_name: zod_1.z.string().optional().describe("Recipient name for create_invoice (required)."),
2223
+ bill_to_company: zod_1.z.string().optional().describe("Recipient company for create_invoice."),
2224
+ bill_to_email: zod_1.z.string().optional().describe("Recipient email for create_invoice."),
2225
+ line_item_description: zod_1.z.string().optional().describe("Single line-item description for create_invoice."),
2226
+ quantity: zod_1.z.number().optional().describe("Line-item quantity for create_invoice (default 1)."),
2227
+ unit_price: zod_1.z.number().optional().describe("Line-item unit price for create_invoice (default 0)."),
2228
+ currency: zod_1.z.string().optional().describe("Invoice currency for create_invoice (default USD)."),
2229
+ invoice_notes: zod_1.z.string().optional().describe("Notes shown on the invoice for create_invoice."),
1991
2230
  }, async (args) => {
1992
- const { action, slug, name, description, status, cadence, host, host_address, port, health_url, source_path, source_repo, mind_identity_doc_id, responsibilities, triggers, tags, owner_email, expected_interval_seconds, authority_can_autonomous, authority_requires_approval, hard, current_job, metrics, note, source, activity_type, activity_payload, list_status, list_host, list_tag, include_archived, limit, overwrite, } = args;
2231
+ const { action, slug, name, description, status, cadence, host, host_address, port, health_url, source_path, source_repo, mind_identity_doc_id, responsibilities, triggers, tags, owner_email, expected_interval_seconds, authority_can_autonomous, authority_requires_approval, hard, current_job, metrics, note, source, activity_type, activity_payload, list_status, list_host, list_tag, include_archived, limit, overwrite, invoice_id, bill_to_name, bill_to_company, bill_to_email, line_item_description, quantity, unit_price, currency, invoice_notes, } = args;
1993
2232
  const requireSlug = (label) => {
1994
2233
  if (!slug) {
1995
2234
  return `Error: 'slug' is required for action=${label}.`;
@@ -2250,6 +2489,109 @@ function createMindMcpServer(client) {
2250
2489
  ],
2251
2490
  };
2252
2491
  }
2492
+ case "list_invoices": {
2493
+ const err = requireSlug("list_invoices");
2494
+ if (err)
2495
+ return { content: [{ type: "text", text: err }], isError: true };
2496
+ const result = await client.listAgentInvoices(slug);
2497
+ if (!result.invoices.length) {
2498
+ return { content: [{ type: "text", text: `No invoices linked to ${slug}.` }] };
2499
+ }
2500
+ const lines = result.invoices.map((i) => ` ${i.invoice_number.padEnd(10)} ${i.status.padEnd(8)} ${i.currency} ${i.total
2501
+ .toFixed(2)
2502
+ .padStart(10)} — ${i.bill_to_company ?? i.bill_to_name ?? "—"}`);
2503
+ return {
2504
+ content: [
2505
+ { type: "text", text: `Invoices linked to ${slug}:\n${lines.join("\n")}` },
2506
+ ],
2507
+ };
2508
+ }
2509
+ case "link_invoice": {
2510
+ const err = requireSlug("link_invoice");
2511
+ if (err)
2512
+ return { content: [{ type: "text", text: err }], isError: true };
2513
+ if (!invoice_id) {
2514
+ return {
2515
+ content: [{ type: "text", text: "Error: 'invoice_id' is required for link_invoice." }],
2516
+ isError: true,
2517
+ };
2518
+ }
2519
+ const updated = await client.linkAgentInvoice(slug, invoice_id);
2520
+ return {
2521
+ content: [
2522
+ {
2523
+ type: "text",
2524
+ text: `🔗 Linked invoice ${invoice_id} to ${updated.slug} (${updated.linked_invoices.length} total).`,
2525
+ },
2526
+ ],
2527
+ };
2528
+ }
2529
+ case "unlink_invoice": {
2530
+ const err = requireSlug("unlink_invoice");
2531
+ if (err)
2532
+ return { content: [{ type: "text", text: err }], isError: true };
2533
+ if (!invoice_id) {
2534
+ return {
2535
+ content: [{ type: "text", text: "Error: 'invoice_id' is required for unlink_invoice." }],
2536
+ isError: true,
2537
+ };
2538
+ }
2539
+ const updated = await client.unlinkAgentInvoice(slug, invoice_id);
2540
+ return {
2541
+ content: [
2542
+ {
2543
+ type: "text",
2544
+ text: `✂️ Unlinked invoice ${invoice_id} from ${updated.slug} (${updated.linked_invoices.length} remain).`,
2545
+ },
2546
+ ],
2547
+ };
2548
+ }
2549
+ case "create_invoice": {
2550
+ const err = requireSlug("create_invoice");
2551
+ if (err)
2552
+ return { content: [{ type: "text", text: err }], isError: true };
2553
+ if (!bill_to_name) {
2554
+ return {
2555
+ content: [
2556
+ { type: "text", text: "Error: 'bill_to_name' is required for create_invoice." },
2557
+ ],
2558
+ isError: true,
2559
+ };
2560
+ }
2561
+ const invoicePayload = {
2562
+ bill_from: {
2563
+ name: "Anthony Conti",
2564
+ company: "Astra AI, Inc.",
2565
+ email: "anthony@theastraway.com",
2566
+ },
2567
+ bill_to: {
2568
+ name: bill_to_name,
2569
+ company: bill_to_company ?? null,
2570
+ email: bill_to_email ?? null,
2571
+ },
2572
+ line_items: line_item_description
2573
+ ? [
2574
+ {
2575
+ description: line_item_description,
2576
+ quantity: quantity ?? 1,
2577
+ unit_price: unit_price ?? 0,
2578
+ },
2579
+ ]
2580
+ : [],
2581
+ currency: currency ?? "USD",
2582
+ };
2583
+ if (invoice_notes)
2584
+ invoicePayload.notes = invoice_notes;
2585
+ const res = await client.createAgentInvoice(slug, invoicePayload);
2586
+ return {
2587
+ content: [
2588
+ {
2589
+ type: "text",
2590
+ text: `🧾 Created invoice ${res.invoice.invoice_number} (${res.invoice.currency} ${res.invoice.total.toFixed(2)}) and linked it to ${slug}.`,
2591
+ },
2592
+ ],
2593
+ };
2594
+ }
2253
2595
  }
2254
2596
  }
2255
2597
  catch (err) {
@@ -2259,6 +2601,171 @@ function createMindMcpServer(client) {
2259
2601
  };
2260
2602
  }
2261
2603
  });
2604
+ // ─── mind_accounts ──────────────────────────────────────
2605
+ // Multi-MIND accounts: discover the MINDs this key's owner can access,
2606
+ // create new ones, and manage owners / viewers. Requires the server to
2607
+ // have MULTI_MIND_ACCOUNTS_ENABLED set.
2608
+ server.tool("mind_accounts", "Manage multi-MIND accounts. A 'MIND' is a knowledge-graph account; one person can own or be granted access to many. Use to discover every MIND you can access (list), spin up a new one (create), permanently delete one (delete), see who can access a MIND (members), grant an existing user access (grant), or email an invitation (invite).", {
2609
+ action: zod_1.z
2610
+ .enum(["list", "create", "delete", "members", "grant", "invite"])
2611
+ .describe("list (every MIND you can access), create (a new MIND you own), delete (permanently delete a MIND you own), members (owners/viewers of a MIND), grant (give an existing user access), invite (email an invitation)"),
2612
+ label: zod_1.z
2613
+ .string()
2614
+ .optional()
2615
+ .describe("Display name for the new MIND (required for create)"),
2616
+ mind_username: zod_1.z
2617
+ .string()
2618
+ .optional()
2619
+ .describe("Username of the MIND to manage (required for delete/members/grant/invite)"),
2620
+ grantee_username: zod_1.z
2621
+ .string()
2622
+ .optional()
2623
+ .describe("Existing MINDapp username to grant access to (required for grant)"),
2624
+ email: zod_1.z
2625
+ .string()
2626
+ .optional()
2627
+ .describe("Email address to send an invitation to (required for invite)"),
2628
+ role: zod_1.z
2629
+ .enum(["owner", "viewer"])
2630
+ .optional()
2631
+ .default("owner")
2632
+ .describe("Access level: owner (full access) or viewer (read-only)"),
2633
+ }, async ({ action, label, mind_username, grantee_username, email, role }) => {
2634
+ try {
2635
+ switch (action) {
2636
+ case "list": {
2637
+ const res = await client.listMinds();
2638
+ if (!res.enabled) {
2639
+ return {
2640
+ content: [
2641
+ {
2642
+ type: "text",
2643
+ text: "Multi-MIND accounts are not enabled for this MIND.",
2644
+ },
2645
+ ],
2646
+ };
2647
+ }
2648
+ const lines = res.accounts.map((a) => `${a.is_active ? "▸" : " "} ${a.label} (@${a.username}) — ${a.role}${a.is_self ? " · you" : ""}`);
2649
+ return {
2650
+ content: [
2651
+ {
2652
+ type: "text",
2653
+ text: `MINDs you can access (${res.accounts.length}):\n${lines.join("\n")}`,
2654
+ },
2655
+ ],
2656
+ };
2657
+ }
2658
+ case "create": {
2659
+ if (!label) {
2660
+ return {
2661
+ content: [{ type: "text", text: "Error: label is required for create" }],
2662
+ isError: true,
2663
+ };
2664
+ }
2665
+ const res = await client.createMind(label);
2666
+ return {
2667
+ content: [
2668
+ {
2669
+ type: "text",
2670
+ text: `✅ Created MIND "${res.label}" (@${res.username}).`,
2671
+ },
2672
+ ],
2673
+ };
2674
+ }
2675
+ case "delete": {
2676
+ if (!mind_username) {
2677
+ return {
2678
+ content: [{ type: "text", text: "Error: mind_username is required for delete" }],
2679
+ isError: true,
2680
+ };
2681
+ }
2682
+ await client.deleteMind(mind_username);
2683
+ return {
2684
+ content: [
2685
+ {
2686
+ type: "text",
2687
+ text: `✅ Permanently deleted MIND @${mind_username}.`,
2688
+ },
2689
+ ],
2690
+ };
2691
+ }
2692
+ case "members": {
2693
+ if (!mind_username) {
2694
+ return {
2695
+ content: [{ type: "text", text: "Error: mind_username is required for members" }],
2696
+ isError: true,
2697
+ };
2698
+ }
2699
+ const res = await client.listMindMembers(mind_username);
2700
+ const members = res.members
2701
+ .map((m) => `• @${m.username} — ${m.role}${m.is_primary ? " (primary)" : ""}`)
2702
+ .join("\n");
2703
+ const invites = res.pending_invites.length
2704
+ ? "\nPending invites:\n" +
2705
+ res.pending_invites.map((i) => `• ${i.email} — ${i.role}`).join("\n")
2706
+ : "";
2707
+ return {
2708
+ content: [
2709
+ {
2710
+ type: "text",
2711
+ text: `Members of @${res.mind_username}:\n${members}${invites}`,
2712
+ },
2713
+ ],
2714
+ };
2715
+ }
2716
+ case "grant": {
2717
+ if (!mind_username || !grantee_username) {
2718
+ return {
2719
+ content: [
2720
+ {
2721
+ type: "text",
2722
+ text: "Error: mind_username and grantee_username are required for grant",
2723
+ },
2724
+ ],
2725
+ isError: true,
2726
+ };
2727
+ }
2728
+ await client.grantMindMember(mind_username, grantee_username, role);
2729
+ return {
2730
+ content: [
2731
+ {
2732
+ type: "text",
2733
+ text: `✅ Granted @${grantee_username} ${role} access to @${mind_username}.`,
2734
+ },
2735
+ ],
2736
+ };
2737
+ }
2738
+ case "invite": {
2739
+ if (!mind_username || !email) {
2740
+ return {
2741
+ content: [
2742
+ {
2743
+ type: "text",
2744
+ text: "Error: mind_username and email are required for invite",
2745
+ },
2746
+ ],
2747
+ isError: true,
2748
+ };
2749
+ }
2750
+ const res = await client.createMindInvite(mind_username, email, role);
2751
+ return {
2752
+ content: [
2753
+ {
2754
+ type: "text",
2755
+ text: `✅ Invitation sent to ${res.email} (${res.role}) for @${mind_username}.`,
2756
+ },
2757
+ ],
2758
+ };
2759
+ }
2760
+ }
2761
+ }
2762
+ catch (err) {
2763
+ return {
2764
+ content: [{ type: "text", text: `mind_accounts error: ${err}` }],
2765
+ isError: true,
2766
+ };
2767
+ }
2768
+ });
2262
2769
  return server;
2263
2770
  }
2264
2771
  //# sourceMappingURL=server.js.map