mindgraph-mcp 0.3.3 → 0.4.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.
Files changed (3) hide show
  1. package/dist/cli.js +355 -350
  2. package/dist/index.js +355 -350
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -41,20 +41,12 @@ function err(message) {
41
41
  async function handleTool(client2, name, args) {
42
42
  try {
43
43
  switch (name) {
44
- case "mindgraph_journal":
45
- return await handleJournal(client2, args);
46
44
  case "mindgraph_capture":
47
45
  return await handleCapture(client2, args);
48
- case "mindgraph_argue":
49
- return await handleArgue(client2, args);
50
- case "mindgraph_inquire":
51
- return await handleInquire(client2, args);
46
+ case "mindgraph_reason":
47
+ return await handleReason(client2, args);
52
48
  case "mindgraph_commit":
53
49
  return await handleCommit(client2, args);
54
- case "mindgraph_decide":
55
- return await handleDecide(client2, args);
56
- case "mindgraph_action":
57
- return await handleAction(client2, args);
58
50
  case "mindgraph_plan":
59
51
  return await handlePlan(client2, args);
60
52
  case "mindgraph_retrieve":
@@ -69,31 +61,29 @@ async function handleTool(client2, name, args) {
69
61
  return err(message);
70
62
  }
71
63
  }
72
- async function handleJournal(client2, args) {
73
- const { label, content, mood, tags, agent_id } = args;
74
- const props = { content };
75
- if (mood) props.mood = mood;
76
- if (tags) props.tags = tags;
77
- const result = await client2.journal(
78
- label,
79
- props,
80
- { agent_id }
81
- );
82
- return ok(result);
83
- }
84
64
  async function handleCapture(client2, args) {
85
65
  const {
86
66
  action,
87
67
  label,
88
68
  summary,
69
+ content,
89
70
  entity_type,
90
71
  source_uid,
72
+ mood,
73
+ tags,
91
74
  confidence,
92
75
  salience,
93
76
  props,
94
77
  agent_id
95
78
  } = args;
96
79
  switch (action) {
80
+ case "journal": {
81
+ if (!content) return err("content is required for action=journal");
82
+ const journalProps = { content };
83
+ if (mood) journalProps.mood = mood;
84
+ if (tags) journalProps.tags = tags;
85
+ return ok(await client2.journal(label, journalProps, { agent_id }));
86
+ }
97
87
  case "entity": {
98
88
  const type = entity_type || "concept";
99
89
  const entityProps = { ...props };
@@ -167,58 +157,85 @@ async function handleCapture(client2, args) {
167
157
  return err(`Unknown capture action: ${action}`);
168
158
  }
169
159
  }
170
- async function handleArgue(client2, args) {
171
- const { claim, evidence, warrant, argument, agent_id } = args;
172
- const result = await client2.argue({
160
+ async function handleReason(client2, args) {
161
+ const {
162
+ action,
163
+ label,
164
+ summary,
173
165
  claim,
174
166
  evidence,
175
167
  warrant,
176
168
  argument,
177
- agent_id
178
- });
179
- return ok(result);
180
- }
181
- async function handleInquire(client2, args) {
182
- const { action, label, summary, confidence, salience, props, agent_id } = args;
183
- const result = await client2.inquire({
184
- action,
185
- label,
186
- summary,
187
169
  confidence,
188
170
  salience,
189
171
  props,
190
172
  agent_id
191
- });
192
- return ok(result);
173
+ } = args;
174
+ if (action === "claim") {
175
+ const claimObj = claim || (label ? { label, confidence } : null);
176
+ if (!claimObj) return err("claim object or label is required for action=claim");
177
+ return ok(
178
+ await client2.argue({
179
+ claim: claimObj,
180
+ evidence,
181
+ warrant,
182
+ argument,
183
+ agent_id
184
+ })
185
+ );
186
+ }
187
+ if (!label) return err(`label is required for action=${action}`);
188
+ return ok(
189
+ await client2.inquire({
190
+ action,
191
+ label,
192
+ summary,
193
+ confidence,
194
+ salience,
195
+ props,
196
+ agent_id
197
+ })
198
+ );
193
199
  }
194
200
  async function handleCommit(client2, args) {
195
- const { action, label, summary, parent_uid, confidence, salience, props, agent_id } = args;
196
- const result = await client2.commit({
201
+ const {
197
202
  action,
198
203
  label,
199
204
  summary,
200
205
  parent_uid,
206
+ decision_uid,
207
+ chosen_option_uid,
201
208
  confidence,
202
209
  salience,
203
210
  props,
204
211
  agent_id
205
- });
206
- return ok(result);
207
- }
208
- async function handleDecide(client2, args) {
209
- const { action, label, summary, decision_uid, chosen_option_uid, props, agent_id } = args;
212
+ } = args;
210
213
  switch (action) {
214
+ case "goal":
215
+ case "project":
216
+ case "milestone":
217
+ if (!label) return err(`label is required for action=${action}`);
218
+ return ok(
219
+ await client2.commit({
220
+ action,
221
+ label,
222
+ summary,
223
+ parent_uid,
224
+ confidence,
225
+ salience,
226
+ props,
227
+ agent_id
228
+ })
229
+ );
211
230
  case "open_decision":
212
231
  if (!label) return err("label is required for open_decision");
213
232
  return ok(await client2.openDecision(label, { summary, props, agent_id }));
214
233
  case "add_option":
215
- if (!decision_uid) return err("decision_uid is required");
234
+ if (!decision_uid) return err("decision_uid is required for add_option");
216
235
  if (!label) return err("label is required for add_option");
217
- return ok(
218
- await client2.addOption(decision_uid, label, { summary, props, agent_id })
219
- );
236
+ return ok(await client2.addOption(decision_uid, label, { summary, props, agent_id }));
220
237
  case "add_constraint":
221
- if (!decision_uid) return err("decision_uid is required");
238
+ if (!decision_uid) return err("decision_uid is required for add_constraint");
222
239
  return ok(
223
240
  await client2.deliberate({
224
241
  action: "add_constraint",
@@ -229,64 +246,35 @@ async function handleDecide(client2, args) {
229
246
  agent_id
230
247
  })
231
248
  );
232
- case "resolve":
233
- if (!decision_uid) return err("decision_uid is required");
234
- if (!chosen_option_uid) return err("chosen_option_uid is required");
249
+ case "resolve_decision":
250
+ if (!decision_uid) return err("decision_uid is required for resolve_decision");
251
+ if (!chosen_option_uid) return err("chosen_option_uid is required for resolve_decision");
235
252
  return ok(
236
253
  await client2.resolveDecision(decision_uid, chosen_option_uid, {
237
254
  summary,
238
255
  agent_id
239
256
  })
240
257
  );
241
- case "get_open":
258
+ case "get_open_decisions":
242
259
  return ok(await client2.getOpenDecisions());
243
260
  default:
244
- return err(`Unknown decide action: ${action}`);
245
- }
246
- }
247
- async function handleAction(client2, args) {
248
- const { action, label, summary, target_uid, props, agent_id } = args;
249
- switch (action) {
250
- case "create_flow":
251
- case "add_step":
252
- case "add_affordance":
253
- case "add_control":
254
- return ok(
255
- await client2.procedure({
256
- action,
257
- label,
258
- summary,
259
- target_uid,
260
- props,
261
- agent_id
262
- })
263
- );
264
- case "assess_risk":
265
- return ok(
266
- await client2.risk({
267
- action: "assess",
268
- label,
269
- summary,
270
- target_uid,
271
- props,
272
- agent_id
273
- })
274
- );
275
- case "get_assessments":
276
- return ok(
277
- await client2.risk({
278
- action: "get_assessments",
279
- target_uid,
280
- agent_id
281
- })
282
- );
283
- default:
284
- return err(`Unknown action: ${action}`);
261
+ return err(`Unknown commit action: ${action}`);
285
262
  }
286
263
  }
287
264
  async function handlePlan(client2, args) {
288
- const { action, label, summary, plan_uid, task_uid, status, props, agent_id } = args;
265
+ const {
266
+ action,
267
+ label,
268
+ summary,
269
+ plan_uid,
270
+ task_uid,
271
+ target_uid,
272
+ status,
273
+ props,
274
+ agent_id
275
+ } = args;
289
276
  switch (action) {
277
+ // Agent planning
290
278
  case "create_task":
291
279
  case "create_plan":
292
280
  case "add_step":
@@ -304,63 +292,70 @@ async function handlePlan(client2, args) {
304
292
  agent_id
305
293
  })
306
294
  );
295
+ // Execution tracking
307
296
  case "start_execution":
297
+ return ok(await client2.execution({ action: "start", task_uid, agent_id }));
298
+ case "complete_execution":
299
+ return ok(await client2.execution({ action: "complete", task_uid, agent_id }));
300
+ case "fail_execution":
301
+ return ok(await client2.execution({ action: "fail", task_uid, agent_id }));
302
+ // Governance
303
+ case "create_policy":
308
304
  return ok(
309
- await client2.execution({
310
- action: "start",
311
- task_uid,
312
- agent_id
313
- })
305
+ await client2.governance({ action: "create_policy", label, summary, props, agent_id })
314
306
  );
315
- case "complete_execution":
307
+ case "request_approval":
316
308
  return ok(
317
- await client2.execution({
318
- action: "complete",
319
- task_uid,
320
- agent_id
321
- })
309
+ await client2.governance({ action: "request_approval", label, summary, props, agent_id })
322
310
  );
323
- case "fail_execution":
311
+ case "resolve_approval":
324
312
  return ok(
325
- await client2.execution({
326
- action: "fail",
327
- task_uid,
328
- agent_id
329
- })
313
+ await client2.governance({ action: "resolve_approval", task_uid, props, agent_id })
330
314
  );
331
- case "create_policy":
315
+ case "get_pending":
316
+ return ok(await client2.governance({ action: "get_pending", agent_id }));
317
+ // Procedures (merged from mindgraph_action)
318
+ case "create_flow":
319
+ case "add_affordance":
320
+ case "add_control":
332
321
  return ok(
333
- await client2.governance({
334
- action: "create_policy",
322
+ await client2.procedure({
323
+ action,
335
324
  label,
336
325
  summary,
326
+ target_uid,
337
327
  props,
338
328
  agent_id
339
329
  })
340
330
  );
341
- case "request_approval":
331
+ case "add_procedure_step":
342
332
  return ok(
343
- await client2.governance({
344
- action: "request_approval",
333
+ await client2.procedure({
334
+ action: "add_step",
345
335
  label,
346
336
  summary,
337
+ target_uid,
347
338
  props,
348
339
  agent_id
349
340
  })
350
341
  );
351
- case "resolve_approval":
342
+ // Risk assessment (merged from mindgraph_action)
343
+ case "assess_risk":
352
344
  return ok(
353
- await client2.governance({
354
- action: "resolve_approval",
355
- task_uid,
345
+ await client2.risk({
346
+ action: "assess",
347
+ label,
348
+ summary,
349
+ target_uid,
356
350
  props,
357
351
  agent_id
358
352
  })
359
353
  );
360
- case "get_pending":
354
+ case "get_assessments":
361
355
  return ok(
362
- await client2.governance({
363
- action: "get_pending",
356
+ await client2.risk({
357
+ action: "get_assessments",
358
+ target_uid,
364
359
  agent_id
365
360
  })
366
361
  );
@@ -372,6 +367,11 @@ async function handleRetrieve(client2, args) {
372
367
  const {
373
368
  action,
374
369
  query,
370
+ start_uid,
371
+ end_uid,
372
+ max_depth,
373
+ direction,
374
+ edge_types,
375
375
  node_types,
376
376
  layer,
377
377
  limit,
@@ -406,6 +406,31 @@ async function handleRetrieve(client2, args) {
406
406
  agent_id
407
407
  })
408
408
  );
409
+ case "semantic":
410
+ if (!query) return err("query is required for semantic search");
411
+ return ok(
412
+ await client2.retrieve({
413
+ action: "semantic",
414
+ query,
415
+ k: limit,
416
+ node_types,
417
+ layer,
418
+ agent_id
419
+ })
420
+ );
421
+ case "hybrid":
422
+ if (!query) return err("query is required for hybrid search");
423
+ return ok(
424
+ await client2.retrieve({
425
+ action: "hybrid",
426
+ query,
427
+ k: limit,
428
+ node_types,
429
+ layer,
430
+ agent_id
431
+ })
432
+ );
433
+ // Structured queries
409
434
  case "active_goals":
410
435
  return ok(await client2.getGoals());
411
436
  case "open_questions":
@@ -437,6 +462,51 @@ async function handleRetrieve(client2, args) {
437
462
  agent_id
438
463
  })
439
464
  );
465
+ // Graph traversal
466
+ case "chain":
467
+ if (!start_uid) return err("start_uid is required for chain traversal");
468
+ return ok(
469
+ await client2.traverse({
470
+ action: "chain",
471
+ start_uid,
472
+ max_depth
473
+ })
474
+ );
475
+ case "neighborhood":
476
+ if (!start_uid) return err("start_uid is required for neighborhood traversal");
477
+ return ok(
478
+ await client2.traverse({
479
+ action: "neighborhood",
480
+ start_uid,
481
+ max_depth,
482
+ direction,
483
+ edge_types
484
+ })
485
+ );
486
+ case "path":
487
+ if (!start_uid) return err("start_uid is required for path traversal");
488
+ if (!end_uid) return err("end_uid is required for path traversal");
489
+ return ok(
490
+ await client2.traverse({
491
+ action: "path",
492
+ start_uid,
493
+ end_uid,
494
+ max_depth,
495
+ direction,
496
+ edge_types
497
+ })
498
+ );
499
+ case "subgraph":
500
+ if (!start_uid) return err("start_uid is required for subgraph traversal");
501
+ return ok(
502
+ await client2.traverse({
503
+ action: "subgraph",
504
+ start_uid,
505
+ max_depth,
506
+ direction,
507
+ edge_types
508
+ })
509
+ );
440
510
  default:
441
511
  return err(`Unknown retrieve action: ${action}`);
442
512
  }
@@ -493,72 +563,47 @@ var init_tools = __esm({
493
563
  "src/tools.ts"() {
494
564
  "use strict";
495
565
  TOOLS = [
496
- {
497
- name: "mindgraph_journal",
498
- description: "Quick, informal capture for the user's inner world: preferences ('I prefer dark mode'), reflections ('I've been thinking about...'), moods, daily notes, and anything subjective. Use this instead of mindgraph_capture when the content is personal/informal rather than a structured fact about the external world. Good for: likes/dislikes, feelings, habits, reminders-to-self, freeform notes.",
499
- inputSchema: {
500
- type: "object",
501
- properties: {
502
- label: {
503
- type: "string",
504
- description: "Brief title for the journal entry"
505
- },
506
- content: {
507
- type: "string",
508
- description: "The journal content/body text"
509
- },
510
- mood: {
511
- type: "string",
512
- description: "Emotional tone or mood tag"
513
- },
514
- tags: {
515
- type: "array",
516
- items: { type: "string" },
517
- description: "Categorization tags"
518
- },
519
- agent_id: {
520
- type: "string",
521
- description: "Agent identity"
522
- }
523
- },
524
- required: ["label", "content"]
525
- }
526
- },
527
566
  {
528
567
  name: "mindgraph_capture",
529
- description: "Capture structured facts about the external world into the Reality layer. Use proactively whenever the user mentions a named entity. Actions: 'entity' for people/orgs/places/events/nations/concepts (auto-deduplicates \u2014 safe to call even if already exists), 'observation' for factual statements about the world, 'source' for documents/URLs/references, 'snippet' for direct quotes from a source. Prefer this over mindgraph_journal when the content is an objective fact rather than a personal note.",
568
+ description: "Capture knowledge into the graph. Use 'entity' for people/orgs/places/events/nations/concepts (auto-deduplicates \u2014 safe to call even if already exists), 'observation' for factual statements, 'source' for documents/URLs, 'snippet' for quotes from a source, 'concept' for abstract ideas. Use 'journal' for quick personal notes, preferences, reflections, moods \u2014 anything subjective or informal. Prefer 'entity'/'observation' for objective facts, 'journal' for personal notes.",
530
569
  inputSchema: {
531
570
  type: "object",
532
571
  properties: {
533
572
  action: {
534
573
  type: "string",
535
- enum: ["entity", "observation", "source", "snippet", "concept"],
536
- description: "Type of reality to capture"
574
+ enum: ["entity", "observation", "source", "snippet", "concept", "journal"],
575
+ description: "Type of knowledge to capture"
537
576
  },
538
577
  label: {
539
578
  type: "string",
540
- description: "Name or title"
579
+ description: "Name, title, or brief heading"
541
580
  },
542
581
  summary: {
543
582
  type: "string",
544
- description: "Description or summary text"
583
+ description: "Description or summary text (for entity/observation/source/snippet/concept)"
584
+ },
585
+ content: {
586
+ type: "string",
587
+ description: "Journal content/body text (for action=journal)"
545
588
  },
546
589
  entity_type: {
547
590
  type: "string",
548
- enum: [
549
- "person",
550
- "organization",
551
- "place",
552
- "event",
553
- "nation",
554
- "concept"
555
- ],
591
+ enum: ["person", "organization", "place", "event", "nation", "concept"],
556
592
  description: "Entity subtype (only for action=entity)"
557
593
  },
558
594
  source_uid: {
559
595
  type: "string",
560
596
  description: "Source node UID (for snippets)"
561
597
  },
598
+ mood: {
599
+ type: "string",
600
+ description: "Emotional tone or mood tag (for action=journal)"
601
+ },
602
+ tags: {
603
+ type: "array",
604
+ items: { type: "string" },
605
+ description: "Categorization tags (for action=journal)"
606
+ },
562
607
  confidence: {
563
608
  type: "number",
564
609
  minimum: 0,
@@ -584,11 +629,33 @@ var init_tools = __esm({
584
629
  }
585
630
  },
586
631
  {
587
- name: "mindgraph_argue",
588
- description: "Record a claim WITH supporting evidence. Use when the user states something as true/false and provides reasoning or sources. Creates interconnected Claim + Evidence + Warrant nodes. Set confidence based on evidence strength: 0.9+ for well-sourced facts, 0.5-0.8 for plausible claims, below 0.5 for speculation. Prefer mindgraph_inquire instead when there's a question or hypothesis WITHOUT evidence yet.",
632
+ name: "mindgraph_reason",
633
+ description: "Record reasoning, claims, and open questions. Use 'claim' when the user states something as true/false with reasoning \u2014 creates interconnected Claim + Evidence + Warrant nodes. Set confidence by evidence: 0.9+ for well-sourced, 0.5-0.8 for plausible, <0.5 for speculation. Use 'open_question' for questions worth tracking, 'hypothesis' for testable predictions, 'theory' for explanatory frameworks, 'anomaly' for things that don't fit, 'assumption' for unstated beliefs. Prefer 'claim' when evidence exists, other actions when it doesn't yet.",
589
634
  inputSchema: {
590
635
  type: "object",
591
636
  properties: {
637
+ action: {
638
+ type: "string",
639
+ enum: [
640
+ "claim",
641
+ "question",
642
+ "open_question",
643
+ "hypothesis",
644
+ "theory",
645
+ "paradigm",
646
+ "anomaly",
647
+ "assumption"
648
+ ],
649
+ description: "Type of reasoning to record"
650
+ },
651
+ label: {
652
+ type: "string",
653
+ description: "The claim, question, or hypothesis statement (used for non-claim actions, or as fallback for claim if claim object omitted)"
654
+ },
655
+ summary: {
656
+ type: "string",
657
+ description: "Expanded description or context (for non-claim actions)"
658
+ },
592
659
  claim: {
593
660
  type: "object",
594
661
  properties: {
@@ -602,7 +669,7 @@ var init_tools = __esm({
602
669
  }
603
670
  },
604
671
  required: ["label"],
605
- description: "The central claim being argued"
672
+ description: "The central claim being argued (for action=claim)"
606
673
  },
607
674
  evidence: {
608
675
  type: "array",
@@ -614,7 +681,7 @@ var init_tools = __esm({
614
681
  },
615
682
  required: ["label"]
616
683
  },
617
- description: "Supporting evidence items"
684
+ description: "Supporting evidence items (for action=claim)"
618
685
  },
619
686
  warrant: {
620
687
  type: "object",
@@ -622,61 +689,26 @@ var init_tools = __esm({
622
689
  label: { type: "string" },
623
690
  content: { type: "string" }
624
691
  },
625
- description: "Logical warrant connecting evidence to claim"
692
+ description: "Logical warrant connecting evidence to claim (for action=claim)"
626
693
  },
627
694
  argument: {
628
695
  type: "object",
629
696
  properties: {
630
697
  label: { type: "string" }
631
698
  },
632
- description: "Top-level argument container"
633
- },
634
- agent_id: {
635
- type: "string",
636
- description: "Agent identity"
637
- }
638
- },
639
- required: ["claim"]
640
- }
641
- },
642
- {
643
- name: "mindgraph_inquire",
644
- description: "Record things that need investigation or are uncertain. Use 'open_question' when the user asks something worth tracking ('How does X work?'), 'hypothesis' for testable predictions, 'theory' for explanatory frameworks, 'anomaly' for things that don't fit existing understanding, 'assumption' for unstated beliefs worth surfacing. These stay in the graph as open items until resolved. Prefer mindgraph_argue instead when there IS evidence to attach.",
645
- inputSchema: {
646
- type: "object",
647
- properties: {
648
- action: {
649
- type: "string",
650
- enum: [
651
- "question",
652
- "open_question",
653
- "hypothesis",
654
- "theory",
655
- "paradigm",
656
- "anomaly",
657
- "assumption"
658
- ],
659
- description: "Type of epistemic inquiry"
660
- },
661
- label: {
662
- type: "string",
663
- description: "The question, hypothesis, or theory statement"
664
- },
665
- summary: {
666
- type: "string",
667
- description: "Expanded description or context"
699
+ description: "Top-level argument container (for action=claim)"
668
700
  },
669
701
  confidence: {
670
702
  type: "number",
671
703
  minimum: 0,
672
704
  maximum: 1,
673
- description: "Confidence level (0-1)"
705
+ description: "Confidence level (for non-claim actions)"
674
706
  },
675
707
  salience: {
676
708
  type: "number",
677
709
  minimum: 0,
678
710
  maximum: 1,
679
- description: "Importance score (0-1)"
711
+ description: "Importance score (for non-claim actions)"
680
712
  },
681
713
  props: {
682
714
  type: "object",
@@ -687,31 +719,48 @@ var init_tools = __esm({
687
719
  description: "Agent identity"
688
720
  }
689
721
  },
690
- required: ["action", "label"]
722
+ required: ["action"]
691
723
  }
692
724
  },
693
725
  {
694
726
  name: "mindgraph_commit",
695
- description: "Track the user's goals, projects, and milestones. Use 'goal' when the user expresses a desired outcome ('I want to learn Rust'), 'project' for organized efforts ('my blog redesign'), 'milestone' for checkpoints ('launch MVP by March'). Link milestones to projects and projects to goals via parent_uid. These appear in daily briefings and active goals queries.",
727
+ description: "Track goals, projects, milestones, and decisions. Use 'goal' for desired outcomes ('I want to learn Rust'), 'project' for organized efforts, 'milestone' for checkpoints. Link milestones to projects and projects to goals via parent_uid. Use 'open_decision' when facing a choice ('Postgres vs SQLite?'), 'add_option'/'add_constraint' to build out alternatives, 'resolve_decision' to pick one, 'get_open_decisions' to review pending choices.",
696
728
  inputSchema: {
697
729
  type: "object",
698
730
  properties: {
699
731
  action: {
700
732
  type: "string",
701
- enum: ["goal", "project", "milestone"],
702
- description: "Type of commitment"
733
+ enum: [
734
+ "goal",
735
+ "project",
736
+ "milestone",
737
+ "open_decision",
738
+ "add_option",
739
+ "add_constraint",
740
+ "resolve_decision",
741
+ "get_open_decisions"
742
+ ],
743
+ description: "Commitment or decision action"
703
744
  },
704
745
  label: {
705
746
  type: "string",
706
- description: "Name of the goal, project, or milestone"
747
+ description: "Name of the goal, project, milestone, decision, option, or constraint"
707
748
  },
708
749
  summary: {
709
750
  type: "string",
710
- description: "Description and success criteria"
751
+ description: "Description, success criteria, or rationale"
711
752
  },
712
753
  parent_uid: {
713
754
  type: "string",
714
- description: "Parent goal/project UID to link under"
755
+ description: "Parent goal/project UID to link under (for goal/project/milestone)"
756
+ },
757
+ decision_uid: {
758
+ type: "string",
759
+ description: "Decision UID (for add_option, add_constraint, resolve_decision)"
760
+ },
761
+ chosen_option_uid: {
762
+ type: "string",
763
+ description: "UID of the chosen option (for resolve_decision)"
715
764
  },
716
765
  confidence: {
717
766
  type: "number",
@@ -732,93 +781,12 @@ var init_tools = __esm({
732
781
  description: "Agent identity"
733
782
  }
734
783
  },
735
- required: ["action", "label"]
736
- }
737
- },
738
- {
739
- name: "mindgraph_decide",
740
- description: "Track decisions through their lifecycle. Use 'open_decision' when the user faces a choice ('Should I use Postgres or SQLite?'), 'add_option' to record each alternative, 'add_constraint' for requirements or dealbreakers, 'resolve' when a choice is made. Use 'get_open' to review pending decisions. This creates a structured decision record that can be referenced later.",
741
- inputSchema: {
742
- type: "object",
743
- properties: {
744
- action: {
745
- type: "string",
746
- enum: ["open_decision", "add_option", "add_constraint", "resolve", "get_open"],
747
- description: "Decision lifecycle action"
748
- },
749
- label: {
750
- type: "string",
751
- description: "Decision, option, or constraint label"
752
- },
753
- summary: {
754
- type: "string",
755
- description: "Description or rationale"
756
- },
757
- decision_uid: {
758
- type: "string",
759
- description: "Decision UID (for add_option, add_constraint, resolve)"
760
- },
761
- chosen_option_uid: {
762
- type: "string",
763
- description: "UID of the chosen option (for resolve)"
764
- },
765
- props: {
766
- type: "object",
767
- description: "Additional properties"
768
- },
769
- agent_id: {
770
- type: "string",
771
- description: "Agent identity"
772
- }
773
- },
774
- required: ["action"]
775
- }
776
- },
777
- {
778
- name: "mindgraph_action",
779
- description: "Record procedural knowledge and risk assessments. Use 'create_flow' for workflows/processes, 'add_step' for individual steps in a flow, 'add_affordance' for capabilities ('this API supports batch operations'), 'add_control' for guardrails/constraints. Use 'assess_risk' when the user identifies a risk or potential problem. Less commonly used than capture/argue/commit \u2014 reach for this when the conversation is about HOW to do something.",
780
- inputSchema: {
781
- type: "object",
782
- properties: {
783
- action: {
784
- type: "string",
785
- enum: [
786
- "create_flow",
787
- "add_step",
788
- "add_affordance",
789
- "add_control",
790
- "assess_risk",
791
- "get_assessments"
792
- ],
793
- description: "Action layer operation"
794
- },
795
- label: {
796
- type: "string",
797
- description: "Flow, step, affordance, control, or risk label"
798
- },
799
- summary: {
800
- type: "string",
801
- description: "Description"
802
- },
803
- target_uid: {
804
- type: "string",
805
- description: "Parent flow/step UID or target node for risk assessment"
806
- },
807
- props: {
808
- type: "object",
809
- description: "Type-specific properties (e.g. likelihood, impact, mitigation for risks)"
810
- },
811
- agent_id: {
812
- type: "string",
813
- description: "Agent identity"
814
- }
815
- },
816
784
  required: ["action"]
817
785
  }
818
786
  },
819
787
  {
820
788
  name: "mindgraph_plan",
821
- description: "Agent-level task management and governance. Use 'create_plan'/'create_task'/'add_step' for breaking down work into trackable items, 'update_status' to mark progress, 'start_execution'/'complete_execution'/'fail_execution' for execution tracking. Use 'create_policy' and 'request_approval' for governance workflows. Prefer mindgraph_commit for the user's goals/projects; use mindgraph_plan for agent-managed task breakdowns and execution.",
789
+ description: "Agent-level task management, governance, and procedural knowledge. Use 'create_plan'/'create_task'/'add_step' for task breakdowns, 'update_status' for progress, 'get_plan' to review. Use 'create_flow'/'add_procedure_step'/'add_affordance'/'add_control' for workflows and procedures. Use 'assess_risk'/'get_assessments' for risk analysis. Use 'create_policy'/'request_approval'/'resolve_approval'/'get_pending' for governance. Prefer mindgraph_commit for user goals/projects; use this for agent-managed execution.",
822
790
  inputSchema: {
823
791
  type: "object",
824
792
  properties: {
@@ -836,13 +804,19 @@ var init_tools = __esm({
836
804
  "create_policy",
837
805
  "request_approval",
838
806
  "resolve_approval",
839
- "get_pending"
807
+ "get_pending",
808
+ "create_flow",
809
+ "add_procedure_step",
810
+ "add_affordance",
811
+ "add_control",
812
+ "assess_risk",
813
+ "get_assessments"
840
814
  ],
841
- description: "Agent layer operation"
815
+ description: "Planning, procedure, or governance action"
842
816
  },
843
817
  label: {
844
818
  type: "string",
845
- description: "Task, plan, step, or policy label"
819
+ description: "Task, plan, step, flow, policy, or risk label"
846
820
  },
847
821
  summary: {
848
822
  type: "string",
@@ -854,7 +828,11 @@ var init_tools = __esm({
854
828
  },
855
829
  task_uid: {
856
830
  type: "string",
857
- description: "Task/step UID (for update_status, execution actions)"
831
+ description: "Task/step UID (for update_status, execution actions, resolve_approval)"
832
+ },
833
+ target_uid: {
834
+ type: "string",
835
+ description: "Parent flow/step UID or target node (for procedure/risk actions)"
858
836
  },
859
837
  status: {
860
838
  type: "string",
@@ -862,7 +840,7 @@ var init_tools = __esm({
862
840
  },
863
841
  props: {
864
842
  type: "object",
865
- description: "Additional properties"
843
+ description: "Additional properties (e.g. likelihood, impact, mitigation for risks)"
866
844
  },
867
845
  agent_id: {
868
846
  type: "string",
@@ -874,7 +852,7 @@ var init_tools = __esm({
874
852
  },
875
853
  {
876
854
  name: "mindgraph_retrieve",
877
- description: "Search the knowledge graph. Primary action: 'context' \u2014 pass a short keyword query (specific nouns/terms, not sentences) for FTS + graph traversal results. Use 'text' for fast keyword-only lookup. Other actions ('active_goals', 'open_questions', 'weak_claims', 'pending_approvals', 'unresolved_contradictions', 'layer', 'recent') are ONLY for when the user explicitly asks about those topics \u2014 never pre-fetch them.",
855
+ description: "Search and explore the knowledge graph. Use 'context' (default) for BM25 keyword retrieval \u2014 pass 1-3 discriminating keywords (proper nouns, technical terms), not sentences. GOOD: 'Kissinger NATO'. BAD: 'What is Kissinger\\'s view on NATO?'. Use 'semantic' when keywords return nothing \u2014 good for conceptual/fuzzy queries where user words differ from stored labels. Use 'hybrid' to combine keyword + semantic. Use 'text' for fast keyword-only lookup. Use 'neighborhood' to explore around a known node, 'chain' for reasoning chains, 'path' between two nodes, 'subgraph' for connected components. Other actions ('active_goals', 'open_questions', etc.) only when the user explicitly asks.",
878
856
  inputSchema: {
879
857
  type: "object",
880
858
  properties: {
@@ -883,19 +861,47 @@ var init_tools = __esm({
883
861
  enum: [
884
862
  "text",
885
863
  "context",
864
+ "semantic",
865
+ "hybrid",
886
866
  "active_goals",
887
867
  "open_questions",
888
868
  "weak_claims",
889
869
  "pending_approvals",
890
870
  "unresolved_contradictions",
891
871
  "layer",
892
- "recent"
872
+ "recent",
873
+ "chain",
874
+ "neighborhood",
875
+ "path",
876
+ "subgraph"
893
877
  ],
894
- description: "Retrieval strategy"
878
+ description: "Retrieval or traversal strategy"
895
879
  },
896
880
  query: {
897
881
  type: "string",
898
- description: "Keyword search query \u2014 use specific nouns and terms, e.g. 'Rust async runtime' not 'what do I know about async in Rust' (for text, context)"
882
+ description: "Search query \u2014 for 'text'/'context': 1-3 BM25 keywords, drop filler words. For 'semantic'/'hybrid': natural language is OK since it uses vector similarity."
883
+ },
884
+ start_uid: {
885
+ type: "string",
886
+ description: "Starting node UID (for chain, neighborhood, path, subgraph)"
887
+ },
888
+ end_uid: {
889
+ type: "string",
890
+ description: "Target node UID (for path)"
891
+ },
892
+ max_depth: {
893
+ type: "number",
894
+ description: "Maximum traversal depth (for chain, neighborhood, path, subgraph)"
895
+ },
896
+ direction: {
897
+ type: "string",
898
+ enum: ["outgoing", "incoming", "both"],
899
+ description: "Traversal direction (for neighborhood, subgraph)"
900
+ },
901
+ edge_types: {
902
+ type: "array",
903
+ items: { type: "string" },
904
+ description: "Filter by edge types (for traversal actions)"
899
905
  },
900
906
  node_types: {
901
907
  type: "array",
@@ -904,15 +910,8 @@ var init_tools = __esm({
904
910
  },
905
911
  layer: {
906
912
  type: "string",
907
- enum: [
908
- "reality",
909
- "epistemic",
910
- "intent",
911
- "action",
912
- "memory",
913
- "agent"
914
- ],
915
- description: "Filter by cognitive layer (for context, text, layer actions)"
913
+ enum: ["reality", "epistemic", "intent", "action", "memory", "agent"],
914
+ description: "Filter by cognitive layer"
916
915
  },
917
916
  limit: {
918
917
  type: "number",
@@ -1014,7 +1013,7 @@ async function main() {
1014
1013
  const transport = new import_stdio.StdioServerTransport();
1015
1014
  await server.connect(transport);
1016
1015
  console.error(
1017
- `MindGraph MCP server v0.3.2 running on stdio (${BASE_URL})`
1016
+ `MindGraph MCP server v0.4.0 running on stdio (${BASE_URL})`
1018
1017
  );
1019
1018
  }
1020
1019
  var import_server, import_stdio, import_types, import_mindgraph, API_KEY, BASE_URL, AGENT_ID, client, INSTRUCTIONS, server, PROMPTS;
@@ -1039,16 +1038,14 @@ var init_src = __esm({
1039
1038
  baseUrl: BASE_URL,
1040
1039
  apiKey: API_KEY
1041
1040
  });
1042
- INSTRUCTIONS = `You have access to a persistent knowledge graph via MindGraph.
1041
+ INSTRUCTIONS = `You have access to a persistent knowledge graph via MindGraph (6 tools).
1043
1042
 
1044
1043
  ## #1 RULE: Go straight to the user's topic
1045
1044
 
1046
1045
  When the user asks about something, your FIRST and ONLY action should be a SINGLE \`mindgraph_retrieve\` call with action "context" and keyword terms from their message. Nothing else first.
1047
1046
 
1048
1047
  **NEVER do any of these before addressing the user's topic:**
1049
- - Do NOT retrieve active_goals
1050
- - Do NOT retrieve open_questions
1051
- - Do NOT retrieve contradictions or weak_claims
1048
+ - Do NOT retrieve active_goals, open_questions, contradictions, or weak_claims
1052
1049
  - Do NOT follow a "session lifecycle" or "warm-up" sequence
1053
1050
  - Do NOT make multiple serial retrieve calls when one "context" call covers it
1054
1051
 
@@ -1056,45 +1053,55 @@ There is no session to open. There is no context to pre-load. Just search for wh
1056
1053
 
1057
1054
  **Example:** User says "Tell me about Indian philosophy and Taoism"
1058
1055
  \u2713 CORRECT: \`mindgraph_retrieve({action: "context", query: "Indian philosophy Taoism"})\`
1059
- \u2717 WRONG: First retrieve active_goals, then open_questions, then search for the topic
1056
+ \u2717 WRONG: First retrieve active_goals, then open_questions, then search
1057
+ \u2717 WRONG: \`mindgraph_retrieve({action: "context", query: "Tell me about Indian philosophy and Taoism"})\` \u2014 natural language won't match BM25
1058
+
1059
+ ## Search strategy \u2014 keyword first, semantic as fallback
1060
1060
 
1061
- ## Search query style
1061
+ The default search uses BM25 keyword matching. Query with 1\u20133 discriminating terms (proper nouns, technical terms). Drop filler words.
1062
1062
 
1063
- Full-text search (BM25) \u2014 use short keyword phrases, not natural language:
1064
- - GOOD: \`"Rust async runtime"\`, \`"Indian philosophy Taoism"\`
1065
- - BAD: \`"what do I know about async programming in Rust?"\`
1063
+ **Keyword examples:**
1064
+ - "What is Kissinger's view on NATO?" \u2192 query: \`"Kissinger NATO"\`
1065
+ - "Tell me about async in Rust" \u2192 query: \`"Rust async runtime"\`
1066
+ - "Implications of carbon tax?" \u2192 query: \`"carbon tax"\`
1067
+
1068
+ If keyword search returns no results, escalate:
1069
+ 1. Try synonyms (e.g. \`"global warming"\` instead of \`"climate change"\`)
1070
+ 2. Use \`action: "semantic"\` \u2014 vector similarity, natural language OK (e.g. \`"ways to manage stress"\` finds "mental health" nodes)
1071
+ 3. Use \`action: "hybrid"\` \u2014 combines BM25 + semantic for best coverage
1066
1072
 
1067
1073
  ## When to READ
1068
1074
 
1069
1075
  - User asks about topic X \u2192 \`mindgraph_retrieve\` action "context", query "X keywords"
1070
1076
  - User explicitly asks "what are my goals?" \u2192 action "active_goals"
1071
1077
  - User explicitly asks about open questions \u2192 action "open_questions"
1072
- - Before asserting something the user previously said \u2192 retrieve to check
1073
- - Parallelize independent calls in a single batch
1078
+ - Explore around a known node \u2192 action "neighborhood" with start_uid
1079
+ - Find connections between nodes \u2192 action "path" with start_uid + end_uid
1074
1080
 
1075
1081
  ## When to WRITE
1076
1082
 
1077
1083
  Capture knowledge when the user shares something worth remembering:
1078
1084
  - People/orgs/places/events \u2192 \`mindgraph_capture\` action "entity"
1079
- - Quick notes, preferences \u2192 \`mindgraph_journal\`
1085
+ - Quick notes, preferences \u2192 \`mindgraph_capture\` action "journal"
1080
1086
  - Factual observations \u2192 \`mindgraph_capture\` action "observation"
1081
- - Claims with evidence \u2192 \`mindgraph_argue\`
1082
- - Questions to track \u2192 \`mindgraph_inquire\` action "open_question"
1083
- - Goals or projects \u2192 \`mindgraph_commit\`
1084
- - Decisions \u2192 \`mindgraph_decide\`
1087
+ - Claims with evidence \u2192 \`mindgraph_reason\` action "claim"
1088
+ - Questions to track \u2192 \`mindgraph_reason\` action "open_question"
1089
+ - Goals or projects \u2192 \`mindgraph_commit\` action "goal"/"project"
1090
+ - Decisions \u2192 \`mindgraph_commit\` action "open_decision"
1085
1091
  - Long-form content \u2192 \`mindgraph_ingest\`
1086
1092
 
1087
1093
  ## Tool tips
1088
1094
 
1089
- - \`capture\` for structured/factual, \`journal\` for personal/informal
1090
- - \`argue\` when evidence exists, \`inquire\` for open questions
1091
- - \`text\` for fast lookup, \`context\` for rich retrieval with graph traversal
1095
+ - \`capture\`: "entity"/"observation" for facts, "journal" for personal/informal
1096
+ - \`reason\`: "claim" when evidence exists, "open_question"/"hypothesis" otherwise
1097
+ - \`retrieve\`: "context" (FTS default) \u2192 "semantic" (conceptual fallback) \u2192 "hybrid" (both)
1098
+ - \`retrieve\`: "neighborhood"/"chain"/"path"/"subgraph" for graph exploration
1092
1099
  - Confidence: 0.9+ for facts, 0.5-0.8 for uncertain, <0.5 for speculation
1093
1100
  - Don't narrate tool usage \u2014 capture naturally as part of conversation`;
1094
1101
  server = new import_server.Server(
1095
1102
  {
1096
1103
  name: "mindgraph",
1097
- version: "0.3.3"
1104
+ version: "0.4.0"
1098
1105
  },
1099
1106
  {
1100
1107
  capabilities: {
@@ -1227,7 +1234,7 @@ Capture knowledge when the user shares something worth remembering:
1227
1234
  role: "user",
1228
1235
  content: {
1229
1236
  type: "text",
1230
- text: `Search my knowledge graph for everything related to "${topic}". Use context retrieval with keyword queries to find entities, claims, evidence, questions, and any connected knowledge. Try multiple keyword variations to ensure broad coverage. Present a structured overview of what I know about this topic, highlighting any gaps or open questions.`
1237
+ text: `Search my knowledge graph for everything related to "${topic}". Use context retrieval with short BM25 keyword queries (1\u20133 discriminating terms extracted from the topic, not full sentences). Try multiple keyword variations and synonyms to ensure broad coverage. Present a structured overview of what I know about this topic, highlighting any gaps or open questions.`
1231
1238
  }
1232
1239
  }
1233
1240
  ]
@@ -1254,14 +1261,12 @@ Capture knowledge when the user shares something worth remembering:
1254
1261
  content: {
1255
1262
  type: "text",
1256
1263
  text: `Analyze the following conversation and capture all important information into my knowledge graph. Extract:
1257
- - Named entities (people, organizations, places, events)
1258
- - Factual claims and observations
1259
- - Decisions made or pending
1260
- - Goals or commitments mentioned
1261
- - Open questions raised
1262
- - Any hypotheses or theories discussed
1263
-
1264
- Use the appropriate MindGraph tools for each type of knowledge.
1264
+ - Named entities (people, organizations, places, events) \u2192 mindgraph_capture action "entity"
1265
+ - Factual claims and observations \u2192 mindgraph_capture action "observation" or mindgraph_reason action "claim"
1266
+ - Decisions made or pending \u2192 mindgraph_commit action "open_decision"
1267
+ - Goals or commitments mentioned \u2192 mindgraph_commit action "goal"/"project"
1268
+ - Open questions raised \u2192 mindgraph_reason action "open_question"
1269
+ - Any hypotheses or theories discussed \u2192 mindgraph_reason action "hypothesis"/"theory"
1265
1270
 
1266
1271
  Conversation:
1267
1272
  ${conversation}`
@@ -1322,7 +1327,7 @@ ${conversation}`
1322
1327
  {
1323
1328
  uriTemplate: "mindgraph://search/{query}",
1324
1329
  name: "Search Results",
1325
- description: "Full-text search across all nodes in the knowledge graph",
1330
+ description: "BM25 keyword search across all nodes \u2014 pass 1\u20133 discriminating terms (e.g. 'Kissinger NATO'), not natural language sentences",
1326
1331
  mimeType: "application/json"
1327
1332
  },
1328
1333
  {