@astramindapp/mcp-server 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/dist/integration-guide.d.ts +29 -2
- package/dist/integration-guide.d.ts.map +1 -1
- package/dist/integration-guide.js +1293 -3
- package/dist/integration-guide.js.map +1 -1
- package/dist/mind-client.d.ts +188 -0
- package/dist/mind-client.d.ts.map +1 -1
- package/dist/mind-client.js +125 -1
- package/dist/mind-client.js.map +1 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +417 -22
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
* integration path to use for its runtime, how to authenticate, and the
|
|
13
13
|
* session protocol — without having to be told.
|
|
14
14
|
*
|
|
15
|
-
* Tools (
|
|
15
|
+
* Tools (45):
|
|
16
16
|
* Memory & knowledge — mind_query, mind_remember, mind_folders,
|
|
17
17
|
* mind_folder_routes, mind_folder_suggest, mind_share (document share
|
|
18
18
|
* links), mind_context, mind_graph, mind_insights, mind_research,
|
|
19
19
|
* mind_train
|
|
20
20
|
* Life & work — mind_life, mind_focuses, mind_tasks, mind_automate,
|
|
21
21
|
* mind_notify, mind_checklists (Kanon checklists)
|
|
22
|
+
* Agent sessions — mind_sessions (log this session into MIND Chat →
|
|
23
|
+
* Agents; see the AGENT SESSION PROTOCOL in ./integration-guide)
|
|
22
24
|
* People — mind_crm
|
|
23
25
|
* Social & profile — mind_social, mind_social_analytics, mind_profile,
|
|
24
26
|
* mind_personas
|
|
@@ -84,7 +86,7 @@ const apiDetail = (e) => {
|
|
|
84
86
|
function createMindMcpServer(client) {
|
|
85
87
|
const server = new mcp_js_1.McpServer({
|
|
86
88
|
name: "mind",
|
|
87
|
-
version: "0.
|
|
89
|
+
version: "0.27.0",
|
|
88
90
|
}, {
|
|
89
91
|
// Returned to every client in the MCP `initialize` response — the first
|
|
90
92
|
// thing any connecting agent sees about how to integrate with MIND.
|
|
@@ -94,7 +96,7 @@ function createMindMcpServer(client) {
|
|
|
94
96
|
// The full integration playbook, readable on demand by any MCP client.
|
|
95
97
|
server.registerResource("integration-guide", "mind://integration-guide", {
|
|
96
98
|
title: "MIND Integration Guide",
|
|
97
|
-
description: "Complete playbook for integrating any AI agent with MIND — the three integration paths (MCP server, OpenClaw plugin, REST API), authentication, the session protocol, all
|
|
99
|
+
description: "Complete playbook for integrating any AI agent with MIND — the three integration paths (MCP server, OpenClaw plugin, REST API), authentication, the session protocol, all 45 tools, REST endpoint mapping, and common recipes.",
|
|
98
100
|
mimeType: "text/markdown",
|
|
99
101
|
}, async (uri) => ({
|
|
100
102
|
contents: [
|
|
@@ -105,10 +107,105 @@ function createMindMcpServer(client) {
|
|
|
105
107
|
},
|
|
106
108
|
],
|
|
107
109
|
}));
|
|
110
|
+
// ─── mind://agent-standard ──────────────────────────────
|
|
111
|
+
// The full MIND Agent Operating Standard (AGENTS.md, verbatim — see
|
|
112
|
+
// AGENT_STANDARD_MD in ./integration-guide.ts for provenance and the
|
|
113
|
+
// refresh recipe). SERVER_INSTRUCTIONS names this resource as mandatory
|
|
114
|
+
// reading in its "═══ MANDATORY PROTOCOLS ═══" section so an unauthenticated
|
|
115
|
+
// client sees the pointer even before it can read this resource.
|
|
116
|
+
server.registerResource("agent-standard", "mind://agent-standard", {
|
|
117
|
+
title: "The MIND Agent Operating Standard",
|
|
118
|
+
description: "The full, binding operating constitution for a MIND-connected agent (AGENTS.md, verbatim) — Law Zero, the boot protocol, session sync, the inactivity and termination protocols, the action-time gates, the sense catalog, and the memory contract. SERVER_INSTRUCTIONS names this as mandatory reading; this resource is the complete text.",
|
|
119
|
+
mimeType: "text/markdown",
|
|
120
|
+
}, async (uri) => ({
|
|
121
|
+
contents: [
|
|
122
|
+
{
|
|
123
|
+
uri: uri.href,
|
|
124
|
+
mimeType: "text/markdown",
|
|
125
|
+
text: integration_guide_js_1.AGENT_STANDARD_MD,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
}));
|
|
129
|
+
// ─── sync-local-docs-to-mind prompt ─────────────────────
|
|
130
|
+
// Standard prompt shipped WITH the server so any connected agent can back
|
|
131
|
+
// up the user's durable local documents into MIND without being taught
|
|
132
|
+
// the procedure from scratch. Body lives in integration-guide.ts beside
|
|
133
|
+
// SERVER_INSTRUCTIONS and INTEGRATION_GUIDE so all shipped copy is in one
|
|
134
|
+
// place. MCP prompt arguments are always strings.
|
|
135
|
+
server.registerPrompt("sync-local-docs-to-mind", {
|
|
136
|
+
title: "Sync local documents into MIND",
|
|
137
|
+
description: "Back up every durable document on this machine into the user's MIND, skipping code, junk and secrets. Safe by default: reports what it would upload before uploading anything.",
|
|
138
|
+
argsSchema: {
|
|
139
|
+
root: zod_1.z.string().optional().describe("Directory to scan. Default: the current working directory."),
|
|
140
|
+
dry_run: zod_1.z
|
|
141
|
+
.string()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe('"true" (default) reports the plan without writing. "false" performs the upload.'),
|
|
144
|
+
since: zod_1.z.string().optional().describe("Only consider files modified after this ISO date."),
|
|
145
|
+
},
|
|
146
|
+
}, async ({ root, dry_run, since }) => ({
|
|
147
|
+
messages: [
|
|
148
|
+
{
|
|
149
|
+
role: "user",
|
|
150
|
+
content: {
|
|
151
|
+
type: "text",
|
|
152
|
+
text: (0, integration_guide_js_1.buildSyncLocalDocsPrompt)({ root, dry_run, since }),
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
}));
|
|
157
|
+
// ─── sync-agent-session prompt ───────────────────────────
|
|
158
|
+
// Standard prompt shipped WITH the server so any connected agent can adopt
|
|
159
|
+
// the AGENT SESSION PROTOCOL (see integration-guide.ts) without being
|
|
160
|
+
// taught the procedure from scratch. Body lives in integration-guide.ts
|
|
161
|
+
// beside SERVER_INSTRUCTIONS and buildSyncLocalDocsPrompt so all shipped
|
|
162
|
+
// copy is in one place — see AGENT_SESSION_PROTOCOL_BODY there, which is
|
|
163
|
+
// also embedded verbatim in SERVER_INSTRUCTIONS and (compact) in the
|
|
164
|
+
// mind_sessions tool description below, so a client that only reads tool
|
|
165
|
+
// descriptions still follows it.
|
|
166
|
+
server.registerPrompt("sync-agent-session", {
|
|
167
|
+
title: "Adopt the Agent Session Protocol",
|
|
168
|
+
description: "Log this agent's live session into MIND Chat → Agents so Anthony can read and reply to it. Returns the full open/append/close/handoff protocol, addressed to your runtime.",
|
|
169
|
+
argsSchema: {
|
|
170
|
+
runtime: zod_1.z.string().optional().describe('Your runtime name, e.g. "claude-code", "codex", "cursor". Default: "your runtime".'),
|
|
171
|
+
source_key: zod_1.z.string().optional().describe('The MIND Chat sidebar toggle you were assigned, e.g. "claude-code-1". Default: "your-source-key".'),
|
|
172
|
+
},
|
|
173
|
+
}, async ({ runtime, source_key }) => ({
|
|
174
|
+
messages: [
|
|
175
|
+
{
|
|
176
|
+
role: "user",
|
|
177
|
+
content: {
|
|
178
|
+
type: "text",
|
|
179
|
+
text: (0, integration_guide_js_1.buildSyncAgentSessionPrompt)({ runtime, source_key }),
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
}));
|
|
184
|
+
// ─── adopt-agent-standard prompt ─────────────────────────
|
|
185
|
+
// Same content as the mind://agent-standard resource (AGENT_STANDARD_MD —
|
|
186
|
+
// see integration-guide.ts for provenance and the refresh recipe), offered
|
|
187
|
+
// as a prompt for clients that call prompts/get rather than reading MCP
|
|
188
|
+
// resources. SERVER_INSTRUCTIONS points every connecting agent at whichever
|
|
189
|
+
// of the two ("the resource ... or the adopt-agent-standard prompt") its
|
|
190
|
+
// host actually supports.
|
|
191
|
+
server.registerPrompt("adopt-agent-standard", {
|
|
192
|
+
title: "Adopt the MIND Agent Operating Standard",
|
|
193
|
+
description: "Returns the full MIND Agent Operating Standard (AGENTS.md, verbatim) — Law Zero, the boot protocol, session sync, the inactivity and termination protocols, the action-time gates, the sense catalog, and the memory contract. Read this before acting on behalf of an owner for the first time.",
|
|
194
|
+
}, async () => ({
|
|
195
|
+
messages: [
|
|
196
|
+
{
|
|
197
|
+
role: "user",
|
|
198
|
+
content: {
|
|
199
|
+
type: "text",
|
|
200
|
+
text: integration_guide_js_1.AGENT_STANDARD_MD,
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
}));
|
|
108
205
|
// ─── mind_query ─────────────────────────────────────────
|
|
109
206
|
// Semantic search across the user's knowledge graph.
|
|
110
207
|
// Replaces flat MEMORY.md — returns only relevant memories.
|
|
111
|
-
server.tool("mind_query", "Search
|
|
208
|
+
server.tool("mind_query", "Search the user's MIND knowledge graph — their persistent memory of people, projects, decisions, outcomes and history. Returns RETRIEVED CONTEXT for YOU to read and synthesize — documents, entries, entities and relationships — NOT a finished answer. Does not use MIND's LLM and costs 0 credits. Call this before asserting anything about the user's world, and before saying something does not exist. (Pass retrieve_only=false to have MIND's own LLM write the answer instead, which spends credits.)\n\nHOW TO ASK — this changes answer quality more than any parameter. Ask a rich, specific, full-sentence question; \"what is X\" retrieves poorly. Best results come from retrieve-then-write in one ask: \"Find everything about X, Y and Z, then write <deliverable> in this shape: <template>. Use only what you found; mark anything missing as unknown and do not invent it.\" Name the thing you expect to find — a document title, a person, a project, a date range. If the first answer is thin, change the QUESTION, not the mode — chain a narrower ask.\n\nPICKING A MODE (mechanical): naive reads document text only — best for recalling an exact passage or wording. local walks a named entity and its immediate graph neighbours — best for one specific person, company or thing. global reasons over relationships and themes across the whole graph — best for cross-cutting patterns. hybrid combines local+global graph reasoning but reads no raw document text. mix adds raw document text on top of hybrid and is the most complete; reach for it when hybrid feels thin. hybrid is the default — drop to naive/local/global only when you specifically need that narrower lens.\n\nNEGATIVES ARE THE HIGHEST-RISK ANSWER. An empty or thin result means your query missed — it is never proof the thing does not exist. Before reporting that something is absent, re-ask with different wording and say what you searched.", {
|
|
112
209
|
query: zod_1.z.string().describe("What to search for in your knowledge graph"),
|
|
113
210
|
mode: zod_1.z
|
|
114
211
|
.enum(["mix", "hybrid", "global", "local", "naive"])
|
|
@@ -167,7 +264,7 @@ function createMindMcpServer(client) {
|
|
|
167
264
|
// ─── mind_remember ──────────────────────────────────────
|
|
168
265
|
// Store/manage content in the knowledge graph. Auto-categorized by type.
|
|
169
266
|
// Enhanced: now supports create, delete, search, get, list actions.
|
|
170
|
-
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.\n\nTitle rule: lessons are titled 'Lesson - Failure - <behavior>' / 'Lesson - Behavior - <behavior>' / 'Lesson - Win - <behavior>'; never put '/' or parentheses in a title, the card is derived from it.", {
|
|
267
|
+
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.\n\nTitle rule: lessons are titled 'Lesson - Failure - <behavior>' / 'Lesson - Behavior - <behavior>' / 'Lesson - Win - <behavior>'; never put '/' or parentheses in a title, the card is derived from it.\n\nWRITE FOR THE AGENT WHO WILL SEARCH FOR THIS LATER — retrieval quality is decided here, not at query time. State facts in the words someone will later search for. Put the entity name in the first sentence. Inline dates, ids, file paths and numbers rather than saying \"the PR\" or \"yesterday\" — a note that only says \"fixed it\" is unfindable. If this supersedes an earlier note, say so explicitly and name what it replaces, so the older fact can be closed off instead of silently competing with this one.", {
|
|
171
268
|
action: zod_1.z
|
|
172
269
|
.enum(["create", "delete", "search", "get", "list"])
|
|
173
270
|
.optional()
|
|
@@ -355,15 +452,28 @@ function createMindMcpServer(client) {
|
|
|
355
452
|
// ─── mind_folders ───────────────────────────────────────
|
|
356
453
|
// Organize documents into folders. Folders are a presentation layer — the
|
|
357
454
|
// knowledge graph still indexes every document regardless of folder.
|
|
358
|
-
server.tool("mind_folders", "Organize your MIND documents into folders. Folders are a presentation layer — the knowledge graph still indexes and retrieves across every document regardless of folder. Use mind_remember to create a document, then mind_folders move_documents to file it. Actions: list, create, rename, move, delete, move_documents, set_hint (
|
|
455
|
+
server.tool("mind_folders", "Organize your MIND documents into folders. Folders are a presentation layer — the knowledge graph still indexes and retrieves across every document regardless of folder. Use mind_remember to create a document, then mind_folders move_documents to file it. Actions: list, create, rename, move, delete, move_documents, set_hint, secure, unsecure, unlock, reset_request, reset (Secure Folders — password-gate a folder).", {
|
|
359
456
|
action: zod_1.z
|
|
360
|
-
.enum([
|
|
361
|
-
|
|
457
|
+
.enum([
|
|
458
|
+
"list",
|
|
459
|
+
"create",
|
|
460
|
+
"rename",
|
|
461
|
+
"move",
|
|
462
|
+
"delete",
|
|
463
|
+
"move_documents",
|
|
464
|
+
"set_hint",
|
|
465
|
+
"secure",
|
|
466
|
+
"unsecure",
|
|
467
|
+
"unlock",
|
|
468
|
+
"reset_request",
|
|
469
|
+
"reset",
|
|
470
|
+
])
|
|
471
|
+
.describe("list (all folders + counts + routing hints + secure/locked flags), create (new folder; pass routing_hint to enable agent-routing), rename (change a folder's name), move (re-nest a folder), delete (remove a folder — its documents and subfolders move up a level, nothing is deleted), move_documents (file documents into a folder), set_hint (write/clear the routing_hint that mind_folder_suggest reads), secure (password-gate folder_id — pass passphrase; changing an existing passphrase needs an active unlock first), unsecure (turn off secure mode — needs an active unlock), unlock (verify passphrase, mints a 15-minute unlock kept in memory for this session and sent on every later call), reset_request (email a one-time reset link to the account email), reset (complete a reset — pass token + new_passphrase)"),
|
|
362
472
|
name: zod_1.z.string().optional().describe("Folder name — required for create and rename"),
|
|
363
473
|
folder_id: zod_1.z
|
|
364
474
|
.string()
|
|
365
475
|
.optional()
|
|
366
|
-
.describe("Folder id — the folder to rename/move/delete/set_hint, or the destination for move_documents (omit or pass 'root' to file documents at the top level)"),
|
|
476
|
+
.describe("Folder id — the folder to rename/move/delete/set_hint/secure/unsecure/unlock/reset_request/reset, or the destination for move_documents (omit or pass 'root' to file documents at the top level)"),
|
|
367
477
|
parent_id: zod_1.z
|
|
368
478
|
.string()
|
|
369
479
|
.optional()
|
|
@@ -376,7 +486,23 @@ function createMindMcpServer(client) {
|
|
|
376
486
|
.string()
|
|
377
487
|
.optional()
|
|
378
488
|
.describe("Free-text instruction answering \"when should MIND save things to this folder?\". Read by mind_folder_suggest to LLM-route new content. Pass on create to set up-front; pass on set_hint to update. Pass empty string to clear (disables the folder from auto-routing)."),
|
|
379
|
-
|
|
489
|
+
passphrase: zod_1.z
|
|
490
|
+
.string()
|
|
491
|
+
.optional()
|
|
492
|
+
.describe("Folder passphrase — required for secure and unlock"),
|
|
493
|
+
new_passphrase: zod_1.z
|
|
494
|
+
.string()
|
|
495
|
+
.optional()
|
|
496
|
+
.describe("New passphrase — required for reset"),
|
|
497
|
+
token: zod_1.z
|
|
498
|
+
.string()
|
|
499
|
+
.optional()
|
|
500
|
+
.describe("One-time reset token from the reset email — required for reset"),
|
|
501
|
+
unlock_token: zod_1.z
|
|
502
|
+
.string()
|
|
503
|
+
.optional()
|
|
504
|
+
.describe("Pass the exact `unlock_token` string returned by a prior 'unlock' call here to carry a 15-minute unlock into a later 'secure' (passphrase change) or 'unsecure' call. Not needed for the first time a folder is secured, and not used by list/create/rename/move/delete/move_documents/set_hint/unlock/reset_request/reset. This stdio server keeps unlock tokens in memory for the whole session and normally attaches them automatically (see 'unlock'), so passing this explicitly is usually redundant — but when supplied it takes precedence over the remembered token, so the same request shape works on both this server and the hosted MCP."),
|
|
505
|
+
}, async ({ action, name, folder_id, parent_id, doc_ids, routing_hint, passphrase, new_passphrase, token, unlock_token }) => {
|
|
380
506
|
try {
|
|
381
507
|
switch (action) {
|
|
382
508
|
case "list": {
|
|
@@ -396,7 +522,8 @@ function createMindMcpServer(client) {
|
|
|
396
522
|
const parent = f.parent_id ? byId.get(f.parent_id)?.name ?? "?" : "(top level)";
|
|
397
523
|
const hint = (f.routing_hint || "").trim();
|
|
398
524
|
const hintTail = hint ? ` · hint: ${hint.length > 80 ? hint.slice(0, 80) + "…" : hint}` : "";
|
|
399
|
-
|
|
525
|
+
const secureTail = f.secure ? (f.locked ? " · 🔒 secure (locked)" : " · 🔓 secure (unlocked)") : "";
|
|
526
|
+
return `• ${f.name} — ${f.document_count ?? 0} doc(s) · id: ${f.id} · parent: ${parent}${hintTail}${secureTail}`;
|
|
400
527
|
});
|
|
401
528
|
return {
|
|
402
529
|
content: [
|
|
@@ -490,6 +617,73 @@ function createMindMcpServer(client) {
|
|
|
490
617
|
],
|
|
491
618
|
};
|
|
492
619
|
}
|
|
620
|
+
case "secure": {
|
|
621
|
+
if (!folder_id)
|
|
622
|
+
throw new Error("'folder_id' is required to secure a folder");
|
|
623
|
+
if (!passphrase)
|
|
624
|
+
throw new Error("'passphrase' is required to secure a folder");
|
|
625
|
+
const res = await client.secureFolder(folder_id, passphrase, unlock_token);
|
|
626
|
+
return {
|
|
627
|
+
content: [
|
|
628
|
+
{ type: "text", text: `Folder ${res.folder_id} is now secure. Unlock it with action 'unlock' before reading its contents.` },
|
|
629
|
+
],
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
case "unsecure": {
|
|
633
|
+
if (!folder_id)
|
|
634
|
+
throw new Error("'folder_id' is required to unsecure a folder");
|
|
635
|
+
const res = await client.unsecureFolder(folder_id, unlock_token);
|
|
636
|
+
client.clearSecureFolderUnlockToken(folder_id);
|
|
637
|
+
return {
|
|
638
|
+
content: [{ type: "text", text: `Folder ${res.folder_id} is no longer secure.` }],
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
case "unlock": {
|
|
642
|
+
if (!folder_id)
|
|
643
|
+
throw new Error("'folder_id' is required to unlock a folder");
|
|
644
|
+
if (!passphrase)
|
|
645
|
+
throw new Error("'passphrase' is required to unlock a folder");
|
|
646
|
+
const res = await client.unlockFolder(folder_id, passphrase);
|
|
647
|
+
client.setSecureFolderUnlockToken(folder_id, res.unlock_token);
|
|
648
|
+
return {
|
|
649
|
+
content: [
|
|
650
|
+
{
|
|
651
|
+
type: "text",
|
|
652
|
+
text: `Unlocked. Expires at ${res.expires_at} (15 minutes) — every mind_query / mind_folders / document call this session will see inside it until then.`,
|
|
653
|
+
},
|
|
654
|
+
],
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
case "reset_request": {
|
|
658
|
+
if (!folder_id)
|
|
659
|
+
throw new Error("'folder_id' is required to request a passphrase reset");
|
|
660
|
+
const res = await client.requestFolderReset(folder_id);
|
|
661
|
+
return {
|
|
662
|
+
content: [
|
|
663
|
+
{
|
|
664
|
+
type: "text",
|
|
665
|
+
text: res.status === "sent"
|
|
666
|
+
? `Reset email sent to the account's email address (expires in 15 minutes).`
|
|
667
|
+
: `Reset requested, but email delivery is not configured on this deployment.`,
|
|
668
|
+
},
|
|
669
|
+
],
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
case "reset": {
|
|
673
|
+
if (!folder_id)
|
|
674
|
+
throw new Error("'folder_id' is required to reset a passphrase");
|
|
675
|
+
if (!token)
|
|
676
|
+
throw new Error("'token' (from the reset email) is required to reset a passphrase");
|
|
677
|
+
if (!new_passphrase)
|
|
678
|
+
throw new Error("'new_passphrase' is required to reset a passphrase");
|
|
679
|
+
const res = await client.resetFolder(folder_id, token, new_passphrase);
|
|
680
|
+
client.clearSecureFolderUnlockToken(folder_id);
|
|
681
|
+
return {
|
|
682
|
+
content: [
|
|
683
|
+
{ type: "text", text: `Passphrase reset for folder ${res.folder_id}. Unlock it with the new passphrase.` },
|
|
684
|
+
],
|
|
685
|
+
};
|
|
686
|
+
}
|
|
493
687
|
default:
|
|
494
688
|
throw new Error(`Unknown action: ${action}`);
|
|
495
689
|
}
|
|
@@ -653,7 +847,7 @@ function createMindMcpServer(client) {
|
|
|
653
847
|
// Get structured always-loaded context.
|
|
654
848
|
// Equivalent to OpenClaw's SOUL.md + USER.md + AGENTS.md bootstrap injection,
|
|
655
849
|
// but backed by the knowledge graph.
|
|
656
|
-
server.tool("mind_context", "
|
|
850
|
+
server.tool("mind_context", "Load the user's persistent context from MIND at session start — identity, preferences, operating rules, current priorities and recent activity. Returns RETRIEVED CONTEXT for YOU to synthesize, NOT a finished briefing. Does not use MIND's LLM and costs 0 credits. Call this at the start of every session.\n\nPass only the `sections` you actually need for the task at hand — a focused payload measurably outperforms the full default set, because the model attends better to fewer, more relevant facts. Every fact carries a date; when two facts conflict, the newer one wins, and say so if you rely on it. An empty `recent` section means nothing was logged, not that nothing happened — follow up with mind_query before assuming a quiet day. This is a snapshot, not the whole graph; for anything specific, follow up with mind_query.", {
|
|
657
851
|
sections: zod_1.z
|
|
658
852
|
.array(zod_1.z.enum(["soul", "user", "rules", "priorities", "recent"]))
|
|
659
853
|
.optional()
|
|
@@ -1230,7 +1424,7 @@ function createMindMcpServer(client) {
|
|
|
1230
1424
|
// ─── mind_tasks ─────────────────────────────────────────
|
|
1231
1425
|
// Site-wide tasks: assignable, completable work items that attach to a
|
|
1232
1426
|
// Life project, a CRM contact, an agent, or stand alone.
|
|
1233
|
-
server.tool("mind_tasks", "Manage site-wide tasks
|
|
1427
|
+
server.tool("mind_tasks", "Manage site-wide tasks — assignable, completable work items that are lighter-weight than a Life project/outcome and simpler than a Kanon checklist item. Reach for mind_tasks for a single actionable to-do (optionally attached to a Life project via parent_type=life_item, a CRM contact via parent_type=contact, or an agent) that needs an owner and a done/not-done state; reach for mind_life when the work is itself a deliverable inside the Focus→Project→Outcome hierarchy, and mind_checklists when you need a multi-item checklist with a progress rollup. Assign tasks to a MIND member, an agent, or an external email. Actions: list/create/get/update/complete/reopen/assign/delete, reports (completion analytics). An empty list means no tasks exist under that filter, not that no work is happening — check mind_life and mind_checklists for the same window before concluding nothing is tracked.", {
|
|
1234
1428
|
action: zod_1.z
|
|
1235
1429
|
.enum([
|
|
1236
1430
|
"list", "create", "get", "update", "complete", "reopen",
|
|
@@ -1436,7 +1630,7 @@ function createMindMcpServer(client) {
|
|
|
1436
1630
|
// ─── mind_crm ───────────────────────────────────────────
|
|
1437
1631
|
// Read/write contacts, interactions, and activities.
|
|
1438
1632
|
// Enhanced: delete, get, log_activity, list_activities.
|
|
1439
|
-
server.tool("mind_crm", "Manage contacts and relationships in MIND CRM
|
|
1633
|
+
server.tool("mind_crm", "Manage contacts and relationships in MIND CRM — the system of record for people, companies, leads and prospects, separate from the knowledge graph's document/entry memory. Reach for this (not mind_query) when you need to create, update, or list a specific contact record, or log/read a dated interaction history — reach for mind_query when you want a synthesized answer about a relationship drawn from everything MIND knows. Actions: list/create/update/delete/get contacts, log_activity (record an interaction), list_activities (interaction history). An empty list or 'No contacts found' means no CRM records exist yet, not that the person is unknown to MIND — check mind_query before concluding a relationship is undocumented.", {
|
|
1440
1634
|
action: zod_1.z
|
|
1441
1635
|
.enum(["list", "create", "update", "delete", "get", "log_activity", "list_activities"])
|
|
1442
1636
|
.describe("What to do: list/create/update/delete/get contacts, log_activity (record interaction), list_activities (view interaction history)"),
|
|
@@ -1588,7 +1782,7 @@ function createMindMcpServer(client) {
|
|
|
1588
1782
|
// ─── mind_graph ─────────────────────────────────────────
|
|
1589
1783
|
// Get graph statistics, diagnostics, and labels.
|
|
1590
1784
|
// Enhanced: action param with stats (default), diagnostics, labels.
|
|
1591
|
-
server.tool("mind_graph", "Get MIND knowledge graph statistics
|
|
1785
|
+
server.tool("mind_graph", "Get MIND knowledge graph statistics and diagnostics — entity/relationship counts, growth, label breakdown, and health status. Use this for a quantitative pulse-check on the graph itself (e.g. before a large ingestion, or to cite \"MIND has N entities\"); it does not search or retrieve content, so for facts, people or history use mind_query instead. Actions: stats (default overview), diagnostics (health check), labels (entity type breakdown). A low or zero count can mean an empty tenant OR a scoping/auth issue reading the wrong account — verify with mind_query on a known fact before treating a small graph as evidence nothing has been logged.", {
|
|
1592
1786
|
action: zod_1.z
|
|
1593
1787
|
.enum(["stats", "diagnostics", "labels"])
|
|
1594
1788
|
.optional()
|
|
@@ -2044,7 +2238,7 @@ function createMindMcpServer(client) {
|
|
|
2044
2238
|
// ═══════════════════════════════════════════════════════════
|
|
2045
2239
|
// ─── mind_sense ─────────────────────────────────────────
|
|
2046
2240
|
// MINDsense emotional intelligence layer.
|
|
2047
|
-
server.tool("mind_sense", "Access MINDsense
|
|
2241
|
+
server.tool("mind_sense", "Access MINDsense — the user's live emotional state, signal history, spikes and emotionally-weighted entities, derived from valence/arousal signal processing rather than asked directly. Reach for this before a sensitive conversation, when deciding how hard to push on a topic, or when asked \"how am I feeling\" / \"read the room\"; reach for mind_query instead for factual history about what happened. Actions: state (current snapshot), signals (recent raw signals), timeline (historical trend), kg_weights (which entities carry emotional weight), spikes (notable events, some unacknowledged), acknowledge (clear a spike), summary (AI-written recap). No signals in the lookback window means nothing was captured in that period, not that the user was neutral — widen `days` before concluding calm.", {
|
|
2048
2242
|
action: zod_1.z
|
|
2049
2243
|
.enum(["state", "signals", "timeline", "kg_weights", "spikes", "acknowledge", "summary"])
|
|
2050
2244
|
.describe("Action: state (current emotion), signals (recent signals), timeline (historical), kg_weights (emotionally weighted entities), spikes (recent spikes), acknowledge (ack a spike), summary (AI emotional summary)"),
|
|
@@ -2143,7 +2337,7 @@ function createMindMcpServer(client) {
|
|
|
2143
2337
|
});
|
|
2144
2338
|
// ─── mind_research ──────────────────────────────────────
|
|
2145
2339
|
// Deep research agent jobs.
|
|
2146
|
-
server.tool("mind_research", "Launch and
|
|
2340
|
+
server.tool("mind_research", "Launch and track autonomous deep-research jobs — MIND gathers sources, synthesizes them, and writes findings into the knowledge graph as it goes. Use this for a genuinely open-ended investigation (competitive analysis, market research, a technical deep-dive) that would take multiple search rounds; use mind_query for a quick fact lookup instead. Actions: start (launch, returns job_id), status (poll progress and read the summary once complete), list (all jobs). A job still 'running' has no findings yet — poll status again rather than treating a thin or missing summary as a negative result; once complete, read the findings via mind_query rather than re-reading the raw job.", {
|
|
2147
2341
|
action: zod_1.z
|
|
2148
2342
|
.enum(["start", "status", "list"])
|
|
2149
2343
|
.describe("Action: start (launch research), status (check job progress), list (view all jobs)"),
|
|
@@ -2210,7 +2404,7 @@ function createMindMcpServer(client) {
|
|
|
2210
2404
|
});
|
|
2211
2405
|
// ─── mind_train ─────────────────────────────────────────
|
|
2212
2406
|
// Self-training and chat-to-KG sessions.
|
|
2213
|
-
server.tool("mind_train", "
|
|
2407
|
+
server.tool("mind_train", "Run guided or freeform sessions that teach MIND about the user through conversation, or extract an existing chat transcript into the knowledge graph as durable memories — this is how unstructured conversation becomes queryable facts, distinct from mind_remember (one explicit fact) or mind_query (reading facts back). Actions: start (begin a session, optionally typed: basics/network/expertise/history/goals/freeform), chat (send the next training message), status (progress + items learned so far), list_sessions, pause/resume, save_chat (extract a chat session_id into the graph). 'Items learned: 0' or an empty list_sessions means no training has happened yet in this account, not that the user has nothing worth learning — check mind_query for what's already there before starting a duplicate session.", {
|
|
2214
2408
|
action: zod_1.z
|
|
2215
2409
|
.enum(["start", "chat", "status", "list_sessions", "pause", "resume", "save_chat"])
|
|
2216
2410
|
.describe("Action: start (begin training), chat (send message), status (check progress), list_sessions (view past), pause/resume (control session), save_chat (save chat to KG)"),
|
|
@@ -2533,7 +2727,7 @@ function createMindMcpServer(client) {
|
|
|
2533
2727
|
});
|
|
2534
2728
|
// ─── mind_profile ───────────────────────────────────────
|
|
2535
2729
|
// Profile, prompts, and model preferences.
|
|
2536
|
-
server.tool("mind_profile", "Manage
|
|
2730
|
+
server.tool("mind_profile", "Manage the user's own MIND profile, public-chat prompt, and model preferences — bio, display name, the system prompt used at their public /m/{username} chat surface, and their default LLM model. This is account/identity settings, not knowledge-graph content — for what MIND knows about the user, use mind_context or mind_query instead. Actions: get/update (profile fields), get_chat_prompt/set_chat_prompt, get_thought_prompt/set_thought_prompt, get_model/set_model/list_models. 'No custom prompt set' on get_chat_prompt/get_thought_prompt means the platform default applies, not that chat is unconfigured — call list_models before set_model if unsure a model id is valid, since an unrecognized id fails at the provider, not here.", {
|
|
2537
2731
|
action: zod_1.z
|
|
2538
2732
|
.enum([
|
|
2539
2733
|
"get", "update",
|
|
@@ -2653,7 +2847,7 @@ function createMindMcpServer(client) {
|
|
|
2653
2847
|
});
|
|
2654
2848
|
// ─── mind_insights ──────────────────────────────────────
|
|
2655
2849
|
// ALE insights and analytics.
|
|
2656
|
-
server.tool("mind_insights", "
|
|
2850
|
+
server.tool("mind_insights", "Read what MIND's Autonomous Learning Engine has already noticed about the user without being asked — patterns, weekly summaries, and proactive intelligence generated in the background — or trigger a fresh analysis pass on demand. Reach for this when the user asks \"what have you noticed\" or \"anything I'm missing\"; reach for mind_query when you already know what you're looking for. Actions: list (recent insights), unread_count, view (read one, marks it seen), feedback (rate helpful/not_helpful — tunes future insights), analyze (trigger a new pass now), weekly_summary, context (raw ALE state). 'No insights available' means the engine hasn't generated any yet for this account or period — call analyze to trigger a fresh pass rather than assuming nothing is happening in the graph.", {
|
|
2657
2851
|
action: zod_1.z
|
|
2658
2852
|
.enum(["list", "unread_count", "view", "feedback", "analyze", "weekly_summary", "context"])
|
|
2659
2853
|
.describe("Action: list (recent insights), unread_count, view (mark seen), feedback (rate), analyze (trigger analysis), weekly_summary, context (ALE context)"),
|
|
@@ -2743,7 +2937,7 @@ function createMindMcpServer(client) {
|
|
|
2743
2937
|
});
|
|
2744
2938
|
// ─── mind_automate ──────────────────────────────────────
|
|
2745
2939
|
// Automations and triggers.
|
|
2746
|
-
server.tool("mind_automate", "Create and manage automations
|
|
2940
|
+
server.tool("mind_automate", "Create and manage MIND-native automations — scheduled or event-triggered rules that run without a human or agent invoking them each time (e.g. a weekly CRM digest, a webhook that logs an event to a life project). This is for recurring MIND-internal work, not a general task scheduler for external systems. Actions: list/create/update/delete, run_now (fire immediately for testing), history (execution log). `trigger_config`/`action_config` are JSON strings, not objects — pass valid JSON or the call throws. An empty list means no automations are configured in this account yet, not that scheduled work isn't happening elsewhere.", {
|
|
2747
2941
|
action: zod_1.z
|
|
2748
2942
|
.enum(["list", "create", "update", "delete", "run_now", "history"])
|
|
2749
2943
|
.describe("Action: list/create/update/delete automations, run_now (trigger immediately), history (execution log)"),
|
|
@@ -2879,7 +3073,7 @@ function createMindMcpServer(client) {
|
|
|
2879
3073
|
});
|
|
2880
3074
|
// ─── mind_notify ────────────────────────────────────────
|
|
2881
3075
|
// Notifications management.
|
|
2882
|
-
server.tool("mind_notify", "Read and manage MIND
|
|
3076
|
+
server.tool("mind_notify", "Read and manage the user's MIND notification inbox — alerts, reminders, insight pings, and system messages generated by other MIND features. It is not a way to send a notification yourself. Use this to check what MIND has already surfaced to the user, or to clear it down; for the underlying event (why an insight fired, what an alert refers to) follow up with the originating tool (mind_insights, mind_sense, etc.) or mind_query. Actions: list, mark_read, mark_all_read, stats (total/unread/read counts). 'No notifications' or unread:0 means nothing has been pushed to the inbox — a quiet inbox and a quiet graph are different claims.", {
|
|
2883
3077
|
action: zod_1.z
|
|
2884
3078
|
.enum(["list", "mark_read", "mark_all_read", "stats"])
|
|
2885
3079
|
.describe("Action: list (view notifications), mark_read (single), mark_all_read (all), stats (overview)"),
|
|
@@ -2934,6 +3128,207 @@ function createMindMcpServer(client) {
|
|
|
2934
3128
|
};
|
|
2935
3129
|
}
|
|
2936
3130
|
});
|
|
3131
|
+
// ─── mind_sessions ──────────────────────────────────────
|
|
3132
|
+
// "Agent Sessions in MIND Chat" — logs THIS agent's own live session into
|
|
3133
|
+
// MIND as a tagged Agent Session so Anthony can read the transcript and
|
|
3134
|
+
// reply from MIND Chat → Agents. Backed by
|
|
3135
|
+
// backend/routes/agent_session_routes.py, prefix
|
|
3136
|
+
// /developer/v1/agent-sessions. See the full AGENT SESSION PROTOCOL in
|
|
3137
|
+
// integration-guide.ts (embedded verbatim in SERVER_INSTRUCTIONS and the
|
|
3138
|
+
// sync-agent-session prompt) — the compact version below is repeated here
|
|
3139
|
+
// so a client that only ever reads tool descriptions still gets it.
|
|
3140
|
+
server.tool("mind_sessions", "Log THIS agent's own live session into MIND Chat → Agents, so Anthony can read the transcript and reply — his reply reaches you on your next turn. Distinct from mind_remember (one durable fact) and mind_train (teaching the KG): this is the live, turn-by-turn session log, mirrored into a MIND document when you close it.\n\n" +
|
|
3141
|
+
"PROTOCOL (do this every session): " +
|
|
3142
|
+
"1) CONNECT — as soon as mind_context succeeds, call action=open with source_key (your assigned MIND Chat toggle, e.g. \"claude-code-1\"), external_session_id (your runtime's own session id), runtime, title (first user ask, 6-10 words), machine/cwd/repo/branch/model. If `resumed` is true, read `tail` before answering, and answer everything in `pending_replies` first — those arrived while you were away. " +
|
|
3143
|
+
"2) EVERY TURN — after you finish replying, call action=append with the user's message and your final reply (role user / assistant); tool calls go in as role=tool one-line summaries, never raw payloads. Check `pending_replies` on the response and answer them next turn. action=reply is a shortcut for appending a single assistant-role message when you have no user message to log alongside it. " +
|
|
3144
|
+
"3) IDLE — MIND marks the session idle after 30 minutes with no append; the next append revives it, nothing to do meanwhile. " +
|
|
3145
|
+
"4) TERMINATE — on exit, compaction, or \"done\", call action=close with a summary (what was asked, what shipped with ids/PR numbers, what is still undone); MIND mirrors the transcript into your Sessions folder as a document. " +
|
|
3146
|
+
"5) HANDOFF — to pass the conversation to another agent, call action=handoff with to_source_key=<their toggle>; they see it in their session list with the transcript as context. " +
|
|
3147
|
+
"Never claim a session is synced without the session_id MIND returned. Never log secrets or raw tool payloads.\n\n" +
|
|
3148
|
+
"Actions: open, append, close, list, get, reply (alias for append of one assistant message), inbox (undelivered mind-origin replies), handoff, sources (source_action=list|create|update|delete manages the MIND Chat sidebar toggles — auto-created on first open with an unknown source_key).", {
|
|
3149
|
+
action: zod_1.z
|
|
3150
|
+
.enum(["open", "append", "close", "list", "get", "reply", "inbox", "handoff", "sources"])
|
|
3151
|
+
.describe("Which agent-session operation to perform."),
|
|
3152
|
+
// open
|
|
3153
|
+
source_key: zod_1.z.string().optional().describe("Your assigned MIND Chat sidebar toggle slug, e.g. \"claude-code-1\" — required for open; also filters list; also required for sources action=create (as the new source's key)."),
|
|
3154
|
+
external_session_id: zod_1.z.string().optional().describe("Your runtime's own session id — required for open. Idempotent: opening the same (source_key, external_session_id) again resumes the existing session instead of creating a new one."),
|
|
3155
|
+
runtime: zod_1.z.string().optional().describe("Runtime name, e.g. \"claude-code\", \"codex\", \"cursor\", \"openclaw\", \"grok\", \"n8n\", \"custom\" — open (used if the source is auto-created); sources action=create/update."),
|
|
3156
|
+
source_label: zod_1.z.string().optional().describe("Human-readable label for an auto-created source on open, e.g. \"Claude Code 1\" — defaults to the titlecased source_key if omitted."),
|
|
3157
|
+
title: zod_1.z.string().optional().describe("Session title (first user ask, 6-10 words) — open (initial) or append (updates it)."),
|
|
3158
|
+
machine: zod_1.z.string().optional().describe("Machine identifier — open."),
|
|
3159
|
+
cwd: zod_1.z.string().optional().describe("Working directory — open."),
|
|
3160
|
+
repo: zod_1.z.string().optional().describe("Repository name — open."),
|
|
3161
|
+
branch: zod_1.z.string().optional().describe("Git branch — open."),
|
|
3162
|
+
model: zod_1.z.string().optional().describe("LLM model in use — open."),
|
|
3163
|
+
tags: zod_1.z.array(zod_1.z.string()).optional().describe("Freeform tags — open."),
|
|
3164
|
+
// append / reply
|
|
3165
|
+
session_id: zod_1.z.string().optional().describe("Session id returned by open — required for append/close/get/inbox/handoff."),
|
|
3166
|
+
messages: zod_1.z
|
|
3167
|
+
.array(zod_1.z.object({
|
|
3168
|
+
role: zod_1.z.enum(["user", "assistant", "system", "tool"]),
|
|
3169
|
+
content: zod_1.z.string(),
|
|
3170
|
+
origin: zod_1.z.enum(["agent"]).optional(),
|
|
3171
|
+
meta: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(),
|
|
3172
|
+
created_at: zod_1.z.string().optional(),
|
|
3173
|
+
}))
|
|
3174
|
+
.optional()
|
|
3175
|
+
.describe("Messages to append, in order — required for append. Tool-call messages should be role=tool, one-line summaries only, never raw payloads."),
|
|
3176
|
+
content: zod_1.z.string().optional().describe("Message text — required for reply (appended as a single role=assistant message)."),
|
|
3177
|
+
// close
|
|
3178
|
+
summary: zod_1.z.string().optional().describe("What was asked, what shipped (with ids/PR numbers), what is still undone — close. If omitted, MIND builds one from the transcript."),
|
|
3179
|
+
// list / close (status set) share this field
|
|
3180
|
+
status: zod_1.z.enum(["active", "idle", "ended"]).optional().describe("close: pass \"ended\" to explicitly close (default when summary is given). list: filter sessions by status."),
|
|
3181
|
+
q: zod_1.z.string().optional().describe("Free-text search over title/preview — list."),
|
|
3182
|
+
limit: zod_1.z.number().int().optional().describe("Max results — list (default 30) / get (default 200, messages)."),
|
|
3183
|
+
before: zod_1.z.string().optional().describe("Pagination cursor (last_activity_at) — list."),
|
|
3184
|
+
before_seq: zod_1.z.number().int().optional().describe("Return messages with seq before this value — get."),
|
|
3185
|
+
// handoff
|
|
3186
|
+
to_source_key: zod_1.z.string().optional().describe("Target source's key to hand this session off to — required for handoff."),
|
|
3187
|
+
// sources
|
|
3188
|
+
source_action: zod_1.z.enum(["list", "create", "update", "delete"]).optional().describe("Sub-action for action=sources (default list)."),
|
|
3189
|
+
source_id: zod_1.z.string().optional().describe("Source id — required for sources action=update/delete."),
|
|
3190
|
+
key: zod_1.z.string().optional().describe("New source's key slug — required for sources action=create."),
|
|
3191
|
+
label: zod_1.z.string().optional().describe("Source label, e.g. \"Claude Code 1\" — sources action=create (required) / update."),
|
|
3192
|
+
color: zod_1.z.string().optional().describe("Sidebar chip color — sources action=create/update."),
|
|
3193
|
+
wake_url: zod_1.z.string().optional().describe("Optional push endpoint MIND POSTs {session_id, reply} to (fire-and-forget, 5s timeout) when the user replies — sources action=create/update."),
|
|
3194
|
+
force: zod_1.z.boolean().optional().describe("sources action=delete: also delete the source's sessions instead of failing 409 when sessions exist."),
|
|
3195
|
+
}, async (args) => {
|
|
3196
|
+
const { action } = args;
|
|
3197
|
+
try {
|
|
3198
|
+
switch (action) {
|
|
3199
|
+
case "open": {
|
|
3200
|
+
const { source_key, external_session_id } = args;
|
|
3201
|
+
if (!source_key)
|
|
3202
|
+
return err("Error: 'source_key' is required for open.");
|
|
3203
|
+
if (!external_session_id)
|
|
3204
|
+
return err("Error: 'external_session_id' is required for open.");
|
|
3205
|
+
return ok(await client.openAgentSession({
|
|
3206
|
+
source_key,
|
|
3207
|
+
external_session_id,
|
|
3208
|
+
runtime: args.runtime,
|
|
3209
|
+
source_label: args.source_label,
|
|
3210
|
+
title: args.title,
|
|
3211
|
+
machine: args.machine,
|
|
3212
|
+
cwd: args.cwd,
|
|
3213
|
+
repo: args.repo,
|
|
3214
|
+
branch: args.branch,
|
|
3215
|
+
model: args.model,
|
|
3216
|
+
tags: args.tags,
|
|
3217
|
+
}));
|
|
3218
|
+
}
|
|
3219
|
+
case "append": {
|
|
3220
|
+
const { session_id, messages } = args;
|
|
3221
|
+
if (!session_id)
|
|
3222
|
+
return err("Error: 'session_id' is required for append.");
|
|
3223
|
+
if (!messages?.length)
|
|
3224
|
+
return err("Error: 'messages' (at least one) is required for append.");
|
|
3225
|
+
return ok(await client.appendAgentSession(session_id, messages, args.title));
|
|
3226
|
+
}
|
|
3227
|
+
case "reply": {
|
|
3228
|
+
const { session_id, content } = args;
|
|
3229
|
+
if (!session_id)
|
|
3230
|
+
return err("Error: 'session_id' is required for reply.");
|
|
3231
|
+
if (!content)
|
|
3232
|
+
return err("Error: 'content' is required for reply.");
|
|
3233
|
+
return ok(await client.appendAgentSession(session_id, [{ role: "assistant", content }]));
|
|
3234
|
+
}
|
|
3235
|
+
case "close": {
|
|
3236
|
+
const { session_id } = args;
|
|
3237
|
+
if (!session_id)
|
|
3238
|
+
return err("Error: 'session_id' is required for close.");
|
|
3239
|
+
return ok(await client.closeAgentSession(session_id, {
|
|
3240
|
+
summary: args.summary,
|
|
3241
|
+
status: args.status === "ended" ? "ended" : undefined,
|
|
3242
|
+
}));
|
|
3243
|
+
}
|
|
3244
|
+
case "list":
|
|
3245
|
+
return ok(await client.listAgentSessions({
|
|
3246
|
+
source_key: args.source_key,
|
|
3247
|
+
status: args.status,
|
|
3248
|
+
q: args.q,
|
|
3249
|
+
limit: args.limit,
|
|
3250
|
+
before: args.before,
|
|
3251
|
+
}));
|
|
3252
|
+
case "get": {
|
|
3253
|
+
const { session_id } = args;
|
|
3254
|
+
if (!session_id)
|
|
3255
|
+
return err("Error: 'session_id' is required for get.");
|
|
3256
|
+
return ok(await client.getAgentSession(session_id, {
|
|
3257
|
+
limit: args.limit,
|
|
3258
|
+
before_seq: args.before_seq,
|
|
3259
|
+
}));
|
|
3260
|
+
}
|
|
3261
|
+
case "inbox": {
|
|
3262
|
+
const { session_id } = args;
|
|
3263
|
+
if (!session_id)
|
|
3264
|
+
return err("Error: 'session_id' is required for inbox.");
|
|
3265
|
+
return ok(await client.agentSessionInbox(session_id));
|
|
3266
|
+
}
|
|
3267
|
+
case "handoff": {
|
|
3268
|
+
const { session_id, to_source_key } = args;
|
|
3269
|
+
if (!session_id)
|
|
3270
|
+
return err("Error: 'session_id' is required for handoff.");
|
|
3271
|
+
if (!to_source_key)
|
|
3272
|
+
return err("Error: 'to_source_key' is required for handoff.");
|
|
3273
|
+
return ok(await client.handoffAgentSession(session_id, to_source_key));
|
|
3274
|
+
}
|
|
3275
|
+
case "sources": {
|
|
3276
|
+
const sourceAction = args.source_action ?? "list";
|
|
3277
|
+
switch (sourceAction) {
|
|
3278
|
+
case "list":
|
|
3279
|
+
return ok(await client.listAgentSessionSources());
|
|
3280
|
+
case "create": {
|
|
3281
|
+
const { key, label, runtime } = args;
|
|
3282
|
+
if (!key)
|
|
3283
|
+
return err("Error: 'key' is required for sources action=create.");
|
|
3284
|
+
if (!label)
|
|
3285
|
+
return err("Error: 'label' is required for sources action=create.");
|
|
3286
|
+
if (!runtime)
|
|
3287
|
+
return err("Error: 'runtime' is required for sources action=create.");
|
|
3288
|
+
return ok(await client.createAgentSessionSource({
|
|
3289
|
+
key,
|
|
3290
|
+
label,
|
|
3291
|
+
runtime,
|
|
3292
|
+
color: args.color,
|
|
3293
|
+
wake_url: args.wake_url,
|
|
3294
|
+
}));
|
|
3295
|
+
}
|
|
3296
|
+
case "update": {
|
|
3297
|
+
const { source_id } = args;
|
|
3298
|
+
if (!source_id)
|
|
3299
|
+
return err("Error: 'source_id' is required for sources action=update.");
|
|
3300
|
+
return ok(await client.updateAgentSessionSource(source_id, {
|
|
3301
|
+
label: args.label,
|
|
3302
|
+
runtime: args.runtime,
|
|
3303
|
+
color: args.color,
|
|
3304
|
+
wake_url: args.wake_url,
|
|
3305
|
+
}));
|
|
3306
|
+
}
|
|
3307
|
+
case "delete": {
|
|
3308
|
+
const { source_id } = args;
|
|
3309
|
+
if (!source_id)
|
|
3310
|
+
return err("Error: 'source_id' is required for sources action=delete.");
|
|
3311
|
+
await client.deleteAgentSessionSource(source_id, args.force);
|
|
3312
|
+
return ok({ ok: true, source_id });
|
|
3313
|
+
}
|
|
3314
|
+
default: {
|
|
3315
|
+
const _exhaustive = sourceAction;
|
|
3316
|
+
return err(`Unknown source_action: ${_exhaustive}`);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
default: {
|
|
3321
|
+
const _exhaustive = action;
|
|
3322
|
+
return err(`Unknown action: ${_exhaustive}`);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
catch (e) {
|
|
3327
|
+
if (e instanceof mind_client_js_1.MindApiError)
|
|
3328
|
+
return err(`mind_sessions ${action} failed (HTTP ${e.status}): ${apiDetail(e)}`);
|
|
3329
|
+
return err(`mind_sessions error: ${e instanceof Error ? e.message : String(e)}`);
|
|
3330
|
+
}
|
|
3331
|
+
});
|
|
2937
3332
|
// ─── MIND Front Layer (typed-document taxonomy / "MIND Sense") ─────────────
|
|
2938
3333
|
// Three tools that expose the 16 typed-document templates and the typed-save flow.
|
|
2939
3334
|
// The same templates power the developer API endpoints under /v1/templates.
|