@astramindapp/mcp-server 0.14.0 → 0.17.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/README.md +7 -7
- package/dist/integration-guide.d.ts +2 -2
- package/dist/integration-guide.d.ts.map +1 -1
- package/dist/integration-guide.js +23 -6
- package/dist/integration-guide.js.map +1 -1
- package/dist/mind-client.d.ts +64 -0
- package/dist/mind-client.d.ts.map +1 -1
- package/dist/mind-client.js +95 -0
- package/dist/mind-client.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +536 -12
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* mind_sense — MINDsense emotional intelligence layer
|
|
27
27
|
* mind_research — Deep research agent jobs
|
|
28
28
|
* mind_train — Self-training and chat-to-KG sessions
|
|
29
|
-
* mind_social —
|
|
29
|
+
* mind_social — Public feed posts, communities, and social feed
|
|
30
30
|
* mind_profile — Profile, prompts, and model preferences
|
|
31
31
|
* mind_insights — ALE insights and analytics
|
|
32
32
|
* mind_automate — Automations and triggers
|
|
@@ -48,7 +48,7 @@ const integration_guide_js_1 = require("./integration-guide.js");
|
|
|
48
48
|
function createMindMcpServer(client) {
|
|
49
49
|
const server = new mcp_js_1.McpServer({
|
|
50
50
|
name: "mind",
|
|
51
|
-
version: "0.
|
|
51
|
+
version: "0.17.0",
|
|
52
52
|
}, {
|
|
53
53
|
// Returned to every client in the MCP `initialize` response — the first
|
|
54
54
|
// thing any connecting agent sees about how to integrate with MIND.
|
|
@@ -72,7 +72,7 @@ function createMindMcpServer(client) {
|
|
|
72
72
|
// ─── mind_query ─────────────────────────────────────────
|
|
73
73
|
// Semantic search across the user's knowledge graph.
|
|
74
74
|
// Replaces flat MEMORY.md — returns only relevant memories.
|
|
75
|
-
server.tool("mind_query", "Search your MIND knowledge graph. Returns AI-synthesized answer from your stored documents, entries, and
|
|
75
|
+
server.tool("mind_query", "Search your MIND knowledge graph. Returns AI-synthesized answer from your stored documents, entries, and feed posts. Use this BEFORE making decisions — MIND is your memory.", {
|
|
76
76
|
query: zod_1.z.string().describe("What to search for in your knowledge graph"),
|
|
77
77
|
mode: zod_1.z
|
|
78
78
|
.enum(["mix", "hybrid", "global", "local", "naive"])
|
|
@@ -105,7 +105,7 @@ function createMindMcpServer(client) {
|
|
|
105
105
|
// ─── mind_remember ──────────────────────────────────────
|
|
106
106
|
// Store/manage content in the knowledge graph. Auto-categorized by type.
|
|
107
107
|
// Enhanced: now supports create, delete, search, get, list actions.
|
|
108
|
-
server.tool("mind_remember", "Store and manage content in your MIND knowledge graph. Use for facts, decisions, learnings, research, notes — anything worth remembering. Auto-categorized. Always log outcomes here after completing tasks. Supports create (default), delete, search, get, and list.", {
|
|
108
|
+
server.tool("mind_remember", "Store and manage content in your MIND knowledge graph. Use for facts, decisions, learnings, research, notes — anything worth remembering. Auto-categorized. Always log outcomes here after completing tasks. Supports create (default), delete, search, get, and list.\n\n⚠️ PRIVATE vs PUBLIC: `document` and `entry` are PRIVATE to the user's knowledge graph. `feed_post` is a PUBLIC social-media post that appears on the user's public feed for everyone to see. Default to `entry` for all agent outcomes, logs, decisions, and research. NEVER use `feed_post` unless the user explicitly says \"post\", \"share\", \"tweet\", \"feed\", or \"thought to my feed\" — deploy logs, PR notes, work outcomes, and agent activity belong in `entry`, NOT on the public feed.", {
|
|
109
109
|
action: zod_1.z
|
|
110
110
|
.enum(["create", "delete", "search", "get", "list"])
|
|
111
111
|
.optional()
|
|
@@ -113,14 +113,14 @@ function createMindMcpServer(client) {
|
|
|
113
113
|
.describe("Action: create (store new content — default), delete (remove by ID), search (find entries), get (retrieve by ID), list (paginated listing)"),
|
|
114
114
|
content: zod_1.z.string().optional().describe("What to remember — the actual content to store (required for create)"),
|
|
115
115
|
type: zod_1.z
|
|
116
|
-
.enum(["document", "entry", "thought"])
|
|
116
|
+
.enum(["document", "entry", "feed_post", "thought"])
|
|
117
117
|
.optional()
|
|
118
118
|
.default("entry")
|
|
119
|
-
.describe("Storage type: document (long-form, structured — research, specs, strategies), entry (medium — observations, findings, action logs
|
|
119
|
+
.describe("Storage type. PRIVATE: `document` (long-form, structured — research, specs, strategies), `entry` (medium — observations, findings, action logs, agent outcomes — DEFAULT for agent work). PUBLIC: `feed_post` (a social-media-style post that appears on the user's PUBLIC feed for everyone to see — NEVER use unless the user explicitly said \"post\", \"share\", \"tweet\", \"feed\", or \"thought to my feed\"). `thought` is a deprecated alias for `feed_post` and behaves identically — prefer `feed_post` for clarity."),
|
|
120
120
|
title: zod_1.z
|
|
121
121
|
.string()
|
|
122
122
|
.optional()
|
|
123
|
-
.describe("Title for documents and entries (auto-generated if omitted for
|
|
123
|
+
.describe("Title for documents and entries (auto-generated if omitted for feed posts)"),
|
|
124
124
|
tags: zod_1.z
|
|
125
125
|
.array(zod_1.z.string())
|
|
126
126
|
.optional()
|
|
@@ -167,9 +167,10 @@ function createMindMcpServer(client) {
|
|
|
167
167
|
});
|
|
168
168
|
storedAs = "document";
|
|
169
169
|
break;
|
|
170
|
+
case "feed_post":
|
|
170
171
|
case "thought":
|
|
171
172
|
result = await client.createThought({ content });
|
|
172
|
-
storedAs = "
|
|
173
|
+
storedAs = "feed_post";
|
|
173
174
|
break;
|
|
174
175
|
case "entry":
|
|
175
176
|
default:
|
|
@@ -202,6 +203,7 @@ function createMindMcpServer(client) {
|
|
|
202
203
|
case "document":
|
|
203
204
|
await client.deleteDocument(item_id);
|
|
204
205
|
break;
|
|
206
|
+
case "feed_post":
|
|
205
207
|
case "thought":
|
|
206
208
|
await client.deleteThought(item_id);
|
|
207
209
|
break;
|
|
@@ -211,7 +213,7 @@ function createMindMcpServer(client) {
|
|
|
211
213
|
break;
|
|
212
214
|
}
|
|
213
215
|
return {
|
|
214
|
-
content: [{ type: "text", text: `✅ Deleted ${type} ${item_id}` }],
|
|
216
|
+
content: [{ type: "text", text: `✅ Deleted ${type === "thought" ? "feed_post" : type} ${item_id}` }],
|
|
215
217
|
};
|
|
216
218
|
}
|
|
217
219
|
case "search": {
|
|
@@ -257,11 +259,12 @@ function createMindMcpServer(client) {
|
|
|
257
259
|
const lines = docs.map((d) => `• ${d.title} (status: ${d.status}, source: ${d.source}) — id: ${d.id}`);
|
|
258
260
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
259
261
|
}
|
|
262
|
+
case "feed_post":
|
|
260
263
|
case "thought": {
|
|
261
264
|
const result = await client.listThoughts();
|
|
262
265
|
const thoughts = result.thoughts ?? [];
|
|
263
266
|
if (thoughts.length === 0) {
|
|
264
|
-
return { content: [{ type: "text", text: "No
|
|
267
|
+
return { content: [{ type: "text", text: "No feed posts found." }] };
|
|
265
268
|
}
|
|
266
269
|
const lines = thoughts.map((t) => `• ${t.content?.slice(0, 100)}... — id: ${t.id ?? t.thought_id}`);
|
|
267
270
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
@@ -1808,7 +1811,7 @@ function createMindMcpServer(client) {
|
|
|
1808
1811
|
});
|
|
1809
1812
|
// ─── mind_social ────────────────────────────────────────
|
|
1810
1813
|
// Thoughts, communities, and feed.
|
|
1811
|
-
server.tool("mind_social", "Interact with MIND's social layer — create thoughts (posts), browse the feed, manage communities, and engage with other users' content.", {
|
|
1814
|
+
server.tool("mind_social", "Interact with MIND's social layer — create thoughts (PUBLIC feed posts), browse the feed, manage communities, and engage with other users' content. ⚠️ create_thought posts to the user's PUBLIC social feed for everyone to see — NEVER call unless the user explicitly said \"post\", \"share\", \"tweet\", \"feed\", or \"thought to my feed\". For private agent outcomes, deploy logs, or work updates, use mind_remember with type=entry instead.", {
|
|
1812
1815
|
action: zod_1.z
|
|
1813
1816
|
.enum([
|
|
1814
1817
|
"create_thought", "get_thought", "delete_thought", "like_thought",
|
|
@@ -1842,7 +1845,7 @@ function createMindMcpServer(client) {
|
|
|
1842
1845
|
content: [
|
|
1843
1846
|
{
|
|
1844
1847
|
type: "text",
|
|
1845
|
-
text: `✅
|
|
1848
|
+
text: `✅ Feed post created on PUBLIC feed (id: ${result.thought_id ?? result.id})`,
|
|
1846
1849
|
},
|
|
1847
1850
|
],
|
|
1848
1851
|
};
|
|
@@ -3524,6 +3527,527 @@ function createMindMcpServer(client) {
|
|
|
3524
3527
|
};
|
|
3525
3528
|
}
|
|
3526
3529
|
});
|
|
3530
|
+
// ─── mind_social ────────────────────────────────────────
|
|
3531
|
+
// Read-only analytics across YouTube, LinkedIn, X, Twitch + goals progress.
|
|
3532
|
+
server.tool("mind_social", "Read social media analytics from MIND's Social Dashboard — YouTube/LinkedIn/X/Twitch channel stats, recent videos with performance, retention curves, traffic sources, comment sentiment, and goal progress. Use this to answer questions like 'how did Tuesday's video do?' or 'am I on pace for 1k subs?'", {
|
|
3533
|
+
action: zod_1.z
|
|
3534
|
+
.enum([
|
|
3535
|
+
"status",
|
|
3536
|
+
"summary",
|
|
3537
|
+
"yt_channel",
|
|
3538
|
+
"yt_videos",
|
|
3539
|
+
"yt_video_detail",
|
|
3540
|
+
"goals",
|
|
3541
|
+
])
|
|
3542
|
+
.describe("Which read to perform: status (per-platform connection state), summary (cross-platform KPIs), yt_channel (channel snapshot + 28-day history), yt_videos (recent videos with perf), yt_video_detail (one video + retention + traffic + sentiment), goals (goal progress)."),
|
|
3543
|
+
video_id: zod_1.z
|
|
3544
|
+
.string()
|
|
3545
|
+
.optional()
|
|
3546
|
+
.describe("Required for yt_video_detail."),
|
|
3547
|
+
limit: zod_1.z
|
|
3548
|
+
.number()
|
|
3549
|
+
.int()
|
|
3550
|
+
.optional()
|
|
3551
|
+
.describe("Max items for yt_videos (default 25)."),
|
|
3552
|
+
}, async ({ action, video_id, limit }) => {
|
|
3553
|
+
try {
|
|
3554
|
+
switch (action) {
|
|
3555
|
+
case "status": {
|
|
3556
|
+
const r = (await client.socialStatus());
|
|
3557
|
+
const lines = ["**Social Dashboard status**"];
|
|
3558
|
+
lines.push(`Enabled: ${r.enabled ? "yes" : "no"} (global flag: ${r.globally_enabled ? "on" : "off"})`);
|
|
3559
|
+
const platforms = r.platforms || {};
|
|
3560
|
+
for (const key of ["youtube", "linkedin", "x", "twitch"]) {
|
|
3561
|
+
const p = platforms[key] || {};
|
|
3562
|
+
lines.push(`• ${key}: ${p.connected ? `connected (${p.account_label || "—"})` : p.configured ? "not connected" : "not configured"}`);
|
|
3563
|
+
}
|
|
3564
|
+
return {
|
|
3565
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
case "summary": {
|
|
3569
|
+
const r = (await client.socialSummary());
|
|
3570
|
+
const yt = r.youtube || {};
|
|
3571
|
+
const lines = [
|
|
3572
|
+
"**Cross-platform summary**",
|
|
3573
|
+
`YouTube subs: ${yt.subs ?? "—"}${yt.subs_delta_28d_pct != null ? ` (28d Δ ${yt.subs_delta_28d_pct}%)` : ""}`,
|
|
3574
|
+
`YouTube views: ${yt.total_views ?? "—"}${yt.views_delta_28d_pct != null ? ` (28d Δ ${yt.views_delta_28d_pct}%)` : ""}`,
|
|
3575
|
+
`YouTube watch minutes (28d): ${yt.watch_minutes_28d ?? "—"}`,
|
|
3576
|
+
`LinkedIn posts recent: ${(r.linkedin || {}).post_count_recent ?? "—"}`,
|
|
3577
|
+
`X tweets recent: ${(r.x || {}).tweet_count_recent ?? "—"}`,
|
|
3578
|
+
`Twitch VODs recent: ${(r.twitch || {}).vod_count_recent ?? "—"}`,
|
|
3579
|
+
];
|
|
3580
|
+
const goals = r.goals || [];
|
|
3581
|
+
if (goals.length) {
|
|
3582
|
+
lines.push("\n**Goals**");
|
|
3583
|
+
for (const g of goals) {
|
|
3584
|
+
lines.push(`• ${g.label || g.metric}: ${g.current ?? 0}/${g.target} (${g.pct ?? 0}%) — ${g.status}`);
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
return {
|
|
3588
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3589
|
+
};
|
|
3590
|
+
}
|
|
3591
|
+
case "yt_channel": {
|
|
3592
|
+
const r = (await client.socialYouTubeChannel());
|
|
3593
|
+
const latest = r.latest || {};
|
|
3594
|
+
const history = r.history || [];
|
|
3595
|
+
const lines = [
|
|
3596
|
+
"**YouTube channel**",
|
|
3597
|
+
`Subs: ${latest.subs ?? "—"}`,
|
|
3598
|
+
`Total views: ${latest.total_views ?? "—"}`,
|
|
3599
|
+
`Total watch minutes (28d): ${latest.total_watch_time_minutes ?? "—"}`,
|
|
3600
|
+
`Videos published: ${latest.video_count ?? "—"}`,
|
|
3601
|
+
`History points (last ${history.length} days):`,
|
|
3602
|
+
...history.slice(-7).map((h) => ` ${h.date}: ${h.subs} subs, ${h.total_views} views`),
|
|
3603
|
+
];
|
|
3604
|
+
return {
|
|
3605
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
case "yt_videos": {
|
|
3609
|
+
const r = (await client.socialYouTubeVideos(limit ?? 25));
|
|
3610
|
+
const items = r.items || [];
|
|
3611
|
+
if (!items.length) {
|
|
3612
|
+
return {
|
|
3613
|
+
content: [{ type: "text", text: "No videos in snapshot cache yet." }],
|
|
3614
|
+
};
|
|
3615
|
+
}
|
|
3616
|
+
const lines = [`**Recent videos** (${items.length})`];
|
|
3617
|
+
for (const v of items.slice(0, 15)) {
|
|
3618
|
+
const l = v.latest || {};
|
|
3619
|
+
lines.push(`• ${v.title} — ${l.views ?? "—"} views, ${l.ctr_percent != null ? l.ctr_percent.toFixed(1) + "%" : "—"} CTR, ${l.comments ?? "—"} comments [${v.video_id}]`);
|
|
3620
|
+
}
|
|
3621
|
+
return {
|
|
3622
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3623
|
+
};
|
|
3624
|
+
}
|
|
3625
|
+
case "yt_video_detail": {
|
|
3626
|
+
if (!video_id) {
|
|
3627
|
+
return {
|
|
3628
|
+
content: [
|
|
3629
|
+
{ type: "text", text: "Error: video_id is required for yt_video_detail" },
|
|
3630
|
+
],
|
|
3631
|
+
isError: true,
|
|
3632
|
+
};
|
|
3633
|
+
}
|
|
3634
|
+
const r = (await client.socialYouTubeVideoDetail(video_id));
|
|
3635
|
+
const meta = r.metadata || {};
|
|
3636
|
+
const latest = r.latest || {};
|
|
3637
|
+
const traffic = r.traffic || [];
|
|
3638
|
+
const sent = r.comments?.sentiment_summary || {};
|
|
3639
|
+
const lines = [
|
|
3640
|
+
`**${meta.title}**`,
|
|
3641
|
+
`Published: ${meta.published_at} · ${meta.duration_seconds ? Math.round(meta.duration_seconds / 60) + " min" : "—"}`,
|
|
3642
|
+
`Views: ${latest.views ?? "—"} · CTR: ${latest.ctr_percent != null ? latest.ctr_percent.toFixed(1) + "%" : "—"} · AVD: ${latest.avd_seconds ? Math.round(latest.avd_seconds) + "s" : "—"}`,
|
|
3643
|
+
`Subs Δ: +${latest.subscribers_gained ?? 0} / -${latest.subscribers_lost ?? 0}`,
|
|
3644
|
+
"",
|
|
3645
|
+
"Traffic sources:",
|
|
3646
|
+
...traffic.slice(0, 5).map((t) => ` • ${t.source}: ${t.views}`),
|
|
3647
|
+
"",
|
|
3648
|
+
`Comments: ${sent.count ?? 0} (${sent.positive ?? 0} pos / ${sent.neutral ?? 0} neu / ${sent.negative ?? 0} neg, avg ${(sent.avg_score ?? 0).toFixed(2)})`,
|
|
3649
|
+
];
|
|
3650
|
+
return {
|
|
3651
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3652
|
+
};
|
|
3653
|
+
}
|
|
3654
|
+
case "goals": {
|
|
3655
|
+
const r = (await client.socialGoals());
|
|
3656
|
+
const items = r.items || [];
|
|
3657
|
+
if (!items.length) {
|
|
3658
|
+
return {
|
|
3659
|
+
content: [{ type: "text", text: "No goals set." }],
|
|
3660
|
+
};
|
|
3661
|
+
}
|
|
3662
|
+
const lines = ["**Goals**"];
|
|
3663
|
+
for (const g of items) {
|
|
3664
|
+
lines.push(`• ${g.label || g.metric}: ${g.current ?? 0}/${g.target} (${g.pct ?? 0}%) — due ${g.due_date} — ${g.status}`);
|
|
3665
|
+
}
|
|
3666
|
+
return {
|
|
3667
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3668
|
+
};
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
catch (err) {
|
|
3673
|
+
return {
|
|
3674
|
+
content: [{ type: "text", text: `mind_social error: ${err}` }],
|
|
3675
|
+
isError: true,
|
|
3676
|
+
};
|
|
3677
|
+
}
|
|
3678
|
+
});
|
|
3679
|
+
// ─── mind_personas ──────────────────────────────────────────
|
|
3680
|
+
// Influencer Factory Command Center surface. Admin-only.
|
|
3681
|
+
// Whole router is dark unless IF_FEATURE_FLAG_ENABLED=true on the server.
|
|
3682
|
+
// Persona == featured_minds row (1:1) — IF fields stored on featured_minds,
|
|
3683
|
+
// asset library (face/voice/bios/Blotato) on the persona_assets collection.
|
|
3684
|
+
server.tool("mind_personas", "Influencer Factory Command Center — synthetic-persona creators that publish across Blotato platforms. Admin-only. Phase 1 surface: persona CRUD (auto-creates a Featured MIND row with IF fields), face anchor (AI-generate via Nano Banana Pro OR user-uploaded with rights affirmation), face variants (image-to-image via n8n + Fal.ai, always pinned to anchor — never chained), voice (ElevenLabs library search + clone + sample), per-platform bios (with optional LLM draft), Blotato account registration (YouTube/IG/LinkedIn/X/Threads/Pinterest; TikTok marked manual_upload). Each persona is publicly chattable at /m/{username} via its linked Featured MIND.", {
|
|
3685
|
+
action: zod_1.z
|
|
3686
|
+
.enum([
|
|
3687
|
+
"health",
|
|
3688
|
+
"list_personas",
|
|
3689
|
+
"get_persona",
|
|
3690
|
+
"create_persona",
|
|
3691
|
+
"update_persona",
|
|
3692
|
+
"delete_persona",
|
|
3693
|
+
"anchor_face_ai_generate",
|
|
3694
|
+
"request_face_variants",
|
|
3695
|
+
"list_face_variants",
|
|
3696
|
+
"search_voice_library",
|
|
3697
|
+
"set_voice_library",
|
|
3698
|
+
"generate_voice_sample",
|
|
3699
|
+
"update_bios",
|
|
3700
|
+
"blotato_whoami",
|
|
3701
|
+
"blotato_accounts",
|
|
3702
|
+
"register_blotato_account",
|
|
3703
|
+
"unregister_blotato_account",
|
|
3704
|
+
])
|
|
3705
|
+
.describe("What to do. Start with 'health' to confirm Fal/ElevenLabs/Blotato/S3/n8n are configured. Most write actions require persona_mind_id."),
|
|
3706
|
+
persona_mind_id: zod_1.z
|
|
3707
|
+
.string()
|
|
3708
|
+
.optional()
|
|
3709
|
+
.describe("Persona id (== featured_minds.mind_id). Required for every per-persona action."),
|
|
3710
|
+
// create_persona
|
|
3711
|
+
username: zod_1.z
|
|
3712
|
+
.string()
|
|
3713
|
+
.optional()
|
|
3714
|
+
.describe("Lowercase username (3–32 chars, [a-z0-9_-]). Used for /m/{username} public landing AND the featured_minds row. Required for create_persona."),
|
|
3715
|
+
display_name: zod_1.z.string().optional().describe("Display name. Required for create_persona."),
|
|
3716
|
+
niche: zod_1.z.string().optional().describe("Niche label, e.g. 'fitness', 'wealth'."),
|
|
3717
|
+
pillars: zod_1.z
|
|
3718
|
+
.array(zod_1.z.string())
|
|
3719
|
+
.optional()
|
|
3720
|
+
.describe("3–5 content pillars the persona writes about."),
|
|
3721
|
+
tone: zod_1.z
|
|
3722
|
+
.string()
|
|
3723
|
+
.optional()
|
|
3724
|
+
.describe("Tone descriptor, e.g. 'warm-direct', 'contrarian-analytical'."),
|
|
3725
|
+
archetype_id: zod_1.z
|
|
3726
|
+
.string()
|
|
3727
|
+
.optional()
|
|
3728
|
+
.describe("Persona archetype template id (looked up in persona_archetypes catalog)."),
|
|
3729
|
+
kg_scope_template_id: zod_1.z
|
|
3730
|
+
.string()
|
|
3731
|
+
.optional()
|
|
3732
|
+
.describe("Knowledge-graph scope template id (bounds what this persona 'knows about')."),
|
|
3733
|
+
niche_tags: zod_1.z
|
|
3734
|
+
.array(zod_1.z.string())
|
|
3735
|
+
.optional()
|
|
3736
|
+
.describe("Topic niche tags used by retrieval (separate from Featured MIND catalog tags)."),
|
|
3737
|
+
daily_credit_ceiling_usd: zod_1.z
|
|
3738
|
+
.number()
|
|
3739
|
+
.optional()
|
|
3740
|
+
.describe("Hard ceiling on daily Fal.ai/ElevenLabs/Veo/Suno spend for this persona. Default 5."),
|
|
3741
|
+
// update_persona — partial
|
|
3742
|
+
status: zod_1.z
|
|
3743
|
+
.enum(["draft", "active", "paused"])
|
|
3744
|
+
.optional()
|
|
3745
|
+
.describe("Persona runtime status."),
|
|
3746
|
+
agent_posting_enabled: zod_1.z
|
|
3747
|
+
.boolean()
|
|
3748
|
+
.optional()
|
|
3749
|
+
.describe("Master kill-switch on the linked Featured MIND row. Off = autonomous posters skip this persona."),
|
|
3750
|
+
// anchor_face_ai_generate
|
|
3751
|
+
prompt: zod_1.z
|
|
3752
|
+
.string()
|
|
3753
|
+
.optional()
|
|
3754
|
+
.describe("Anchor-face generation prompt OR voice sample text (anchor_face_ai_generate, generate_voice_sample)."),
|
|
3755
|
+
model: zod_1.z
|
|
3756
|
+
.enum(["nano_banana_pro", "flux"])
|
|
3757
|
+
.optional()
|
|
3758
|
+
.describe("Anchor-face generator model. Default nano_banana_pro."),
|
|
3759
|
+
// request_face_variants
|
|
3760
|
+
count: zod_1.z
|
|
3761
|
+
.number()
|
|
3762
|
+
.optional()
|
|
3763
|
+
.describe("Variant count (1–20). Default 5."),
|
|
3764
|
+
prompt_modifier: zod_1.z
|
|
3765
|
+
.string()
|
|
3766
|
+
.optional()
|
|
3767
|
+
.describe("Optional modifier appended to the base variant prompt (e.g. 'outdoor golden hour')."),
|
|
3768
|
+
// voice
|
|
3769
|
+
voice_query: zod_1.z
|
|
3770
|
+
.string()
|
|
3771
|
+
.optional()
|
|
3772
|
+
.describe("ElevenLabs library search query (search_voice_library)."),
|
|
3773
|
+
voice_id: zod_1.z
|
|
3774
|
+
.string()
|
|
3775
|
+
.optional()
|
|
3776
|
+
.describe("ElevenLabs voice id (set_voice_library)."),
|
|
3777
|
+
voice_name: zod_1.z
|
|
3778
|
+
.string()
|
|
3779
|
+
.optional()
|
|
3780
|
+
.describe("Display name to store for the voice (set_voice_library)."),
|
|
3781
|
+
voice_text: zod_1.z
|
|
3782
|
+
.string()
|
|
3783
|
+
.optional()
|
|
3784
|
+
.describe("Text to render as a sample MP3 (generate_voice_sample)."),
|
|
3785
|
+
// bios
|
|
3786
|
+
bios: zod_1.z
|
|
3787
|
+
.record(zod_1.z.string(), zod_1.z.string())
|
|
3788
|
+
.optional()
|
|
3789
|
+
.describe("Map of platform → bio text (twitter|instagram|tiktok|linkedin|youtube|threads|pinterest). Length-capped server-side."),
|
|
3790
|
+
generate_with_llm: zod_1.z
|
|
3791
|
+
.boolean()
|
|
3792
|
+
.optional()
|
|
3793
|
+
.describe("If true, LLM drafts missing platform bios. Existing bios stay."),
|
|
3794
|
+
// blotato
|
|
3795
|
+
platform: zod_1.z
|
|
3796
|
+
.enum([
|
|
3797
|
+
"twitter",
|
|
3798
|
+
"instagram",
|
|
3799
|
+
"tiktok",
|
|
3800
|
+
"linkedin",
|
|
3801
|
+
"youtube",
|
|
3802
|
+
"threads",
|
|
3803
|
+
"pinterest",
|
|
3804
|
+
])
|
|
3805
|
+
.optional()
|
|
3806
|
+
.describe("Target platform for Blotato register/unregister."),
|
|
3807
|
+
account_id: zod_1.z
|
|
3808
|
+
.string()
|
|
3809
|
+
.optional()
|
|
3810
|
+
.describe("Blotato account id (from blotato_accounts list)."),
|
|
3811
|
+
page_id: zod_1.z
|
|
3812
|
+
.string()
|
|
3813
|
+
.optional()
|
|
3814
|
+
.describe("LinkedIn / IG / YouTube page id (optional, platform-specific)."),
|
|
3815
|
+
board_id: zod_1.z
|
|
3816
|
+
.string()
|
|
3817
|
+
.optional()
|
|
3818
|
+
.describe("Pinterest board id (REQUIRED for Pinterest)."),
|
|
3819
|
+
handle: zod_1.z.string().optional().describe("Display handle (optional)."),
|
|
3820
|
+
media_type: zod_1.z
|
|
3821
|
+
.enum(["story", "reel"])
|
|
3822
|
+
.optional()
|
|
3823
|
+
.describe("Instagram media type (story or reel)."),
|
|
3824
|
+
// list filters
|
|
3825
|
+
search: zod_1.z.string().optional().describe("Search filter for list_personas."),
|
|
3826
|
+
}, async (args) => {
|
|
3827
|
+
try {
|
|
3828
|
+
const { action, persona_mind_id: pid, username, display_name, niche, pillars, tone, archetype_id, kg_scope_template_id, niche_tags, daily_credit_ceiling_usd, status, agent_posting_enabled, prompt, model, count, prompt_modifier, voice_query, voice_id, voice_name, voice_text, bios, generate_with_llm, platform, account_id, page_id, board_id, handle, media_type, search, } = args;
|
|
3829
|
+
const needPid = () => {
|
|
3830
|
+
if (!pid)
|
|
3831
|
+
throw new Error(`${action} requires persona_mind_id`);
|
|
3832
|
+
};
|
|
3833
|
+
switch (action) {
|
|
3834
|
+
case "health": {
|
|
3835
|
+
const r = await client.ifHealth();
|
|
3836
|
+
return {
|
|
3837
|
+
content: [
|
|
3838
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3839
|
+
],
|
|
3840
|
+
};
|
|
3841
|
+
}
|
|
3842
|
+
case "list_personas": {
|
|
3843
|
+
const r = await client.ifListPersonas({ status, search });
|
|
3844
|
+
if (!r.length) {
|
|
3845
|
+
return { content: [{ type: "text", text: "No personas." }] };
|
|
3846
|
+
}
|
|
3847
|
+
const lines = r.map((p) => `• @${p.username} — ${p.display_name} [${p.status}] (${p.persona_mind_id})`);
|
|
3848
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
3849
|
+
}
|
|
3850
|
+
case "get_persona": {
|
|
3851
|
+
needPid();
|
|
3852
|
+
const r = await client.ifGetPersonaFull(pid);
|
|
3853
|
+
return {
|
|
3854
|
+
content: [
|
|
3855
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3856
|
+
],
|
|
3857
|
+
};
|
|
3858
|
+
}
|
|
3859
|
+
case "create_persona": {
|
|
3860
|
+
if (!username || !display_name)
|
|
3861
|
+
throw new Error("username and display_name are required");
|
|
3862
|
+
const r = await client.ifCreatePersona({
|
|
3863
|
+
username,
|
|
3864
|
+
display_name,
|
|
3865
|
+
niche,
|
|
3866
|
+
pillars,
|
|
3867
|
+
tone,
|
|
3868
|
+
archetype_id,
|
|
3869
|
+
kg_scope_template_id,
|
|
3870
|
+
niche_tags,
|
|
3871
|
+
daily_credit_ceiling_usd,
|
|
3872
|
+
});
|
|
3873
|
+
return {
|
|
3874
|
+
content: [
|
|
3875
|
+
{
|
|
3876
|
+
type: "text",
|
|
3877
|
+
text: `Created persona @${r.username} (mind_id=${r.persona_mind_id})`,
|
|
3878
|
+
},
|
|
3879
|
+
],
|
|
3880
|
+
};
|
|
3881
|
+
}
|
|
3882
|
+
case "update_persona": {
|
|
3883
|
+
needPid();
|
|
3884
|
+
const patch = {};
|
|
3885
|
+
if (display_name !== undefined)
|
|
3886
|
+
patch.display_name = display_name;
|
|
3887
|
+
if (niche !== undefined)
|
|
3888
|
+
patch.niche = niche;
|
|
3889
|
+
if (pillars !== undefined)
|
|
3890
|
+
patch.pillars = pillars;
|
|
3891
|
+
if (tone !== undefined)
|
|
3892
|
+
patch.tone = tone;
|
|
3893
|
+
if (daily_credit_ceiling_usd !== undefined)
|
|
3894
|
+
patch.daily_credit_ceiling_usd = daily_credit_ceiling_usd;
|
|
3895
|
+
if (status !== undefined)
|
|
3896
|
+
patch.status = status;
|
|
3897
|
+
if (archetype_id !== undefined)
|
|
3898
|
+
patch.archetype_id = archetype_id;
|
|
3899
|
+
if (kg_scope_template_id !== undefined)
|
|
3900
|
+
patch.kg_scope_template_id = kg_scope_template_id;
|
|
3901
|
+
if (niche_tags !== undefined)
|
|
3902
|
+
patch.niche_tags = niche_tags;
|
|
3903
|
+
if (agent_posting_enabled !== undefined)
|
|
3904
|
+
patch.agent_posting_enabled = agent_posting_enabled;
|
|
3905
|
+
const r = await client.ifUpdatePersona(pid, patch);
|
|
3906
|
+
return {
|
|
3907
|
+
content: [{ type: "text", text: JSON.stringify(r, null, 2) }],
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
case "delete_persona": {
|
|
3911
|
+
needPid();
|
|
3912
|
+
const r = await client.ifDeletePersona(pid);
|
|
3913
|
+
return {
|
|
3914
|
+
content: [
|
|
3915
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3916
|
+
],
|
|
3917
|
+
};
|
|
3918
|
+
}
|
|
3919
|
+
case "anchor_face_ai_generate": {
|
|
3920
|
+
needPid();
|
|
3921
|
+
if (!prompt)
|
|
3922
|
+
throw new Error("prompt is required");
|
|
3923
|
+
const r = await client.ifAnchorAIGenerate(pid, { prompt, model });
|
|
3924
|
+
return {
|
|
3925
|
+
content: [
|
|
3926
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3927
|
+
],
|
|
3928
|
+
};
|
|
3929
|
+
}
|
|
3930
|
+
case "request_face_variants": {
|
|
3931
|
+
needPid();
|
|
3932
|
+
const r = await client.ifRequestVariants(pid, {
|
|
3933
|
+
count: count ?? 5,
|
|
3934
|
+
prompt_modifier,
|
|
3935
|
+
});
|
|
3936
|
+
return {
|
|
3937
|
+
content: [
|
|
3938
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3939
|
+
],
|
|
3940
|
+
};
|
|
3941
|
+
}
|
|
3942
|
+
case "list_face_variants": {
|
|
3943
|
+
needPid();
|
|
3944
|
+
const r = await client.ifListVariants(pid);
|
|
3945
|
+
return {
|
|
3946
|
+
content: [
|
|
3947
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3948
|
+
],
|
|
3949
|
+
};
|
|
3950
|
+
}
|
|
3951
|
+
case "search_voice_library": {
|
|
3952
|
+
const r = await client.ifSearchVoiceLibrary({ q: voice_query });
|
|
3953
|
+
return {
|
|
3954
|
+
content: [
|
|
3955
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3956
|
+
],
|
|
3957
|
+
};
|
|
3958
|
+
}
|
|
3959
|
+
case "set_voice_library": {
|
|
3960
|
+
needPid();
|
|
3961
|
+
if (!voice_id)
|
|
3962
|
+
throw new Error("voice_id is required");
|
|
3963
|
+
const r = await client.ifSetVoiceLibrary(pid, {
|
|
3964
|
+
voice_id,
|
|
3965
|
+
name: voice_name,
|
|
3966
|
+
});
|
|
3967
|
+
return {
|
|
3968
|
+
content: [
|
|
3969
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3970
|
+
],
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3973
|
+
case "generate_voice_sample": {
|
|
3974
|
+
needPid();
|
|
3975
|
+
if (!voice_text)
|
|
3976
|
+
throw new Error("voice_text is required");
|
|
3977
|
+
const r = await client.ifVoiceSample(pid, voice_text);
|
|
3978
|
+
return {
|
|
3979
|
+
content: [
|
|
3980
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3981
|
+
],
|
|
3982
|
+
};
|
|
3983
|
+
}
|
|
3984
|
+
case "update_bios": {
|
|
3985
|
+
needPid();
|
|
3986
|
+
const r = await client.ifUpdateBios(pid, {
|
|
3987
|
+
bios: bios ?? {},
|
|
3988
|
+
generate_with_llm,
|
|
3989
|
+
});
|
|
3990
|
+
return {
|
|
3991
|
+
content: [
|
|
3992
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
3993
|
+
],
|
|
3994
|
+
};
|
|
3995
|
+
}
|
|
3996
|
+
case "blotato_whoami": {
|
|
3997
|
+
const r = await client.ifBlotatoWhoami();
|
|
3998
|
+
return {
|
|
3999
|
+
content: [
|
|
4000
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
4001
|
+
],
|
|
4002
|
+
};
|
|
4003
|
+
}
|
|
4004
|
+
case "blotato_accounts": {
|
|
4005
|
+
const r = await client.ifBlotatoAccounts();
|
|
4006
|
+
return {
|
|
4007
|
+
content: [
|
|
4008
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
4009
|
+
],
|
|
4010
|
+
};
|
|
4011
|
+
}
|
|
4012
|
+
case "register_blotato_account": {
|
|
4013
|
+
needPid();
|
|
4014
|
+
if (!platform || !account_id)
|
|
4015
|
+
throw new Error("platform and account_id are required");
|
|
4016
|
+
const r = await client.ifRegisterBlotato(pid, platform, {
|
|
4017
|
+
account_id,
|
|
4018
|
+
page_id,
|
|
4019
|
+
board_id,
|
|
4020
|
+
handle,
|
|
4021
|
+
media_type,
|
|
4022
|
+
});
|
|
4023
|
+
return {
|
|
4024
|
+
content: [
|
|
4025
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
4026
|
+
],
|
|
4027
|
+
};
|
|
4028
|
+
}
|
|
4029
|
+
case "unregister_blotato_account": {
|
|
4030
|
+
needPid();
|
|
4031
|
+
if (!platform)
|
|
4032
|
+
throw new Error("platform is required");
|
|
4033
|
+
const r = await client.ifUnregisterBlotato(pid, platform);
|
|
4034
|
+
return {
|
|
4035
|
+
content: [
|
|
4036
|
+
{ type: "text", text: JSON.stringify(r, null, 2) },
|
|
4037
|
+
],
|
|
4038
|
+
};
|
|
4039
|
+
}
|
|
4040
|
+
default:
|
|
4041
|
+
throw new Error(`Unknown action: ${action}`);
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
catch (err) {
|
|
4045
|
+
return {
|
|
4046
|
+
content: [{ type: "text", text: `mind_personas error: ${err}` }],
|
|
4047
|
+
isError: true,
|
|
4048
|
+
};
|
|
4049
|
+
}
|
|
4050
|
+
});
|
|
3527
4051
|
return server;
|
|
3528
4052
|
}
|
|
3529
4053
|
//# sourceMappingURL=server.js.map
|