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/index.js CHANGED
@@ -8,72 +8,47 @@ var import_mindgraph = require("mindgraph");
8
8
 
9
9
  // src/tools.ts
10
10
  var TOOLS = [
11
- {
12
- name: "mindgraph_journal",
13
- 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.",
14
- inputSchema: {
15
- type: "object",
16
- properties: {
17
- label: {
18
- type: "string",
19
- description: "Brief title for the journal entry"
20
- },
21
- content: {
22
- type: "string",
23
- description: "The journal content/body text"
24
- },
25
- mood: {
26
- type: "string",
27
- description: "Emotional tone or mood tag"
28
- },
29
- tags: {
30
- type: "array",
31
- items: { type: "string" },
32
- description: "Categorization tags"
33
- },
34
- agent_id: {
35
- type: "string",
36
- description: "Agent identity"
37
- }
38
- },
39
- required: ["label", "content"]
40
- }
41
- },
42
11
  {
43
12
  name: "mindgraph_capture",
44
- 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.",
13
+ 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.",
45
14
  inputSchema: {
46
15
  type: "object",
47
16
  properties: {
48
17
  action: {
49
18
  type: "string",
50
- enum: ["entity", "observation", "source", "snippet", "concept"],
51
- description: "Type of reality to capture"
19
+ enum: ["entity", "observation", "source", "snippet", "concept", "journal"],
20
+ description: "Type of knowledge to capture"
52
21
  },
53
22
  label: {
54
23
  type: "string",
55
- description: "Name or title"
24
+ description: "Name, title, or brief heading"
56
25
  },
57
26
  summary: {
58
27
  type: "string",
59
- description: "Description or summary text"
28
+ description: "Description or summary text (for entity/observation/source/snippet/concept)"
29
+ },
30
+ content: {
31
+ type: "string",
32
+ description: "Journal content/body text (for action=journal)"
60
33
  },
61
34
  entity_type: {
62
35
  type: "string",
63
- enum: [
64
- "person",
65
- "organization",
66
- "place",
67
- "event",
68
- "nation",
69
- "concept"
70
- ],
36
+ enum: ["person", "organization", "place", "event", "nation", "concept"],
71
37
  description: "Entity subtype (only for action=entity)"
72
38
  },
73
39
  source_uid: {
74
40
  type: "string",
75
41
  description: "Source node UID (for snippets)"
76
42
  },
43
+ mood: {
44
+ type: "string",
45
+ description: "Emotional tone or mood tag (for action=journal)"
46
+ },
47
+ tags: {
48
+ type: "array",
49
+ items: { type: "string" },
50
+ description: "Categorization tags (for action=journal)"
51
+ },
77
52
  confidence: {
78
53
  type: "number",
79
54
  minimum: 0,
@@ -99,11 +74,33 @@ var TOOLS = [
99
74
  }
100
75
  },
101
76
  {
102
- name: "mindgraph_argue",
103
- 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.",
77
+ name: "mindgraph_reason",
78
+ 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.",
104
79
  inputSchema: {
105
80
  type: "object",
106
81
  properties: {
82
+ action: {
83
+ type: "string",
84
+ enum: [
85
+ "claim",
86
+ "question",
87
+ "open_question",
88
+ "hypothesis",
89
+ "theory",
90
+ "paradigm",
91
+ "anomaly",
92
+ "assumption"
93
+ ],
94
+ description: "Type of reasoning to record"
95
+ },
96
+ label: {
97
+ type: "string",
98
+ description: "The claim, question, or hypothesis statement (used for non-claim actions, or as fallback for claim if claim object omitted)"
99
+ },
100
+ summary: {
101
+ type: "string",
102
+ description: "Expanded description or context (for non-claim actions)"
103
+ },
107
104
  claim: {
108
105
  type: "object",
109
106
  properties: {
@@ -117,7 +114,7 @@ var TOOLS = [
117
114
  }
118
115
  },
119
116
  required: ["label"],
120
- description: "The central claim being argued"
117
+ description: "The central claim being argued (for action=claim)"
121
118
  },
122
119
  evidence: {
123
120
  type: "array",
@@ -129,7 +126,7 @@ var TOOLS = [
129
126
  },
130
127
  required: ["label"]
131
128
  },
132
- description: "Supporting evidence items"
129
+ description: "Supporting evidence items (for action=claim)"
133
130
  },
134
131
  warrant: {
135
132
  type: "object",
@@ -137,61 +134,26 @@ var TOOLS = [
137
134
  label: { type: "string" },
138
135
  content: { type: "string" }
139
136
  },
140
- description: "Logical warrant connecting evidence to claim"
137
+ description: "Logical warrant connecting evidence to claim (for action=claim)"
141
138
  },
142
139
  argument: {
143
140
  type: "object",
144
141
  properties: {
145
142
  label: { type: "string" }
146
143
  },
147
- description: "Top-level argument container"
148
- },
149
- agent_id: {
150
- type: "string",
151
- description: "Agent identity"
152
- }
153
- },
154
- required: ["claim"]
155
- }
156
- },
157
- {
158
- name: "mindgraph_inquire",
159
- 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.",
160
- inputSchema: {
161
- type: "object",
162
- properties: {
163
- action: {
164
- type: "string",
165
- enum: [
166
- "question",
167
- "open_question",
168
- "hypothesis",
169
- "theory",
170
- "paradigm",
171
- "anomaly",
172
- "assumption"
173
- ],
174
- description: "Type of epistemic inquiry"
175
- },
176
- label: {
177
- type: "string",
178
- description: "The question, hypothesis, or theory statement"
179
- },
180
- summary: {
181
- type: "string",
182
- description: "Expanded description or context"
144
+ description: "Top-level argument container (for action=claim)"
183
145
  },
184
146
  confidence: {
185
147
  type: "number",
186
148
  minimum: 0,
187
149
  maximum: 1,
188
- description: "Confidence level (0-1)"
150
+ description: "Confidence level (for non-claim actions)"
189
151
  },
190
152
  salience: {
191
153
  type: "number",
192
154
  minimum: 0,
193
155
  maximum: 1,
194
- description: "Importance score (0-1)"
156
+ description: "Importance score (for non-claim actions)"
195
157
  },
196
158
  props: {
197
159
  type: "object",
@@ -202,31 +164,48 @@ var TOOLS = [
202
164
  description: "Agent identity"
203
165
  }
204
166
  },
205
- required: ["action", "label"]
167
+ required: ["action"]
206
168
  }
207
169
  },
208
170
  {
209
171
  name: "mindgraph_commit",
210
- 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.",
172
+ 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.",
211
173
  inputSchema: {
212
174
  type: "object",
213
175
  properties: {
214
176
  action: {
215
177
  type: "string",
216
- enum: ["goal", "project", "milestone"],
217
- description: "Type of commitment"
178
+ enum: [
179
+ "goal",
180
+ "project",
181
+ "milestone",
182
+ "open_decision",
183
+ "add_option",
184
+ "add_constraint",
185
+ "resolve_decision",
186
+ "get_open_decisions"
187
+ ],
188
+ description: "Commitment or decision action"
218
189
  },
219
190
  label: {
220
191
  type: "string",
221
- description: "Name of the goal, project, or milestone"
192
+ description: "Name of the goal, project, milestone, decision, option, or constraint"
222
193
  },
223
194
  summary: {
224
195
  type: "string",
225
- description: "Description and success criteria"
196
+ description: "Description, success criteria, or rationale"
226
197
  },
227
198
  parent_uid: {
228
199
  type: "string",
229
- description: "Parent goal/project UID to link under"
200
+ description: "Parent goal/project UID to link under (for goal/project/milestone)"
201
+ },
202
+ decision_uid: {
203
+ type: "string",
204
+ description: "Decision UID (for add_option, add_constraint, resolve_decision)"
205
+ },
206
+ chosen_option_uid: {
207
+ type: "string",
208
+ description: "UID of the chosen option (for resolve_decision)"
230
209
  },
231
210
  confidence: {
232
211
  type: "number",
@@ -247,93 +226,12 @@ var TOOLS = [
247
226
  description: "Agent identity"
248
227
  }
249
228
  },
250
- required: ["action", "label"]
251
- }
252
- },
253
- {
254
- name: "mindgraph_decide",
255
- 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.",
256
- inputSchema: {
257
- type: "object",
258
- properties: {
259
- action: {
260
- type: "string",
261
- enum: ["open_decision", "add_option", "add_constraint", "resolve", "get_open"],
262
- description: "Decision lifecycle action"
263
- },
264
- label: {
265
- type: "string",
266
- description: "Decision, option, or constraint label"
267
- },
268
- summary: {
269
- type: "string",
270
- description: "Description or rationale"
271
- },
272
- decision_uid: {
273
- type: "string",
274
- description: "Decision UID (for add_option, add_constraint, resolve)"
275
- },
276
- chosen_option_uid: {
277
- type: "string",
278
- description: "UID of the chosen option (for resolve)"
279
- },
280
- props: {
281
- type: "object",
282
- description: "Additional properties"
283
- },
284
- agent_id: {
285
- type: "string",
286
- description: "Agent identity"
287
- }
288
- },
289
- required: ["action"]
290
- }
291
- },
292
- {
293
- name: "mindgraph_action",
294
- 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.",
295
- inputSchema: {
296
- type: "object",
297
- properties: {
298
- action: {
299
- type: "string",
300
- enum: [
301
- "create_flow",
302
- "add_step",
303
- "add_affordance",
304
- "add_control",
305
- "assess_risk",
306
- "get_assessments"
307
- ],
308
- description: "Action layer operation"
309
- },
310
- label: {
311
- type: "string",
312
- description: "Flow, step, affordance, control, or risk label"
313
- },
314
- summary: {
315
- type: "string",
316
- description: "Description"
317
- },
318
- target_uid: {
319
- type: "string",
320
- description: "Parent flow/step UID or target node for risk assessment"
321
- },
322
- props: {
323
- type: "object",
324
- description: "Type-specific properties (e.g. likelihood, impact, mitigation for risks)"
325
- },
326
- agent_id: {
327
- type: "string",
328
- description: "Agent identity"
329
- }
330
- },
331
229
  required: ["action"]
332
230
  }
333
231
  },
334
232
  {
335
233
  name: "mindgraph_plan",
336
- 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.",
234
+ 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.",
337
235
  inputSchema: {
338
236
  type: "object",
339
237
  properties: {
@@ -351,13 +249,19 @@ var TOOLS = [
351
249
  "create_policy",
352
250
  "request_approval",
353
251
  "resolve_approval",
354
- "get_pending"
252
+ "get_pending",
253
+ "create_flow",
254
+ "add_procedure_step",
255
+ "add_affordance",
256
+ "add_control",
257
+ "assess_risk",
258
+ "get_assessments"
355
259
  ],
356
- description: "Agent layer operation"
260
+ description: "Planning, procedure, or governance action"
357
261
  },
358
262
  label: {
359
263
  type: "string",
360
- description: "Task, plan, step, or policy label"
264
+ description: "Task, plan, step, flow, policy, or risk label"
361
265
  },
362
266
  summary: {
363
267
  type: "string",
@@ -369,7 +273,11 @@ var TOOLS = [
369
273
  },
370
274
  task_uid: {
371
275
  type: "string",
372
- description: "Task/step UID (for update_status, execution actions)"
276
+ description: "Task/step UID (for update_status, execution actions, resolve_approval)"
277
+ },
278
+ target_uid: {
279
+ type: "string",
280
+ description: "Parent flow/step UID or target node (for procedure/risk actions)"
373
281
  },
374
282
  status: {
375
283
  type: "string",
@@ -377,7 +285,7 @@ var TOOLS = [
377
285
  },
378
286
  props: {
379
287
  type: "object",
380
- description: "Additional properties"
288
+ description: "Additional properties (e.g. likelihood, impact, mitigation for risks)"
381
289
  },
382
290
  agent_id: {
383
291
  type: "string",
@@ -389,7 +297,7 @@ var TOOLS = [
389
297
  },
390
298
  {
391
299
  name: "mindgraph_retrieve",
392
- 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.",
300
+ 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.",
393
301
  inputSchema: {
394
302
  type: "object",
395
303
  properties: {
@@ -398,19 +306,48 @@ var TOOLS = [
398
306
  enum: [
399
307
  "text",
400
308
  "context",
309
+ "semantic",
310
+ "hybrid",
401
311
  "active_goals",
402
312
  "open_questions",
403
313
  "weak_claims",
404
314
  "pending_approvals",
405
315
  "unresolved_contradictions",
406
316
  "layer",
407
- "recent"
317
+ "recent",
318
+ "chain",
319
+ "neighborhood",
320
+ "path",
321
+ "subgraph",
322
+ "document_index"
408
323
  ],
409
- description: "Retrieval strategy"
324
+ description: "Retrieval or traversal strategy"
410
325
  },
411
326
  query: {
412
327
  type: "string",
413
- 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)"
328
+ 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."
329
+ },
330
+ start_uid: {
331
+ type: "string",
332
+ description: "Starting node UID (for chain, neighborhood, path, subgraph)"
333
+ },
334
+ end_uid: {
335
+ type: "string",
336
+ description: "Target node UID (for path)"
337
+ },
338
+ max_depth: {
339
+ type: "number",
340
+ description: "Maximum traversal depth (for chain, neighborhood, path, subgraph)"
341
+ },
342
+ direction: {
343
+ type: "string",
344
+ enum: ["outgoing", "incoming", "both"],
345
+ description: "Traversal direction (for neighborhood, subgraph)"
346
+ },
347
+ edge_types: {
348
+ type: "array",
349
+ items: { type: "string" },
350
+ description: "Filter by edge types (for traversal actions)"
414
351
  },
415
352
  node_types: {
416
353
  type: "array",
@@ -419,15 +356,8 @@ var TOOLS = [
419
356
  },
420
357
  layer: {
421
358
  type: "string",
422
- enum: [
423
- "reality",
424
- "epistemic",
425
- "intent",
426
- "action",
427
- "memory",
428
- "agent"
429
- ],
430
- description: "Filter by cognitive layer (for context, text, layer actions)"
359
+ enum: ["reality", "epistemic", "intent", "action", "memory", "agent"],
360
+ description: "Filter by cognitive layer"
431
361
  },
432
362
  limit: {
433
363
  type: "number",
@@ -435,7 +365,7 @@ var TOOLS = [
435
365
  },
436
366
  include_chunks: {
437
367
  type: "boolean",
438
- description: "Include source document chunks in context results (default: true)"
368
+ description: "Include source document chunks in context results (default: false \u2014 set true to fetch full chunk text for citations or deep reading)"
439
369
  },
440
370
  include_graph: {
441
371
  type: "boolean",
@@ -534,20 +464,12 @@ function err(message) {
534
464
  async function handleTool(client2, name, args) {
535
465
  try {
536
466
  switch (name) {
537
- case "mindgraph_journal":
538
- return await handleJournal(client2, args);
539
467
  case "mindgraph_capture":
540
468
  return await handleCapture(client2, args);
541
- case "mindgraph_argue":
542
- return await handleArgue(client2, args);
543
- case "mindgraph_inquire":
544
- return await handleInquire(client2, args);
469
+ case "mindgraph_reason":
470
+ return await handleReason(client2, args);
545
471
  case "mindgraph_commit":
546
472
  return await handleCommit(client2, args);
547
- case "mindgraph_decide":
548
- return await handleDecide(client2, args);
549
- case "mindgraph_action":
550
- return await handleAction(client2, args);
551
473
  case "mindgraph_plan":
552
474
  return await handlePlan(client2, args);
553
475
  case "mindgraph_retrieve":
@@ -562,31 +484,29 @@ async function handleTool(client2, name, args) {
562
484
  return err(message);
563
485
  }
564
486
  }
565
- async function handleJournal(client2, args) {
566
- const { label, content, mood, tags, agent_id } = args;
567
- const props = { content };
568
- if (mood) props.mood = mood;
569
- if (tags) props.tags = tags;
570
- const result = await client2.journal(
571
- label,
572
- props,
573
- { agent_id }
574
- );
575
- return ok(result);
576
- }
577
487
  async function handleCapture(client2, args) {
578
488
  const {
579
489
  action,
580
490
  label,
581
491
  summary,
492
+ content,
582
493
  entity_type,
583
494
  source_uid,
495
+ mood,
496
+ tags,
584
497
  confidence,
585
498
  salience,
586
499
  props,
587
500
  agent_id
588
501
  } = args;
589
502
  switch (action) {
503
+ case "journal": {
504
+ if (!content) return err("content is required for action=journal");
505
+ const journalProps = { content };
506
+ if (mood) journalProps.mood = mood;
507
+ if (tags) journalProps.tags = tags;
508
+ return ok(await client2.journal(label, journalProps, { agent_id }));
509
+ }
590
510
  case "entity": {
591
511
  const type = entity_type || "concept";
592
512
  const entityProps = { ...props };
@@ -660,58 +580,85 @@ async function handleCapture(client2, args) {
660
580
  return err(`Unknown capture action: ${action}`);
661
581
  }
662
582
  }
663
- async function handleArgue(client2, args) {
664
- const { claim, evidence, warrant, argument, agent_id } = args;
665
- const result = await client2.argue({
583
+ async function handleReason(client2, args) {
584
+ const {
585
+ action,
586
+ label,
587
+ summary,
666
588
  claim,
667
589
  evidence,
668
590
  warrant,
669
591
  argument,
670
- agent_id
671
- });
672
- return ok(result);
673
- }
674
- async function handleInquire(client2, args) {
675
- const { action, label, summary, confidence, salience, props, agent_id } = args;
676
- const result = await client2.inquire({
677
- action,
678
- label,
679
- summary,
680
592
  confidence,
681
593
  salience,
682
594
  props,
683
595
  agent_id
684
- });
685
- return ok(result);
596
+ } = args;
597
+ if (action === "claim") {
598
+ const claimObj = claim || (label ? { label, confidence } : null);
599
+ if (!claimObj) return err("claim object or label is required for action=claim");
600
+ return ok(
601
+ await client2.argue({
602
+ claim: claimObj,
603
+ evidence,
604
+ warrant,
605
+ argument,
606
+ agent_id
607
+ })
608
+ );
609
+ }
610
+ if (!label) return err(`label is required for action=${action}`);
611
+ return ok(
612
+ await client2.inquire({
613
+ action,
614
+ label,
615
+ summary,
616
+ confidence,
617
+ salience,
618
+ props,
619
+ agent_id
620
+ })
621
+ );
686
622
  }
687
623
  async function handleCommit(client2, args) {
688
- const { action, label, summary, parent_uid, confidence, salience, props, agent_id } = args;
689
- const result = await client2.commit({
624
+ const {
690
625
  action,
691
626
  label,
692
627
  summary,
693
628
  parent_uid,
629
+ decision_uid,
630
+ chosen_option_uid,
694
631
  confidence,
695
632
  salience,
696
633
  props,
697
634
  agent_id
698
- });
699
- return ok(result);
700
- }
701
- async function handleDecide(client2, args) {
702
- const { action, label, summary, decision_uid, chosen_option_uid, props, agent_id } = args;
635
+ } = args;
703
636
  switch (action) {
637
+ case "goal":
638
+ case "project":
639
+ case "milestone":
640
+ if (!label) return err(`label is required for action=${action}`);
641
+ return ok(
642
+ await client2.commit({
643
+ action,
644
+ label,
645
+ summary,
646
+ parent_uid,
647
+ confidence,
648
+ salience,
649
+ props,
650
+ agent_id
651
+ })
652
+ );
704
653
  case "open_decision":
705
654
  if (!label) return err("label is required for open_decision");
706
655
  return ok(await client2.openDecision(label, { summary, props, agent_id }));
707
656
  case "add_option":
708
- if (!decision_uid) return err("decision_uid is required");
657
+ if (!decision_uid) return err("decision_uid is required for add_option");
709
658
  if (!label) return err("label is required for add_option");
710
- return ok(
711
- await client2.addOption(decision_uid, label, { summary, props, agent_id })
712
- );
659
+ return ok(await client2.addOption(decision_uid, label, { summary, props, agent_id }));
713
660
  case "add_constraint":
714
- if (!decision_uid) return err("decision_uid is required");
661
+ if (!decision_uid) return err("decision_uid is required for add_constraint");
715
662
  return ok(
716
663
  await client2.deliberate({
717
664
  action: "add_constraint",
@@ -722,64 +669,35 @@ async function handleDecide(client2, args) {
722
669
  agent_id
723
670
  })
724
671
  );
725
- case "resolve":
726
- if (!decision_uid) return err("decision_uid is required");
727
- if (!chosen_option_uid) return err("chosen_option_uid is required");
672
+ case "resolve_decision":
673
+ if (!decision_uid) return err("decision_uid is required for resolve_decision");
674
+ if (!chosen_option_uid) return err("chosen_option_uid is required for resolve_decision");
728
675
  return ok(
729
676
  await client2.resolveDecision(decision_uid, chosen_option_uid, {
730
677
  summary,
731
678
  agent_id
732
679
  })
733
680
  );
734
- case "get_open":
681
+ case "get_open_decisions":
735
682
  return ok(await client2.getOpenDecisions());
736
683
  default:
737
- return err(`Unknown decide action: ${action}`);
738
- }
739
- }
740
- async function handleAction(client2, args) {
741
- const { action, label, summary, target_uid, props, agent_id } = args;
742
- switch (action) {
743
- case "create_flow":
744
- case "add_step":
745
- case "add_affordance":
746
- case "add_control":
747
- return ok(
748
- await client2.procedure({
749
- action,
750
- label,
751
- summary,
752
- target_uid,
753
- props,
754
- agent_id
755
- })
756
- );
757
- case "assess_risk":
758
- return ok(
759
- await client2.risk({
760
- action: "assess",
761
- label,
762
- summary,
763
- target_uid,
764
- props,
765
- agent_id
766
- })
767
- );
768
- case "get_assessments":
769
- return ok(
770
- await client2.risk({
771
- action: "get_assessments",
772
- target_uid,
773
- agent_id
774
- })
775
- );
776
- default:
777
- return err(`Unknown action: ${action}`);
684
+ return err(`Unknown commit action: ${action}`);
778
685
  }
779
686
  }
780
687
  async function handlePlan(client2, args) {
781
- const { action, label, summary, plan_uid, task_uid, status, props, agent_id } = args;
688
+ const {
689
+ action,
690
+ label,
691
+ summary,
692
+ plan_uid,
693
+ task_uid,
694
+ target_uid,
695
+ status,
696
+ props,
697
+ agent_id
698
+ } = args;
782
699
  switch (action) {
700
+ // Agent planning
783
701
  case "create_task":
784
702
  case "create_plan":
785
703
  case "add_step":
@@ -797,63 +715,70 @@ async function handlePlan(client2, args) {
797
715
  agent_id
798
716
  })
799
717
  );
718
+ // Execution tracking
800
719
  case "start_execution":
720
+ return ok(await client2.execution({ action: "start", task_uid, agent_id }));
721
+ case "complete_execution":
722
+ return ok(await client2.execution({ action: "complete", task_uid, agent_id }));
723
+ case "fail_execution":
724
+ return ok(await client2.execution({ action: "fail", task_uid, agent_id }));
725
+ // Governance
726
+ case "create_policy":
801
727
  return ok(
802
- await client2.execution({
803
- action: "start",
804
- task_uid,
805
- agent_id
806
- })
728
+ await client2.governance({ action: "create_policy", label, summary, props, agent_id })
807
729
  );
808
- case "complete_execution":
730
+ case "request_approval":
809
731
  return ok(
810
- await client2.execution({
811
- action: "complete",
812
- task_uid,
813
- agent_id
814
- })
732
+ await client2.governance({ action: "request_approval", label, summary, props, agent_id })
815
733
  );
816
- case "fail_execution":
734
+ case "resolve_approval":
817
735
  return ok(
818
- await client2.execution({
819
- action: "fail",
820
- task_uid,
821
- agent_id
822
- })
736
+ await client2.governance({ action: "resolve_approval", task_uid, props, agent_id })
823
737
  );
824
- case "create_policy":
738
+ case "get_pending":
739
+ return ok(await client2.governance({ action: "get_pending", agent_id }));
740
+ // Procedures (merged from mindgraph_action)
741
+ case "create_flow":
742
+ case "add_affordance":
743
+ case "add_control":
825
744
  return ok(
826
- await client2.governance({
827
- action: "create_policy",
745
+ await client2.procedure({
746
+ action,
828
747
  label,
829
748
  summary,
749
+ target_uid,
830
750
  props,
831
751
  agent_id
832
752
  })
833
753
  );
834
- case "request_approval":
754
+ case "add_procedure_step":
835
755
  return ok(
836
- await client2.governance({
837
- action: "request_approval",
756
+ await client2.procedure({
757
+ action: "add_step",
838
758
  label,
839
759
  summary,
760
+ target_uid,
840
761
  props,
841
762
  agent_id
842
763
  })
843
764
  );
844
- case "resolve_approval":
765
+ // Risk assessment (merged from mindgraph_action)
766
+ case "assess_risk":
845
767
  return ok(
846
- await client2.governance({
847
- action: "resolve_approval",
848
- task_uid,
768
+ await client2.risk({
769
+ action: "assess",
770
+ label,
771
+ summary,
772
+ target_uid,
849
773
  props,
850
774
  agent_id
851
775
  })
852
776
  );
853
- case "get_pending":
777
+ case "get_assessments":
854
778
  return ok(
855
- await client2.governance({
856
- action: "get_pending",
779
+ await client2.risk({
780
+ action: "get_assessments",
781
+ target_uid,
857
782
  agent_id
858
783
  })
859
784
  );
@@ -865,6 +790,11 @@ async function handleRetrieve(client2, args) {
865
790
  const {
866
791
  action,
867
792
  query,
793
+ start_uid,
794
+ end_uid,
795
+ max_depth,
796
+ direction,
797
+ edge_types,
868
798
  node_types,
869
799
  layer,
870
800
  limit,
@@ -883,7 +813,7 @@ async function handleRetrieve(client2, args) {
883
813
  k: limit,
884
814
  node_types,
885
815
  layer,
886
- include_chunks,
816
+ include_chunks: include_chunks ?? false,
887
817
  include_graph
888
818
  })
889
819
  );
@@ -899,6 +829,31 @@ async function handleRetrieve(client2, args) {
899
829
  agent_id
900
830
  })
901
831
  );
832
+ case "semantic":
833
+ if (!query) return err("query is required for semantic search");
834
+ return ok(
835
+ await client2.retrieve({
836
+ action: "semantic",
837
+ query,
838
+ k: limit,
839
+ node_types,
840
+ layer,
841
+ agent_id
842
+ })
843
+ );
844
+ case "hybrid":
845
+ if (!query) return err("query is required for hybrid search");
846
+ return ok(
847
+ await client2.retrieve({
848
+ action: "hybrid",
849
+ query,
850
+ k: limit,
851
+ node_types,
852
+ layer,
853
+ agent_id
854
+ })
855
+ );
856
+ // Structured queries
902
857
  case "active_goals":
903
858
  return ok(await client2.getGoals());
904
859
  case "open_questions":
@@ -930,6 +885,59 @@ async function handleRetrieve(client2, args) {
930
885
  agent_id
931
886
  })
932
887
  );
888
+ // Document inventory
889
+ case "document_index":
890
+ return ok(
891
+ await client2.getNodes({
892
+ node_type: "Document",
893
+ limit: limit ?? 100
894
+ })
895
+ );
896
+ // Graph traversal
897
+ case "chain":
898
+ if (!start_uid) return err("start_uid is required for chain traversal");
899
+ return ok(
900
+ await client2.traverse({
901
+ action: "chain",
902
+ start_uid,
903
+ max_depth
904
+ })
905
+ );
906
+ case "neighborhood":
907
+ if (!start_uid) return err("start_uid is required for neighborhood traversal");
908
+ return ok(
909
+ await client2.traverse({
910
+ action: "neighborhood",
911
+ start_uid,
912
+ max_depth,
913
+ direction,
914
+ edge_types
915
+ })
916
+ );
917
+ case "path":
918
+ if (!start_uid) return err("start_uid is required for path traversal");
919
+ if (!end_uid) return err("end_uid is required for path traversal");
920
+ return ok(
921
+ await client2.traverse({
922
+ action: "path",
923
+ start_uid,
924
+ end_uid,
925
+ max_depth,
926
+ direction,
927
+ edge_types
928
+ })
929
+ );
930
+ case "subgraph":
931
+ if (!start_uid) return err("start_uid is required for subgraph traversal");
932
+ return ok(
933
+ await client2.traverse({
934
+ action: "subgraph",
935
+ start_uid,
936
+ max_depth,
937
+ direction,
938
+ edge_types
939
+ })
940
+ );
933
941
  default:
934
942
  return err(`Unknown retrieve action: ${action}`);
935
943
  }
@@ -996,72 +1004,83 @@ var client = new import_mindgraph.MindGraph({
996
1004
  baseUrl: BASE_URL,
997
1005
  apiKey: API_KEY
998
1006
  });
999
- var INSTRUCTIONS = `You have access to a persistent knowledge graph via MindGraph.
1007
+ var INSTRUCTIONS = `You have access to a persistent knowledge graph via MindGraph (6 tools).
1000
1008
 
1001
1009
  ## #1 RULE: Go straight to the user's topic
1002
1010
 
1003
1011
  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.
1004
1012
 
1005
1013
  **NEVER do any of these before addressing the user's topic:**
1006
- - Do NOT retrieve active_goals
1007
- - Do NOT retrieve open_questions
1008
- - Do NOT retrieve contradictions or weak_claims
1014
+ - Do NOT retrieve active_goals, open_questions, contradictions, or weak_claims
1009
1015
  - Do NOT follow a "session lifecycle" or "warm-up" sequence
1010
1016
  - Do NOT make multiple serial retrieve calls when one "context" call covers it
1011
1017
 
1012
1018
  There is no session to open. There is no context to pre-load. Just search for what the user asked about.
1013
1019
 
1014
1020
  **Example:** User says "Tell me about Indian philosophy and Taoism"
1015
- \u2713 CORRECT: \`mindgraph_retrieve({action: "context", query: "Indian philosophy Taoism"})\` \u2014 extracted key nouns, dropped "Tell me about"
1016
- \u2717 WRONG: First retrieve active_goals, then open_questions, then search for the topic
1017
- \u2717 WRONG: \`mindgraph_retrieve({action: "context", query: "Tell me about Indian philosophy and Taoism"})\` \u2014 natural language sentence won't match BM25 index
1021
+ \u2713 CORRECT: \`mindgraph_retrieve({action: "context", query: "Indian philosophy Taoism"})\`
1022
+ \u2717 WRONG: First retrieve active_goals, then open_questions, then search
1023
+ \u2717 WRONG: \`mindgraph_retrieve({action: "context", query: "Tell me about Indian philosophy and Taoism"})\` \u2014 natural language won't match BM25
1024
+
1025
+ ## Two-phase retrieval protocol
1026
+
1027
+ **Phase 1 \u2014 Orient (default, fast, lightweight):**
1028
+ 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.
1018
1029
 
1019
- ## Search query style \u2014 BM25 keyword matching
1030
+ **Phase 2 \u2014 Fetch source text (only when needed):**
1031
+ 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.
1020
1032
 
1021
- 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).
1033
+ **Orientation shortcut:**
1034
+ - \`action: "document_index"\` \u2014 list all ingested documents (titles, dates, UIDs) to see what's in the graph
1022
1035
 
1023
- **Derive keywords from the user's question \u2014 examples:**
1024
- - User asks "What is Kissinger's view on NATO expansion?" \u2192 query: \`"Kissinger NATO"\`
1025
- - User asks "Tell me about async programming in Rust" \u2192 query: \`"Rust async runtime"\`
1026
- - User asks "How does Indian philosophy relate to Taoism?" \u2192 query: \`"Indian philosophy Taoism"\`
1027
- - User asks "What are the implications of carbon tax policy?" \u2192 query: \`"carbon tax"\`
1036
+ ## Search strategy \u2014 keyword first, semantic as fallback
1028
1037
 
1029
- **GOOD queries:** \`"Rust async runtime"\`, \`"Kissinger NATO"\`, \`"carbon tax emissions"\`
1030
- **BAD queries:** \`"what do I know about async programming in Rust?"\`, \`"how does X relate to Y"\`, \`"implications of climate change"\`
1038
+ The default search uses BM25 keyword matching. Query with 1\u20133 discriminating terms (proper nouns, technical terms). Drop filler words.
1031
1039
 
1032
- If the first query returns no results, try synonym or related terms (e.g. \`"global warming"\` instead of \`"climate change"\`).
1040
+ **Keyword examples:**
1041
+ - "What is Kissinger's view on NATO?" \u2192 query: \`"Kissinger NATO"\`
1042
+ - "Tell me about async in Rust" \u2192 query: \`"Rust async runtime"\`
1043
+ - "Implications of carbon tax?" \u2192 query: \`"carbon tax"\`
1044
+
1045
+ If keyword search returns no results, escalate:
1046
+ 1. Try synonyms (e.g. \`"global warming"\` instead of \`"climate change"\`)
1047
+ 2. Use \`action: "semantic"\` \u2014 vector similarity, natural language OK (e.g. \`"ways to manage stress"\` finds "mental health" nodes)
1048
+ 3. Use \`action: "hybrid"\` \u2014 combines BM25 + semantic for best coverage
1033
1049
 
1034
1050
  ## When to READ
1035
1051
 
1036
1052
  - User asks about topic X \u2192 \`mindgraph_retrieve\` action "context", query "X keywords"
1053
+ - User asks "what documents are in my graph?" \u2192 action "document_index"
1037
1054
  - User explicitly asks "what are my goals?" \u2192 action "active_goals"
1038
1055
  - User explicitly asks about open questions \u2192 action "open_questions"
1039
- - Before asserting something the user previously said \u2192 retrieve to check
1040
- - Parallelize independent calls in a single batch
1056
+ - Explore around a known node \u2192 action "neighborhood" with start_uid
1057
+ - Find connections between nodes \u2192 action "path" with start_uid + end_uid
1041
1058
 
1042
1059
  ## When to WRITE
1043
1060
 
1044
1061
  Capture knowledge when the user shares something worth remembering:
1045
1062
  - People/orgs/places/events \u2192 \`mindgraph_capture\` action "entity"
1046
- - Quick notes, preferences \u2192 \`mindgraph_journal\`
1063
+ - Quick notes, preferences \u2192 \`mindgraph_capture\` action "journal"
1047
1064
  - Factual observations \u2192 \`mindgraph_capture\` action "observation"
1048
- - Claims with evidence \u2192 \`mindgraph_argue\`
1049
- - Questions to track \u2192 \`mindgraph_inquire\` action "open_question"
1050
- - Goals or projects \u2192 \`mindgraph_commit\`
1051
- - Decisions \u2192 \`mindgraph_decide\`
1065
+ - Claims with evidence \u2192 \`mindgraph_reason\` action "claim"
1066
+ - Questions to track \u2192 \`mindgraph_reason\` action "open_question"
1067
+ - Goals or projects \u2192 \`mindgraph_commit\` action "goal"/"project"
1068
+ - Decisions \u2192 \`mindgraph_commit\` action "open_decision"
1052
1069
  - Long-form content \u2192 \`mindgraph_ingest\`
1053
1070
 
1054
1071
  ## Tool tips
1055
1072
 
1056
- - \`capture\` for structured/factual, \`journal\` for personal/informal
1057
- - \`argue\` when evidence exists, \`inquire\` for open questions
1058
- - \`text\` for fast lookup, \`context\` for rich retrieval with graph traversal
1073
+ - \`capture\`: "entity"/"observation" for facts, "journal" for personal/informal
1074
+ - \`reason\`: "claim" when evidence exists, "open_question"/"hypothesis" otherwise
1075
+ - \`retrieve\`: "context" returns graph nodes only by default \u2014 set include_chunks=true for source text
1076
+ - \`retrieve\`: "context" (FTS default) \u2192 "semantic" (conceptual fallback) \u2192 "hybrid" (both)
1077
+ - \`retrieve\`: "neighborhood"/"chain"/"path"/"subgraph" for graph exploration
1059
1078
  - Confidence: 0.9+ for facts, 0.5-0.8 for uncertain, <0.5 for speculation
1060
1079
  - Don't narrate tool usage \u2014 capture naturally as part of conversation`;
1061
1080
  var server = new import_server.Server(
1062
1081
  {
1063
1082
  name: "mindgraph",
1064
- version: "0.3.4"
1083
+ version: "0.5.0"
1065
1084
  },
1066
1085
  {
1067
1086
  capabilities: {
@@ -1221,14 +1240,12 @@ server.setRequestHandler(import_types.GetPromptRequestSchema, async (request) =>
1221
1240
  content: {
1222
1241
  type: "text",
1223
1242
  text: `Analyze the following conversation and capture all important information into my knowledge graph. Extract:
1224
- - Named entities (people, organizations, places, events)
1225
- - Factual claims and observations
1226
- - Decisions made or pending
1227
- - Goals or commitments mentioned
1228
- - Open questions raised
1229
- - Any hypotheses or theories discussed
1230
-
1231
- Use the appropriate MindGraph tools for each type of knowledge.
1243
+ - Named entities (people, organizations, places, events) \u2192 mindgraph_capture action "entity"
1244
+ - Factual claims and observations \u2192 mindgraph_capture action "observation" or mindgraph_reason action "claim"
1245
+ - Decisions made or pending \u2192 mindgraph_commit action "open_decision"
1246
+ - Goals or commitments mentioned \u2192 mindgraph_commit action "goal"/"project"
1247
+ - Open questions raised \u2192 mindgraph_reason action "open_question"
1248
+ - Any hypotheses or theories discussed \u2192 mindgraph_reason action "hypothesis"/"theory"
1232
1249
 
1233
1250
  Conversation:
1234
1251
  ${conversation}`
@@ -1419,7 +1436,7 @@ async function main() {
1419
1436
  const transport = new import_stdio.StdioServerTransport();
1420
1437
  await server.connect(transport);
1421
1438
  console.error(
1422
- `MindGraph MCP server v0.3.2 running on stdio (${BASE_URL})`
1439
+ `MindGraph MCP server v0.5.0 running on stdio (${BASE_URL})`
1423
1440
  );
1424
1441
  }
1425
1442
  main().catch((error) => {