mindgraph-mcp 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,7 @@ Or drop this into your Claude Desktop config by hand (`~/Library/Application Sup
49
49
 
50
50
  ## What You Get
51
51
 
52
- **7 tools** covering the full knowledge-graph workflow:
52
+ **8 tools** covering the full knowledge-graph workflow:
53
53
 
54
54
  | Tool | Purpose |
55
55
  |------|---------|
@@ -60,6 +60,7 @@ Or drop this into your Claude Desktop config by hand (`~/Library/Application Sup
60
60
  | `mindgraph_retrieve` | BM25 / semantic / hybrid search, traversal (chain, neighborhood, path, subgraph), document index |
61
61
  | `mindgraph_ingest` | Chunk / document / session ingestion with LLM-powered extraction |
62
62
  | `mindgraph_synthesize` | Project-scoped cross-document synthesis — mine signals, spawn Article-generation jobs |
63
+ | `mindgraph_ontology` | Operational Ontology (Layer 7) — typed domain objects, NL queries with provenance, extraction proposal review (approve/reject), object linking |
63
64
 
64
65
  **7 prompt templates** for common workflows:
65
66
 
package/dist/cli.js CHANGED
@@ -55,6 +55,8 @@ async function handleTool(client2, name, args) {
55
55
  return await handleIngest(client2, args);
56
56
  case "mindgraph_synthesize":
57
57
  return await handleSynthesize(client2, args);
58
+ case "mindgraph_ontology":
59
+ return await handleOntology(client2, args);
58
60
  default:
59
61
  return err(`Unknown tool: ${name}`);
60
62
  }
@@ -588,6 +590,124 @@ async function handleSynthesize(client2, args) {
588
590
  return err(`Unknown synthesize action: ${action}`);
589
591
  }
590
592
  }
593
+ async function handleOntology(client2, args) {
594
+ const {
595
+ action,
596
+ schema_id,
597
+ query,
598
+ object_types,
599
+ object_type,
600
+ uid,
601
+ depth,
602
+ include_cognitive_context,
603
+ include_sources,
604
+ limit,
605
+ status,
606
+ proposal_id,
607
+ feedback,
608
+ reason,
609
+ from_uid,
610
+ to_uid,
611
+ relation_type,
612
+ fields,
613
+ source_uids,
614
+ agent_id
615
+ } = args;
616
+ switch (action) {
617
+ case "schemas":
618
+ return ok(await client2.listOntologySchemas());
619
+ case "schema":
620
+ if (!schema_id) return err("schema_id is required for action='schema'");
621
+ return ok(await client2.getOntologySchema(schema_id));
622
+ case "query": {
623
+ if (!query) return err("query is required for action='query'");
624
+ if (!schema_id) {
625
+ return err(
626
+ "schema_id is required for action='query' (use action='schemas' to find the active schema)"
627
+ );
628
+ }
629
+ return ok(
630
+ await client2.queryOntology({
631
+ query,
632
+ schema_id,
633
+ object_types,
634
+ include_cognitive_context: include_cognitive_context ?? true,
635
+ include_sources: include_sources ?? true,
636
+ depth,
637
+ limit
638
+ })
639
+ );
640
+ }
641
+ case "search":
642
+ if (!query) return err("query is required for action='search'");
643
+ return ok(
644
+ await client2.searchDomainObjects(query, {
645
+ schema_id,
646
+ object_types,
647
+ limit
648
+ })
649
+ );
650
+ case "objects":
651
+ if (!schema_id) return err("schema_id is required for action='objects'");
652
+ return ok(
653
+ await client2.listDomainObjects({ schema_id, object_type, limit })
654
+ );
655
+ case "object":
656
+ if (!uid) return err("uid is required for action='object'");
657
+ return ok(await client2.getDomainObject(uid));
658
+ case "object_context":
659
+ if (!uid) return err("uid is required for action='object_context'");
660
+ return ok(await client2.getDomainObjectContext(uid, depth));
661
+ case "proposals":
662
+ return ok(
663
+ await client2.listOntologyProposals({
664
+ status: status ?? "pending",
665
+ schema_id,
666
+ object_type,
667
+ limit
668
+ })
669
+ );
670
+ case "proposal":
671
+ if (!proposal_id) return err("proposal_id is required for action='proposal'");
672
+ return ok(await client2.getOntologyProposal(proposal_id));
673
+ case "approve":
674
+ if (!proposal_id) return err("proposal_id is required for action='approve'");
675
+ return ok(await client2.approveOntologyProposal(proposal_id, { feedback }));
676
+ case "reject":
677
+ if (!proposal_id) return err("proposal_id is required for action='reject'");
678
+ return ok(await client2.rejectOntologyProposal(proposal_id, reason));
679
+ case "link": {
680
+ if (!from_uid || !to_uid || !relation_type) {
681
+ return err(
682
+ "from_uid, to_uid, and relation_type are required for action='link'"
683
+ );
684
+ }
685
+ return ok(
686
+ await client2.linkDomainObjects({
687
+ from_uid,
688
+ to_uid,
689
+ relation_type,
690
+ fields,
691
+ agent_id
692
+ })
693
+ );
694
+ }
695
+ case "extract": {
696
+ if (!schema_id) return err("schema_id is required for action='extract'");
697
+ if (!source_uids?.length) {
698
+ return err("source_uids is required for action='extract'");
699
+ }
700
+ return ok(
701
+ await client2.extractOntology({
702
+ ontology_schema_id: schema_id,
703
+ source_uids
704
+ })
705
+ );
706
+ }
707
+ default:
708
+ return err(`Unknown ontology action: ${action}`);
709
+ }
710
+ }
591
711
  var TOOLS;
592
712
  var init_tools = __esm({
593
713
  "src/tools.ts"() {
@@ -1068,6 +1188,114 @@ var init_tools = __esm({
1068
1188
  },
1069
1189
  required: ["action"]
1070
1190
  }
1191
+ },
1192
+ {
1193
+ name: "mindgraph_ontology",
1194
+ description: "Work with the Operational Ontology (Layer 7) \u2014 workspace-specific domain objects typed by a user-approved schema (e.g. Client, Contract, Patient, Experiment). Use 'schemas'/'schema' to discover what object and relation types exist before anything else. Use 'query' for natural-language retrieval of typed objects with cognitive context (claims, decisions, risks about them) and source provenance; 'search' for hybrid search over objects; 'objects'/'object'/'object_context' to browse instances. Extraction proposes new objects/relations into a review queue rather than writing directly: use 'proposals'/'proposal' to inspect the queue, and 'approve'/'reject' ONLY when the user explicitly asks \u2014 proposal review is the human-in-the-loop boundary. Use 'link' to relate two existing objects, 'extract' to run schema-typed extraction over already-ingested sources.",
1195
+ inputSchema: {
1196
+ type: "object",
1197
+ properties: {
1198
+ action: {
1199
+ type: "string",
1200
+ enum: [
1201
+ "schemas",
1202
+ "schema",
1203
+ "query",
1204
+ "search",
1205
+ "objects",
1206
+ "object",
1207
+ "object_context",
1208
+ "proposals",
1209
+ "proposal",
1210
+ "approve",
1211
+ "reject",
1212
+ "link",
1213
+ "extract"
1214
+ ],
1215
+ description: "Ontology operation"
1216
+ },
1217
+ schema_id: {
1218
+ type: "string",
1219
+ description: "Ontology schema ID (required for query/objects/extract; optional filter for proposals). Get it from action='schemas'."
1220
+ },
1221
+ query: {
1222
+ type: "string",
1223
+ description: "Natural-language query (for action=query) or search text (for action=search)"
1224
+ },
1225
+ object_types: {
1226
+ type: "array",
1227
+ items: { type: "string" },
1228
+ description: "Restrict to these object type names, e.g. ['Client'] (for query/search)"
1229
+ },
1230
+ object_type: {
1231
+ type: "string",
1232
+ description: "Single object type name filter (for objects/proposals)"
1233
+ },
1234
+ uid: {
1235
+ type: "string",
1236
+ description: "Domain object UID (for object/object_context)"
1237
+ },
1238
+ depth: {
1239
+ type: "number",
1240
+ description: "Traversal depth for context (for query/object_context, default 1)"
1241
+ },
1242
+ include_cognitive_context: {
1243
+ type: "boolean",
1244
+ description: "Include linked cognitive nodes \u2014 claims, decisions, risks (for action=query, default true)"
1245
+ },
1246
+ include_sources: {
1247
+ type: "boolean",
1248
+ description: "Include source provenance entries (for action=query, default true)"
1249
+ },
1250
+ limit: {
1251
+ type: "number",
1252
+ description: "Max results (for query/search/objects/proposals)"
1253
+ },
1254
+ status: {
1255
+ type: "string",
1256
+ enum: ["pending", "approved", "approval_required", "rejected", "applied", "apply_failed"],
1257
+ description: "Review-status filter (for action=proposals, default 'pending')"
1258
+ },
1259
+ proposal_id: {
1260
+ type: "string",
1261
+ description: "Proposal ID (for proposal/approve/reject)"
1262
+ },
1263
+ feedback: {
1264
+ type: "string",
1265
+ description: "Reviewer feedback to record (for action=approve)"
1266
+ },
1267
+ reason: {
1268
+ type: "string",
1269
+ description: "Rejection reason (for action=reject)"
1270
+ },
1271
+ from_uid: {
1272
+ type: "string",
1273
+ description: "Source domain object UID (for action=link)"
1274
+ },
1275
+ to_uid: {
1276
+ type: "string",
1277
+ description: "Target domain object UID (for action=link)"
1278
+ },
1279
+ relation_type: {
1280
+ type: "string",
1281
+ description: "Relation type name from the schema (for action=link)"
1282
+ },
1283
+ fields: {
1284
+ type: "object",
1285
+ description: "Relation field values (for action=link)"
1286
+ },
1287
+ source_uids: {
1288
+ type: "array",
1289
+ items: { type: "string" },
1290
+ description: "Chunk/document UIDs to extract from (for action=extract)"
1291
+ },
1292
+ agent_id: {
1293
+ type: "string",
1294
+ description: "Agent identity"
1295
+ }
1296
+ },
1297
+ required: ["action"]
1298
+ }
1071
1299
  }
1072
1300
  ];
1073
1301
  }
package/dist/index.js CHANGED
@@ -483,6 +483,114 @@ var TOOLS = [
483
483
  },
484
484
  required: ["action"]
485
485
  }
486
+ },
487
+ {
488
+ name: "mindgraph_ontology",
489
+ description: "Work with the Operational Ontology (Layer 7) \u2014 workspace-specific domain objects typed by a user-approved schema (e.g. Client, Contract, Patient, Experiment). Use 'schemas'/'schema' to discover what object and relation types exist before anything else. Use 'query' for natural-language retrieval of typed objects with cognitive context (claims, decisions, risks about them) and source provenance; 'search' for hybrid search over objects; 'objects'/'object'/'object_context' to browse instances. Extraction proposes new objects/relations into a review queue rather than writing directly: use 'proposals'/'proposal' to inspect the queue, and 'approve'/'reject' ONLY when the user explicitly asks \u2014 proposal review is the human-in-the-loop boundary. Use 'link' to relate two existing objects, 'extract' to run schema-typed extraction over already-ingested sources.",
490
+ inputSchema: {
491
+ type: "object",
492
+ properties: {
493
+ action: {
494
+ type: "string",
495
+ enum: [
496
+ "schemas",
497
+ "schema",
498
+ "query",
499
+ "search",
500
+ "objects",
501
+ "object",
502
+ "object_context",
503
+ "proposals",
504
+ "proposal",
505
+ "approve",
506
+ "reject",
507
+ "link",
508
+ "extract"
509
+ ],
510
+ description: "Ontology operation"
511
+ },
512
+ schema_id: {
513
+ type: "string",
514
+ description: "Ontology schema ID (required for query/objects/extract; optional filter for proposals). Get it from action='schemas'."
515
+ },
516
+ query: {
517
+ type: "string",
518
+ description: "Natural-language query (for action=query) or search text (for action=search)"
519
+ },
520
+ object_types: {
521
+ type: "array",
522
+ items: { type: "string" },
523
+ description: "Restrict to these object type names, e.g. ['Client'] (for query/search)"
524
+ },
525
+ object_type: {
526
+ type: "string",
527
+ description: "Single object type name filter (for objects/proposals)"
528
+ },
529
+ uid: {
530
+ type: "string",
531
+ description: "Domain object UID (for object/object_context)"
532
+ },
533
+ depth: {
534
+ type: "number",
535
+ description: "Traversal depth for context (for query/object_context, default 1)"
536
+ },
537
+ include_cognitive_context: {
538
+ type: "boolean",
539
+ description: "Include linked cognitive nodes \u2014 claims, decisions, risks (for action=query, default true)"
540
+ },
541
+ include_sources: {
542
+ type: "boolean",
543
+ description: "Include source provenance entries (for action=query, default true)"
544
+ },
545
+ limit: {
546
+ type: "number",
547
+ description: "Max results (for query/search/objects/proposals)"
548
+ },
549
+ status: {
550
+ type: "string",
551
+ enum: ["pending", "approved", "approval_required", "rejected", "applied", "apply_failed"],
552
+ description: "Review-status filter (for action=proposals, default 'pending')"
553
+ },
554
+ proposal_id: {
555
+ type: "string",
556
+ description: "Proposal ID (for proposal/approve/reject)"
557
+ },
558
+ feedback: {
559
+ type: "string",
560
+ description: "Reviewer feedback to record (for action=approve)"
561
+ },
562
+ reason: {
563
+ type: "string",
564
+ description: "Rejection reason (for action=reject)"
565
+ },
566
+ from_uid: {
567
+ type: "string",
568
+ description: "Source domain object UID (for action=link)"
569
+ },
570
+ to_uid: {
571
+ type: "string",
572
+ description: "Target domain object UID (for action=link)"
573
+ },
574
+ relation_type: {
575
+ type: "string",
576
+ description: "Relation type name from the schema (for action=link)"
577
+ },
578
+ fields: {
579
+ type: "object",
580
+ description: "Relation field values (for action=link)"
581
+ },
582
+ source_uids: {
583
+ type: "array",
584
+ items: { type: "string" },
585
+ description: "Chunk/document UIDs to extract from (for action=extract)"
586
+ },
587
+ agent_id: {
588
+ type: "string",
589
+ description: "Agent identity"
590
+ }
591
+ },
592
+ required: ["action"]
593
+ }
486
594
  }
487
595
  ];
488
596
  function ok(data) {
@@ -513,6 +621,8 @@ async function handleTool(client2, name, args) {
513
621
  return await handleIngest(client2, args);
514
622
  case "mindgraph_synthesize":
515
623
  return await handleSynthesize(client2, args);
624
+ case "mindgraph_ontology":
625
+ return await handleOntology(client2, args);
516
626
  default:
517
627
  return err(`Unknown tool: ${name}`);
518
628
  }
@@ -1046,6 +1156,124 @@ async function handleSynthesize(client2, args) {
1046
1156
  return err(`Unknown synthesize action: ${action}`);
1047
1157
  }
1048
1158
  }
1159
+ async function handleOntology(client2, args) {
1160
+ const {
1161
+ action,
1162
+ schema_id,
1163
+ query,
1164
+ object_types,
1165
+ object_type,
1166
+ uid,
1167
+ depth,
1168
+ include_cognitive_context,
1169
+ include_sources,
1170
+ limit,
1171
+ status,
1172
+ proposal_id,
1173
+ feedback,
1174
+ reason,
1175
+ from_uid,
1176
+ to_uid,
1177
+ relation_type,
1178
+ fields,
1179
+ source_uids,
1180
+ agent_id
1181
+ } = args;
1182
+ switch (action) {
1183
+ case "schemas":
1184
+ return ok(await client2.listOntologySchemas());
1185
+ case "schema":
1186
+ if (!schema_id) return err("schema_id is required for action='schema'");
1187
+ return ok(await client2.getOntologySchema(schema_id));
1188
+ case "query": {
1189
+ if (!query) return err("query is required for action='query'");
1190
+ if (!schema_id) {
1191
+ return err(
1192
+ "schema_id is required for action='query' (use action='schemas' to find the active schema)"
1193
+ );
1194
+ }
1195
+ return ok(
1196
+ await client2.queryOntology({
1197
+ query,
1198
+ schema_id,
1199
+ object_types,
1200
+ include_cognitive_context: include_cognitive_context ?? true,
1201
+ include_sources: include_sources ?? true,
1202
+ depth,
1203
+ limit
1204
+ })
1205
+ );
1206
+ }
1207
+ case "search":
1208
+ if (!query) return err("query is required for action='search'");
1209
+ return ok(
1210
+ await client2.searchDomainObjects(query, {
1211
+ schema_id,
1212
+ object_types,
1213
+ limit
1214
+ })
1215
+ );
1216
+ case "objects":
1217
+ if (!schema_id) return err("schema_id is required for action='objects'");
1218
+ return ok(
1219
+ await client2.listDomainObjects({ schema_id, object_type, limit })
1220
+ );
1221
+ case "object":
1222
+ if (!uid) return err("uid is required for action='object'");
1223
+ return ok(await client2.getDomainObject(uid));
1224
+ case "object_context":
1225
+ if (!uid) return err("uid is required for action='object_context'");
1226
+ return ok(await client2.getDomainObjectContext(uid, depth));
1227
+ case "proposals":
1228
+ return ok(
1229
+ await client2.listOntologyProposals({
1230
+ status: status ?? "pending",
1231
+ schema_id,
1232
+ object_type,
1233
+ limit
1234
+ })
1235
+ );
1236
+ case "proposal":
1237
+ if (!proposal_id) return err("proposal_id is required for action='proposal'");
1238
+ return ok(await client2.getOntologyProposal(proposal_id));
1239
+ case "approve":
1240
+ if (!proposal_id) return err("proposal_id is required for action='approve'");
1241
+ return ok(await client2.approveOntologyProposal(proposal_id, { feedback }));
1242
+ case "reject":
1243
+ if (!proposal_id) return err("proposal_id is required for action='reject'");
1244
+ return ok(await client2.rejectOntologyProposal(proposal_id, reason));
1245
+ case "link": {
1246
+ if (!from_uid || !to_uid || !relation_type) {
1247
+ return err(
1248
+ "from_uid, to_uid, and relation_type are required for action='link'"
1249
+ );
1250
+ }
1251
+ return ok(
1252
+ await client2.linkDomainObjects({
1253
+ from_uid,
1254
+ to_uid,
1255
+ relation_type,
1256
+ fields,
1257
+ agent_id
1258
+ })
1259
+ );
1260
+ }
1261
+ case "extract": {
1262
+ if (!schema_id) return err("schema_id is required for action='extract'");
1263
+ if (!source_uids?.length) {
1264
+ return err("source_uids is required for action='extract'");
1265
+ }
1266
+ return ok(
1267
+ await client2.extractOntology({
1268
+ ontology_schema_id: schema_id,
1269
+ source_uids
1270
+ })
1271
+ );
1272
+ }
1273
+ default:
1274
+ return err(`Unknown ontology action: ${action}`);
1275
+ }
1276
+ }
1049
1277
 
1050
1278
  // src/index.ts
1051
1279
  var API_KEY = process.env.MINDGRAPH_API_KEY;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph-mcp",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "MCP server for MindGraph — connect Claude Desktop, Claude Code, and any MCP client to your knowledge graph",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@modelcontextprotocol/sdk": "^1.12.1",
30
- "mindgraph": "^0.4.0"
30
+ "mindgraph": "^0.5.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.0.0",