mindgraph-mcp 0.3.4 → 0.5.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 +375 -358
  2. package/dist/index.js +375 -358
  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,
@@ -390,7 +390,7 @@ async function handleRetrieve(client2, args) {
390
390
  k: limit,
391
391
  node_types,
392
392
  layer,
393
- include_chunks,
393
+ include_chunks: include_chunks ?? false,
394
394
  include_graph
395
395
  })
396
396
  );
@@ -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,59 @@ async function handleRetrieve(client2, args) {
437
462
  agent_id
438
463
  })
439
464
  );
465
+ // Document inventory
466
+ case "document_index":
467
+ return ok(
468
+ await client2.getNodes({
469
+ node_type: "Document",
470
+ limit: limit ?? 100
471
+ })
472
+ );
473
+ // Graph traversal
474
+ case "chain":
475
+ if (!start_uid) return err("start_uid is required for chain traversal");
476
+ return ok(
477
+ await client2.traverse({
478
+ action: "chain",
479
+ start_uid,
480
+ max_depth
481
+ })
482
+ );
483
+ case "neighborhood":
484
+ if (!start_uid) return err("start_uid is required for neighborhood traversal");
485
+ return ok(
486
+ await client2.traverse({
487
+ action: "neighborhood",
488
+ start_uid,
489
+ max_depth,
490
+ direction,
491
+ edge_types
492
+ })
493
+ );
494
+ case "path":
495
+ if (!start_uid) return err("start_uid is required for path traversal");
496
+ if (!end_uid) return err("end_uid is required for path traversal");
497
+ return ok(
498
+ await client2.traverse({
499
+ action: "path",
500
+ start_uid,
501
+ end_uid,
502
+ max_depth,
503
+ direction,
504
+ edge_types
505
+ })
506
+ );
507
+ case "subgraph":
508
+ if (!start_uid) return err("start_uid is required for subgraph traversal");
509
+ return ok(
510
+ await client2.traverse({
511
+ action: "subgraph",
512
+ start_uid,
513
+ max_depth,
514
+ direction,
515
+ edge_types
516
+ })
517
+ );
440
518
  default:
441
519
  return err(`Unknown retrieve action: ${action}`);
442
520
  }
@@ -493,72 +571,47 @@ var init_tools = __esm({
493
571
  "src/tools.ts"() {
494
572
  "use strict";
495
573
  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
574
  {
528
575
  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.",
576
+ 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
577
  inputSchema: {
531
578
  type: "object",
532
579
  properties: {
533
580
  action: {
534
581
  type: "string",
535
- enum: ["entity", "observation", "source", "snippet", "concept"],
536
- description: "Type of reality to capture"
582
+ enum: ["entity", "observation", "source", "snippet", "concept", "journal"],
583
+ description: "Type of knowledge to capture"
537
584
  },
538
585
  label: {
539
586
  type: "string",
540
- description: "Name or title"
587
+ description: "Name, title, or brief heading"
541
588
  },
542
589
  summary: {
543
590
  type: "string",
544
- description: "Description or summary text"
591
+ description: "Description or summary text (for entity/observation/source/snippet/concept)"
592
+ },
593
+ content: {
594
+ type: "string",
595
+ description: "Journal content/body text (for action=journal)"
545
596
  },
546
597
  entity_type: {
547
598
  type: "string",
548
- enum: [
549
- "person",
550
- "organization",
551
- "place",
552
- "event",
553
- "nation",
554
- "concept"
555
- ],
599
+ enum: ["person", "organization", "place", "event", "nation", "concept"],
556
600
  description: "Entity subtype (only for action=entity)"
557
601
  },
558
602
  source_uid: {
559
603
  type: "string",
560
604
  description: "Source node UID (for snippets)"
561
605
  },
606
+ mood: {
607
+ type: "string",
608
+ description: "Emotional tone or mood tag (for action=journal)"
609
+ },
610
+ tags: {
611
+ type: "array",
612
+ items: { type: "string" },
613
+ description: "Categorization tags (for action=journal)"
614
+ },
562
615
  confidence: {
563
616
  type: "number",
564
617
  minimum: 0,
@@ -584,11 +637,33 @@ var init_tools = __esm({
584
637
  }
585
638
  },
586
639
  {
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.",
640
+ name: "mindgraph_reason",
641
+ 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
642
  inputSchema: {
590
643
  type: "object",
591
644
  properties: {
645
+ action: {
646
+ type: "string",
647
+ enum: [
648
+ "claim",
649
+ "question",
650
+ "open_question",
651
+ "hypothesis",
652
+ "theory",
653
+ "paradigm",
654
+ "anomaly",
655
+ "assumption"
656
+ ],
657
+ description: "Type of reasoning to record"
658
+ },
659
+ label: {
660
+ type: "string",
661
+ description: "The claim, question, or hypothesis statement (used for non-claim actions, or as fallback for claim if claim object omitted)"
662
+ },
663
+ summary: {
664
+ type: "string",
665
+ description: "Expanded description or context (for non-claim actions)"
666
+ },
592
667
  claim: {
593
668
  type: "object",
594
669
  properties: {
@@ -602,7 +677,7 @@ var init_tools = __esm({
602
677
  }
603
678
  },
604
679
  required: ["label"],
605
- description: "The central claim being argued"
680
+ description: "The central claim being argued (for action=claim)"
606
681
  },
607
682
  evidence: {
608
683
  type: "array",
@@ -614,7 +689,7 @@ var init_tools = __esm({
614
689
  },
615
690
  required: ["label"]
616
691
  },
617
- description: "Supporting evidence items"
692
+ description: "Supporting evidence items (for action=claim)"
618
693
  },
619
694
  warrant: {
620
695
  type: "object",
@@ -622,61 +697,26 @@ var init_tools = __esm({
622
697
  label: { type: "string" },
623
698
  content: { type: "string" }
624
699
  },
625
- description: "Logical warrant connecting evidence to claim"
700
+ description: "Logical warrant connecting evidence to claim (for action=claim)"
626
701
  },
627
702
  argument: {
628
703
  type: "object",
629
704
  properties: {
630
705
  label: { type: "string" }
631
706
  },
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"
707
+ description: "Top-level argument container (for action=claim)"
668
708
  },
669
709
  confidence: {
670
710
  type: "number",
671
711
  minimum: 0,
672
712
  maximum: 1,
673
- description: "Confidence level (0-1)"
713
+ description: "Confidence level (for non-claim actions)"
674
714
  },
675
715
  salience: {
676
716
  type: "number",
677
717
  minimum: 0,
678
718
  maximum: 1,
679
- description: "Importance score (0-1)"
719
+ description: "Importance score (for non-claim actions)"
680
720
  },
681
721
  props: {
682
722
  type: "object",
@@ -687,31 +727,48 @@ var init_tools = __esm({
687
727
  description: "Agent identity"
688
728
  }
689
729
  },
690
- required: ["action", "label"]
730
+ required: ["action"]
691
731
  }
692
732
  },
693
733
  {
694
734
  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.",
735
+ 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
736
  inputSchema: {
697
737
  type: "object",
698
738
  properties: {
699
739
  action: {
700
740
  type: "string",
701
- enum: ["goal", "project", "milestone"],
702
- description: "Type of commitment"
741
+ enum: [
742
+ "goal",
743
+ "project",
744
+ "milestone",
745
+ "open_decision",
746
+ "add_option",
747
+ "add_constraint",
748
+ "resolve_decision",
749
+ "get_open_decisions"
750
+ ],
751
+ description: "Commitment or decision action"
703
752
  },
704
753
  label: {
705
754
  type: "string",
706
- description: "Name of the goal, project, or milestone"
755
+ description: "Name of the goal, project, milestone, decision, option, or constraint"
707
756
  },
708
757
  summary: {
709
758
  type: "string",
710
- description: "Description and success criteria"
759
+ description: "Description, success criteria, or rationale"
711
760
  },
712
761
  parent_uid: {
713
762
  type: "string",
714
- description: "Parent goal/project UID to link under"
763
+ description: "Parent goal/project UID to link under (for goal/project/milestone)"
764
+ },
765
+ decision_uid: {
766
+ type: "string",
767
+ description: "Decision UID (for add_option, add_constraint, resolve_decision)"
768
+ },
769
+ chosen_option_uid: {
770
+ type: "string",
771
+ description: "UID of the chosen option (for resolve_decision)"
715
772
  },
716
773
  confidence: {
717
774
  type: "number",
@@ -732,93 +789,12 @@ var init_tools = __esm({
732
789
  description: "Agent identity"
733
790
  }
734
791
  },
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
792
  required: ["action"]
817
793
  }
818
794
  },
819
795
  {
820
796
  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.",
797
+ 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
798
  inputSchema: {
823
799
  type: "object",
824
800
  properties: {
@@ -836,13 +812,19 @@ var init_tools = __esm({
836
812
  "create_policy",
837
813
  "request_approval",
838
814
  "resolve_approval",
839
- "get_pending"
815
+ "get_pending",
816
+ "create_flow",
817
+ "add_procedure_step",
818
+ "add_affordance",
819
+ "add_control",
820
+ "assess_risk",
821
+ "get_assessments"
840
822
  ],
841
- description: "Agent layer operation"
823
+ description: "Planning, procedure, or governance action"
842
824
  },
843
825
  label: {
844
826
  type: "string",
845
- description: "Task, plan, step, or policy label"
827
+ description: "Task, plan, step, flow, policy, or risk label"
846
828
  },
847
829
  summary: {
848
830
  type: "string",
@@ -854,7 +836,11 @@ var init_tools = __esm({
854
836
  },
855
837
  task_uid: {
856
838
  type: "string",
857
- description: "Task/step UID (for update_status, execution actions)"
839
+ description: "Task/step UID (for update_status, execution actions, resolve_approval)"
840
+ },
841
+ target_uid: {
842
+ type: "string",
843
+ description: "Parent flow/step UID or target node (for procedure/risk actions)"
858
844
  },
859
845
  status: {
860
846
  type: "string",
@@ -862,7 +848,7 @@ var init_tools = __esm({
862
848
  },
863
849
  props: {
864
850
  type: "object",
865
- description: "Additional properties"
851
+ description: "Additional properties (e.g. likelihood, impact, mitigation for risks)"
866
852
  },
867
853
  agent_id: {
868
854
  type: "string",
@@ -874,7 +860,7 @@ var init_tools = __esm({
874
860
  },
875
861
  {
876
862
  name: "mindgraph_retrieve",
877
- description: "Search the knowledge graph using BM25 keyword matching. Primary action: 'context' \u2014 pass 1\u20133 discriminating keywords (proper nouns, technical terms) extracted from the user's question. Drop filler words (what, how, tell me about, implications of). GOOD: 'Kissinger NATO', 'Rust async runtime'. BAD: 'What is Kissinger\\'s view on NATO?'. 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.",
863
+ description: "Search and explore the knowledge graph. Use 'context' (default) for BM25 keyword retrieval \u2014 returns graph nodes only by default (labels, summaries, types, confidence); set include_chunks=true to also get full source text. Pass 1-3 discriminating keywords, not sentences. GOOD: 'Kissinger NATO'. BAD: 'What is Kissinger\\'s view on NATO?'. Use 'document_index' to list all ingested documents (titles, dates, UIDs) for orientation. Use 'semantic' when keywords return nothing \u2014 conceptual/fuzzy queries. Use 'hybrid' for keyword + semantic. Use 'text' for fast keyword-only. Use 'neighborhood'/'chain'/'path'/'subgraph' for graph traversal. Other actions ('active_goals', 'open_questions', etc.) only when the user explicitly asks.",
878
864
  inputSchema: {
879
865
  type: "object",
880
866
  properties: {
@@ -883,19 +869,48 @@ var init_tools = __esm({
883
869
  enum: [
884
870
  "text",
885
871
  "context",
872
+ "semantic",
873
+ "hybrid",
886
874
  "active_goals",
887
875
  "open_questions",
888
876
  "weak_claims",
889
877
  "pending_approvals",
890
878
  "unresolved_contradictions",
891
879
  "layer",
892
- "recent"
880
+ "recent",
881
+ "chain",
882
+ "neighborhood",
883
+ "path",
884
+ "subgraph",
885
+ "document_index"
893
886
  ],
894
- description: "Retrieval strategy"
887
+ description: "Retrieval or traversal strategy"
895
888
  },
896
889
  query: {
897
890
  type: "string",
898
- description: "BM25 keyword query \u2014 extract 1\u20133 discriminating terms from the user's question, drop filler words. User asks 'What is Kissinger's view on NATO?' \u2192 'Kissinger NATO'. User asks about async in Rust \u2192 'Rust async runtime'. NEVER pass natural language sentences. (for text, context)"
891
+ 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."
892
+ },
893
+ start_uid: {
894
+ type: "string",
895
+ description: "Starting node UID (for chain, neighborhood, path, subgraph)"
896
+ },
897
+ end_uid: {
898
+ type: "string",
899
+ description: "Target node UID (for path)"
900
+ },
901
+ max_depth: {
902
+ type: "number",
903
+ description: "Maximum traversal depth (for chain, neighborhood, path, subgraph)"
904
+ },
905
+ direction: {
906
+ type: "string",
907
+ enum: ["outgoing", "incoming", "both"],
908
+ description: "Traversal direction (for neighborhood, subgraph)"
909
+ },
910
+ edge_types: {
911
+ type: "array",
912
+ items: { type: "string" },
913
+ description: "Filter by edge types (for traversal actions)"
899
914
  },
900
915
  node_types: {
901
916
  type: "array",
@@ -904,15 +919,8 @@ var init_tools = __esm({
904
919
  },
905
920
  layer: {
906
921
  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)"
922
+ enum: ["reality", "epistemic", "intent", "action", "memory", "agent"],
923
+ description: "Filter by cognitive layer"
916
924
  },
917
925
  limit: {
918
926
  type: "number",
@@ -920,7 +928,7 @@ var init_tools = __esm({
920
928
  },
921
929
  include_chunks: {
922
930
  type: "boolean",
923
- description: "Include source document chunks in context results (default: true)"
931
+ description: "Include source document chunks in context results (default: false \u2014 set true to fetch full chunk text for citations or deep reading)"
924
932
  },
925
933
  include_graph: {
926
934
  type: "boolean",
@@ -1014,7 +1022,7 @@ async function main() {
1014
1022
  const transport = new import_stdio.StdioServerTransport();
1015
1023
  await server.connect(transport);
1016
1024
  console.error(
1017
- `MindGraph MCP server v0.3.2 running on stdio (${BASE_URL})`
1025
+ `MindGraph MCP server v0.5.0 running on stdio (${BASE_URL})`
1018
1026
  );
1019
1027
  }
1020
1028
  var import_server, import_stdio, import_types, import_mindgraph, API_KEY, BASE_URL, AGENT_ID, client, INSTRUCTIONS, server, PROMPTS;
@@ -1039,72 +1047,83 @@ var init_src = __esm({
1039
1047
  baseUrl: BASE_URL,
1040
1048
  apiKey: API_KEY
1041
1049
  });
1042
- INSTRUCTIONS = `You have access to a persistent knowledge graph via MindGraph.
1050
+ INSTRUCTIONS = `You have access to a persistent knowledge graph via MindGraph (6 tools).
1043
1051
 
1044
1052
  ## #1 RULE: Go straight to the user's topic
1045
1053
 
1046
1054
  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
1055
 
1048
1056
  **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
1057
+ - Do NOT retrieve active_goals, open_questions, contradictions, or weak_claims
1052
1058
  - Do NOT follow a "session lifecycle" or "warm-up" sequence
1053
1059
  - Do NOT make multiple serial retrieve calls when one "context" call covers it
1054
1060
 
1055
1061
  There is no session to open. There is no context to pre-load. Just search for what the user asked about.
1056
1062
 
1057
1063
  **Example:** User says "Tell me about Indian philosophy and Taoism"
1058
- \u2713 CORRECT: \`mindgraph_retrieve({action: "context", query: "Indian philosophy Taoism"})\` \u2014 extracted key nouns, dropped "Tell me about"
1059
- \u2717 WRONG: First retrieve active_goals, then open_questions, then search for the topic
1060
- \u2717 WRONG: \`mindgraph_retrieve({action: "context", query: "Tell me about Indian philosophy and Taoism"})\` \u2014 natural language sentence won't match BM25 index
1064
+ \u2713 CORRECT: \`mindgraph_retrieve({action: "context", query: "Indian philosophy Taoism"})\`
1065
+ \u2717 WRONG: First retrieve active_goals, then open_questions, then search
1066
+ \u2717 WRONG: \`mindgraph_retrieve({action: "context", query: "Tell me about Indian philosophy and Taoism"})\` \u2014 natural language won't match BM25
1067
+
1068
+ ## Two-phase retrieval protocol
1069
+
1070
+ **Phase 1 \u2014 Orient (default, fast, lightweight):**
1071
+ Use \`action: "context"\` with keywords. By default this returns only graph nodes \u2014 structured knowledge with labels, summaries, types, confidence scores, and edges. This is usually sufficient and keeps results compact.
1061
1072
 
1062
- ## Search query style \u2014 BM25 keyword matching
1073
+ **Phase 2 \u2014 Fetch source text (only when needed):**
1074
+ If you need the original source text behind a node (for verbatim quotes, citations, or when graph summaries lack detail), use \`action: "context"\` with \`include_chunks: true\`. This adds full document chunks (400-800 words each) to the response.
1063
1075
 
1064
- The search index uses BM25 keyword matching against node labels and summaries. It matches individual words, NOT meaning or concepts. Drop filler words like "what", "how", "implications of", "tell me about". Query with 1\u20133 discriminating terms (proper nouns, technical terms, domain-specific words).
1076
+ **Orientation shortcut:**
1077
+ - \`action: "document_index"\` \u2014 list all ingested documents (titles, dates, UIDs) to see what's in the graph
1065
1078
 
1066
- **Derive keywords from the user's question \u2014 examples:**
1067
- - User asks "What is Kissinger's view on NATO expansion?" \u2192 query: \`"Kissinger NATO"\`
1068
- - User asks "Tell me about async programming in Rust" \u2192 query: \`"Rust async runtime"\`
1069
- - User asks "How does Indian philosophy relate to Taoism?" \u2192 query: \`"Indian philosophy Taoism"\`
1070
- - User asks "What are the implications of carbon tax policy?" \u2192 query: \`"carbon tax"\`
1079
+ ## Search strategy \u2014 keyword first, semantic as fallback
1071
1080
 
1072
- **GOOD queries:** \`"Rust async runtime"\`, \`"Kissinger NATO"\`, \`"carbon tax emissions"\`
1073
- **BAD queries:** \`"what do I know about async programming in Rust?"\`, \`"how does X relate to Y"\`, \`"implications of climate change"\`
1081
+ The default search uses BM25 keyword matching. Query with 1\u20133 discriminating terms (proper nouns, technical terms). Drop filler words.
1074
1082
 
1075
- If the first query returns no results, try synonym or related terms (e.g. \`"global warming"\` instead of \`"climate change"\`).
1083
+ **Keyword examples:**
1084
+ - "What is Kissinger's view on NATO?" \u2192 query: \`"Kissinger NATO"\`
1085
+ - "Tell me about async in Rust" \u2192 query: \`"Rust async runtime"\`
1086
+ - "Implications of carbon tax?" \u2192 query: \`"carbon tax"\`
1087
+
1088
+ If keyword search returns no results, escalate:
1089
+ 1. Try synonyms (e.g. \`"global warming"\` instead of \`"climate change"\`)
1090
+ 2. Use \`action: "semantic"\` \u2014 vector similarity, natural language OK (e.g. \`"ways to manage stress"\` finds "mental health" nodes)
1091
+ 3. Use \`action: "hybrid"\` \u2014 combines BM25 + semantic for best coverage
1076
1092
 
1077
1093
  ## When to READ
1078
1094
 
1079
1095
  - User asks about topic X \u2192 \`mindgraph_retrieve\` action "context", query "X keywords"
1096
+ - User asks "what documents are in my graph?" \u2192 action "document_index"
1080
1097
  - User explicitly asks "what are my goals?" \u2192 action "active_goals"
1081
1098
  - User explicitly asks about open questions \u2192 action "open_questions"
1082
- - Before asserting something the user previously said \u2192 retrieve to check
1083
- - Parallelize independent calls in a single batch
1099
+ - Explore around a known node \u2192 action "neighborhood" with start_uid
1100
+ - Find connections between nodes \u2192 action "path" with start_uid + end_uid
1084
1101
 
1085
1102
  ## When to WRITE
1086
1103
 
1087
1104
  Capture knowledge when the user shares something worth remembering:
1088
1105
  - People/orgs/places/events \u2192 \`mindgraph_capture\` action "entity"
1089
- - Quick notes, preferences \u2192 \`mindgraph_journal\`
1106
+ - Quick notes, preferences \u2192 \`mindgraph_capture\` action "journal"
1090
1107
  - Factual observations \u2192 \`mindgraph_capture\` action "observation"
1091
- - Claims with evidence \u2192 \`mindgraph_argue\`
1092
- - Questions to track \u2192 \`mindgraph_inquire\` action "open_question"
1093
- - Goals or projects \u2192 \`mindgraph_commit\`
1094
- - Decisions \u2192 \`mindgraph_decide\`
1108
+ - Claims with evidence \u2192 \`mindgraph_reason\` action "claim"
1109
+ - Questions to track \u2192 \`mindgraph_reason\` action "open_question"
1110
+ - Goals or projects \u2192 \`mindgraph_commit\` action "goal"/"project"
1111
+ - Decisions \u2192 \`mindgraph_commit\` action "open_decision"
1095
1112
  - Long-form content \u2192 \`mindgraph_ingest\`
1096
1113
 
1097
1114
  ## Tool tips
1098
1115
 
1099
- - \`capture\` for structured/factual, \`journal\` for personal/informal
1100
- - \`argue\` when evidence exists, \`inquire\` for open questions
1101
- - \`text\` for fast lookup, \`context\` for rich retrieval with graph traversal
1116
+ - \`capture\`: "entity"/"observation" for facts, "journal" for personal/informal
1117
+ - \`reason\`: "claim" when evidence exists, "open_question"/"hypothesis" otherwise
1118
+ - \`retrieve\`: "context" returns graph nodes only by default \u2014 set include_chunks=true for source text
1119
+ - \`retrieve\`: "context" (FTS default) \u2192 "semantic" (conceptual fallback) \u2192 "hybrid" (both)
1120
+ - \`retrieve\`: "neighborhood"/"chain"/"path"/"subgraph" for graph exploration
1102
1121
  - Confidence: 0.9+ for facts, 0.5-0.8 for uncertain, <0.5 for speculation
1103
1122
  - Don't narrate tool usage \u2014 capture naturally as part of conversation`;
1104
1123
  server = new import_server.Server(
1105
1124
  {
1106
1125
  name: "mindgraph",
1107
- version: "0.3.4"
1126
+ version: "0.5.0"
1108
1127
  },
1109
1128
  {
1110
1129
  capabilities: {
@@ -1264,14 +1283,12 @@ Capture knowledge when the user shares something worth remembering:
1264
1283
  content: {
1265
1284
  type: "text",
1266
1285
  text: `Analyze the following conversation and capture all important information into my knowledge graph. Extract:
1267
- - Named entities (people, organizations, places, events)
1268
- - Factual claims and observations
1269
- - Decisions made or pending
1270
- - Goals or commitments mentioned
1271
- - Open questions raised
1272
- - Any hypotheses or theories discussed
1273
-
1274
- Use the appropriate MindGraph tools for each type of knowledge.
1286
+ - Named entities (people, organizations, places, events) \u2192 mindgraph_capture action "entity"
1287
+ - Factual claims and observations \u2192 mindgraph_capture action "observation" or mindgraph_reason action "claim"
1288
+ - Decisions made or pending \u2192 mindgraph_commit action "open_decision"
1289
+ - Goals or commitments mentioned \u2192 mindgraph_commit action "goal"/"project"
1290
+ - Open questions raised \u2192 mindgraph_reason action "open_question"
1291
+ - Any hypotheses or theories discussed \u2192 mindgraph_reason action "hypothesis"/"theory"
1275
1292
 
1276
1293
  Conversation:
1277
1294
  ${conversation}`