@astramindapp/mcp-server 0.11.0 → 0.12.1
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/mind-client.d.ts +74 -0
- package/dist/mind-client.d.ts.map +1 -1
- package/dist/mind-client.js +18 -0
- package/dist/mind-client.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +179 -9
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -475,7 +475,13 @@ function createMindMcpServer(client) {
|
|
|
475
475
|
end_time: zod_1.z.string().optional().describe("End time for calendar events (ISO 8601)"),
|
|
476
476
|
event_id: zod_1.z.string().optional().describe("Event ID for calendar_update/calendar_delete"),
|
|
477
477
|
all_day: zod_1.z.boolean().optional().describe("Whether the calendar event is all-day"),
|
|
478
|
-
|
|
478
|
+
tags: zod_1.z.array(zod_1.z.string()).optional().describe("Tags for the life item (free-form strings). On update, REPLACES the existing tag list — pass the full new set."),
|
|
479
|
+
color: zod_1.z
|
|
480
|
+
.enum(["default", "red", "orange", "yellow", "green", "blue", "purple", "pink"])
|
|
481
|
+
.optional()
|
|
482
|
+
.describe("Left-border color stripe on the board card. Use to group items (e.g. Astra=red, Atlas=blue)."),
|
|
483
|
+
target_date: zod_1.z.string().optional().describe("Target completion date in YYYY-MM-DD format — when the project should be done. Powers the countdown badge on the card."),
|
|
484
|
+
}, async ({ action, title, description, status, priority, due_date, item_id, item_ids, start_time, end_time, event_id, all_day, tags, color, target_date }) => {
|
|
479
485
|
try {
|
|
480
486
|
switch (action) {
|
|
481
487
|
case "list": {
|
|
@@ -500,12 +506,22 @@ function createMindMcpServer(client) {
|
|
|
500
506
|
status: status ?? "action",
|
|
501
507
|
priority: priority ?? "medium",
|
|
502
508
|
due_date,
|
|
509
|
+
tags,
|
|
510
|
+
color,
|
|
511
|
+
target_date,
|
|
503
512
|
});
|
|
513
|
+
const extras = [];
|
|
514
|
+
if (result.tags && result.tags.length > 0)
|
|
515
|
+
extras.push(`tags: ${result.tags.join(", ")}`);
|
|
516
|
+
if (result.color && result.color !== "default")
|
|
517
|
+
extras.push(`color: ${result.color}`);
|
|
518
|
+
if (result.target_date)
|
|
519
|
+
extras.push(`target: ${result.target_date}`);
|
|
504
520
|
return {
|
|
505
521
|
content: [
|
|
506
522
|
{
|
|
507
523
|
type: "text",
|
|
508
|
-
text: `✅ Created life item: "${result.title}" (id: ${result.item_id}, priority: ${result.priority}, due: ${result.due_date ?? "none"})`,
|
|
524
|
+
text: `✅ Created life item: "${result.title}" (id: ${result.item_id}, priority: ${result.priority}, due: ${result.due_date ?? "none"}${extras.length ? `, ${extras.join(", ")}` : ""})`,
|
|
509
525
|
},
|
|
510
526
|
],
|
|
511
527
|
};
|
|
@@ -528,9 +544,22 @@ function createMindMcpServer(client) {
|
|
|
528
544
|
patch.priority = priority;
|
|
529
545
|
if (due_date)
|
|
530
546
|
patch.due_date = due_date;
|
|
547
|
+
if (tags)
|
|
548
|
+
patch.tags = tags;
|
|
549
|
+
if (color)
|
|
550
|
+
patch.color = color;
|
|
551
|
+
if (target_date)
|
|
552
|
+
patch.target_date = target_date;
|
|
531
553
|
const result = await client.updateLifeItem(item_id, patch);
|
|
554
|
+
const extras = [];
|
|
555
|
+
if (result.tags && result.tags.length > 0)
|
|
556
|
+
extras.push(`tags: ${result.tags.join(", ")}`);
|
|
557
|
+
if (result.color && result.color !== "default")
|
|
558
|
+
extras.push(`color: ${result.color}`);
|
|
559
|
+
if (result.target_date)
|
|
560
|
+
extras.push(`target: ${result.target_date}`);
|
|
532
561
|
return {
|
|
533
|
-
content: [{ type: "text", text: `✅ Updated: "${result.title}" (status: ${result.status})` }],
|
|
562
|
+
content: [{ type: "text", text: `✅ Updated: "${result.title}" (status: ${result.status}${extras.length ? `, ${extras.join(", ")}` : ""})` }],
|
|
534
563
|
};
|
|
535
564
|
}
|
|
536
565
|
case "complete": {
|
|
@@ -596,8 +625,15 @@ function createMindMcpServer(client) {
|
|
|
596
625
|
const lines = [
|
|
597
626
|
`**${result.title}**`,
|
|
598
627
|
`Status: ${result.status ?? "—"} | Priority: ${result.priority ?? "—"} | Due: ${result.due_date ?? "none"}`,
|
|
599
|
-
result.description ? `\n${result.description}` : "",
|
|
600
628
|
];
|
|
629
|
+
if (result.color && result.color !== "default")
|
|
630
|
+
lines.push(`Color: ${result.color}`);
|
|
631
|
+
if (result.target_date)
|
|
632
|
+
lines.push(`Target: ${result.target_date}`);
|
|
633
|
+
if (result.tags && result.tags.length > 0)
|
|
634
|
+
lines.push(`Tags: ${result.tags.join(", ")}`);
|
|
635
|
+
if (result.description)
|
|
636
|
+
lines.push(`\n${result.description}`);
|
|
601
637
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
602
638
|
}
|
|
603
639
|
case "calendar_list": {
|
|
@@ -2328,8 +2364,12 @@ function createMindMcpServer(client) {
|
|
|
2328
2364
|
"link_invoice",
|
|
2329
2365
|
"unlink_invoice",
|
|
2330
2366
|
"create_invoice",
|
|
2367
|
+
"list_workflows",
|
|
2368
|
+
"link_workflow",
|
|
2369
|
+
"unlink_workflow",
|
|
2370
|
+
"used_by",
|
|
2331
2371
|
])
|
|
2332
|
-
.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), transfer_owner (move the agent to another account's board — needs owner_username), share (grant another account access — needs grantee_username + share_role), list_shares (who the agent is shared with), revoke_share (drop a share grant — needs share_id), 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)"),
|
|
2372
|
+
.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), transfer_owner (move the agent to another account's board — needs owner_username), share (grant another account access — needs grantee_username + share_role), list_shares (who the agent is shared with), revoke_share (drop a share grant — needs share_id), 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), list_workflows (workflows linked to an agent), link_workflow (attach an existing workflow slug — needs workflow_slug), unlink_workflow (detach a workflow — needs workflow_slug), used_by (inverse view: which agents call this workflow)"),
|
|
2333
2373
|
slug: zod_1.z.string().optional().describe("Agent slug (lowercase, dashes). Required for get/update/delete/heartbeat/probe/activities/set_*/transfer_owner/share/list_shares/revoke_share."),
|
|
2334
2374
|
// ownership / sharing
|
|
2335
2375
|
owner_username: zod_1.z.string().optional().describe("MIND account username to transfer the agent to (action=transfer_owner). The account must already exist."),
|
|
@@ -2396,8 +2436,29 @@ function createMindMcpServer(client) {
|
|
|
2396
2436
|
unit_price: zod_1.z.number().optional().describe("Line-item unit price for create_invoice (default 0)."),
|
|
2397
2437
|
currency: zod_1.z.string().optional().describe("Invoice currency for create_invoice (default USD)."),
|
|
2398
2438
|
invoice_notes: zod_1.z.string().optional().describe("Notes shown on the invoice for create_invoice."),
|
|
2439
|
+
// workflow linking + kind discriminator
|
|
2440
|
+
kind: zod_1.z
|
|
2441
|
+
.enum(["agent", "workflow"])
|
|
2442
|
+
.optional()
|
|
2443
|
+
.describe("Registry kind. Pass on create to scaffold a Workflow card instead of an Agent. Pass on action=list (via list_kind) to filter the board."),
|
|
2444
|
+
list_kind: zod_1.z
|
|
2445
|
+
.enum(["agent", "workflow"])
|
|
2446
|
+
.optional()
|
|
2447
|
+
.describe("Filter the board by kind when listing — 'agent' or 'workflow'. Omit to return both."),
|
|
2448
|
+
workflow_slug: zod_1.z.string().optional().describe("Workflow slug — required for link_workflow / unlink_workflow."),
|
|
2449
|
+
trigger_summary: zod_1.z.string().optional().describe("One-line description of what fires this workflow (kind='workflow' only)."),
|
|
2450
|
+
inputs_summary: zod_1.z.string().optional().describe("One-line description of the data this workflow consumes."),
|
|
2451
|
+
outputs_summary: zod_1.z.string().optional().describe("One-line description of the artifacts this workflow produces."),
|
|
2452
|
+
credentials_required: zod_1.z
|
|
2453
|
+
.array(zod_1.z.string())
|
|
2454
|
+
.optional()
|
|
2455
|
+
.describe("Named credentials this workflow touches (e.g. ['OpenAI API key', 'Resend API key', 'MIND tenant key'])."),
|
|
2456
|
+
steps_json: zod_1.z
|
|
2457
|
+
.string()
|
|
2458
|
+
.optional()
|
|
2459
|
+
.describe("JSON-encoded array of WorkflowStep dicts (kind='workflow' only). Each step: {order, name, description, kind, credentials[], inputs[], outputs[], notes}. Step kind ∈ {trigger, action, ai, branch, loop, wait, notify, output}."),
|
|
2399
2460
|
}, async (args) => {
|
|
2400
|
-
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, owner_username, grantee_username, share_role, share_id, 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, list_query, 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;
|
|
2461
|
+
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, owner_username, grantee_username, share_role, share_id, 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, list_query, include_archived, limit, overwrite, invoice_id, bill_to_name, bill_to_company, bill_to_email, line_item_description, quantity, unit_price, currency, invoice_notes, kind, list_kind, workflow_slug, trigger_summary, inputs_summary, outputs_summary, credentials_required, steps_json, } = args;
|
|
2401
2462
|
const requireSlug = (label) => {
|
|
2402
2463
|
if (!slug) {
|
|
2403
2464
|
return `Error: 'slug' is required for action=${label}.`;
|
|
@@ -2446,6 +2507,29 @@ function createMindMcpServer(client) {
|
|
|
2446
2507
|
requires_approval: authority_requires_approval ?? [],
|
|
2447
2508
|
};
|
|
2448
2509
|
}
|
|
2510
|
+
// Workflow-specific create/update fields. `kind` defaults server-side
|
|
2511
|
+
// to "agent" so it's only sent when the caller passes it explicitly.
|
|
2512
|
+
if (kind !== undefined)
|
|
2513
|
+
payload.kind = kind;
|
|
2514
|
+
if (trigger_summary !== undefined)
|
|
2515
|
+
payload.trigger_summary = trigger_summary;
|
|
2516
|
+
if (inputs_summary !== undefined)
|
|
2517
|
+
payload.inputs_summary = inputs_summary;
|
|
2518
|
+
if (outputs_summary !== undefined)
|
|
2519
|
+
payload.outputs_summary = outputs_summary;
|
|
2520
|
+
if (credentials_required !== undefined)
|
|
2521
|
+
payload.credentials_required = credentials_required;
|
|
2522
|
+
if (steps_json !== undefined) {
|
|
2523
|
+
try {
|
|
2524
|
+
const parsed = JSON.parse(steps_json);
|
|
2525
|
+
if (Array.isArray(parsed))
|
|
2526
|
+
payload.steps = parsed;
|
|
2527
|
+
}
|
|
2528
|
+
catch {
|
|
2529
|
+
// Surface a clear error rather than silently sending invalid JSON.
|
|
2530
|
+
throw new Error("steps_json must be a JSON-encoded array of WorkflowStep dicts.");
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2449
2533
|
return payload;
|
|
2450
2534
|
};
|
|
2451
2535
|
try {
|
|
@@ -2455,17 +2539,23 @@ function createMindMcpServer(client) {
|
|
|
2455
2539
|
status: list_status,
|
|
2456
2540
|
host: list_host,
|
|
2457
2541
|
tag: list_tag,
|
|
2542
|
+
kind: list_kind,
|
|
2458
2543
|
q: list_query,
|
|
2459
2544
|
include_archived,
|
|
2460
2545
|
});
|
|
2461
2546
|
const lines = [];
|
|
2462
2547
|
const s = result.stats;
|
|
2463
|
-
|
|
2548
|
+
const get = (k) => s[k] ?? 0;
|
|
2549
|
+
const kindLine = s.agents !== undefined || s.workflows !== undefined
|
|
2550
|
+
? `Kind: ${get("agents")} agents · ${get("workflows")} workflows`
|
|
2551
|
+
: "";
|
|
2552
|
+
lines.push(`Registry: ${get("total")} total · ${get("running")} running · ${get("planned")} planned · ${get("paused")} paused · ${get("error")} errored`, `Live: ${get("online")} online · ${get("stale")} stale · ${get("offline")} offline`, kindLine, "");
|
|
2464
2553
|
for (const a of result.agents) {
|
|
2465
2554
|
const host = a.host ?? "—";
|
|
2466
|
-
|
|
2555
|
+
const kindIcon = a.kind === "workflow" ? "⚙" : "🧠";
|
|
2556
|
+
lines.push(`• ${kindIcon} [${a.status.padEnd(8)}] ${a.slug.padEnd(28)} ${a.live_status.padEnd(7)} host=${host} owner=${a.owner_username ?? "—"} — ${a.name}`);
|
|
2467
2557
|
}
|
|
2468
|
-
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
2558
|
+
return { content: [{ type: "text", text: lines.filter(Boolean).join("\n") }] };
|
|
2469
2559
|
}
|
|
2470
2560
|
case "get": {
|
|
2471
2561
|
const err = requireSlug("get");
|
|
@@ -2837,6 +2927,86 @@ function createMindMcpServer(client) {
|
|
|
2837
2927
|
],
|
|
2838
2928
|
};
|
|
2839
2929
|
}
|
|
2930
|
+
case "list_workflows": {
|
|
2931
|
+
const err = requireSlug("list_workflows");
|
|
2932
|
+
if (err)
|
|
2933
|
+
return { content: [{ type: "text", text: err }], isError: true };
|
|
2934
|
+
const result = await client.listAgentWorkflows(slug);
|
|
2935
|
+
if (!result.workflows.length) {
|
|
2936
|
+
return { content: [{ type: "text", text: `No workflows linked to ${slug}.` }] };
|
|
2937
|
+
}
|
|
2938
|
+
const lines = result.workflows.map((w) => ` ⚙ ${w.slug.padEnd(28)} steps=${String(w.step_count).padStart(2)} · ${w.trigger_summary ?? "(no trigger summary)"} — ${w.name}`);
|
|
2939
|
+
return {
|
|
2940
|
+
content: [
|
|
2941
|
+
{ type: "text", text: `Workflows linked to ${slug}:\n${lines.join("\n")}` },
|
|
2942
|
+
],
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
case "link_workflow": {
|
|
2946
|
+
const err = requireSlug("link_workflow");
|
|
2947
|
+
if (err)
|
|
2948
|
+
return { content: [{ type: "text", text: err }], isError: true };
|
|
2949
|
+
if (!workflow_slug) {
|
|
2950
|
+
return {
|
|
2951
|
+
content: [{ type: "text", text: "Error: 'workflow_slug' is required for link_workflow." }],
|
|
2952
|
+
isError: true,
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
const updated = await client.linkAgentWorkflow(slug, workflow_slug);
|
|
2956
|
+
return {
|
|
2957
|
+
content: [
|
|
2958
|
+
{
|
|
2959
|
+
type: "text",
|
|
2960
|
+
text: `🔗 Linked workflow ${workflow_slug} to ${updated.slug} (${updated.linked_workflows.length} total).`,
|
|
2961
|
+
},
|
|
2962
|
+
],
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2965
|
+
case "unlink_workflow": {
|
|
2966
|
+
const err = requireSlug("unlink_workflow");
|
|
2967
|
+
if (err)
|
|
2968
|
+
return { content: [{ type: "text", text: err }], isError: true };
|
|
2969
|
+
if (!workflow_slug) {
|
|
2970
|
+
return {
|
|
2971
|
+
content: [{ type: "text", text: "Error: 'workflow_slug' is required for unlink_workflow." }],
|
|
2972
|
+
isError: true,
|
|
2973
|
+
};
|
|
2974
|
+
}
|
|
2975
|
+
const updated = await client.unlinkAgentWorkflow(slug, workflow_slug);
|
|
2976
|
+
return {
|
|
2977
|
+
content: [
|
|
2978
|
+
{
|
|
2979
|
+
type: "text",
|
|
2980
|
+
text: `✂️ Unlinked workflow ${workflow_slug} from ${updated.slug} (${updated.linked_workflows.length} remain).`,
|
|
2981
|
+
},
|
|
2982
|
+
],
|
|
2983
|
+
};
|
|
2984
|
+
}
|
|
2985
|
+
case "used_by": {
|
|
2986
|
+
const err = requireSlug("used_by");
|
|
2987
|
+
if (err)
|
|
2988
|
+
return { content: [{ type: "text", text: err }], isError: true };
|
|
2989
|
+
const result = await client.workflowUsedBy(slug);
|
|
2990
|
+
if (!result.agents.length) {
|
|
2991
|
+
return {
|
|
2992
|
+
content: [
|
|
2993
|
+
{
|
|
2994
|
+
type: "text",
|
|
2995
|
+
text: `${result.kind === "workflow" ? "Workflow" : "Agent"} ${result.slug} is not linked from any agent yet.`,
|
|
2996
|
+
},
|
|
2997
|
+
],
|
|
2998
|
+
};
|
|
2999
|
+
}
|
|
3000
|
+
const lines = result.agents.map((a) => ` 🧠 ${a.slug.padEnd(28)} host=${a.host ?? "—"} owner=${a.owner_username ?? "—"} — ${a.name}`);
|
|
3001
|
+
return {
|
|
3002
|
+
content: [
|
|
3003
|
+
{
|
|
3004
|
+
type: "text",
|
|
3005
|
+
text: `${result.name} is linked from ${result.agents.length} agent(s):\n${lines.join("\n")}`,
|
|
3006
|
+
},
|
|
3007
|
+
],
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
2840
3010
|
}
|
|
2841
3011
|
}
|
|
2842
3012
|
catch (err) {
|