mindgraph-mcp 0.7.1 → 0.9.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 +2 -1
- package/dist/cli.js +240 -1
- package/dist/index.js +240 -1
- package/package.json +2 -2
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
|
-
**
|
|
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
|
}
|
|
@@ -443,6 +445,15 @@ async function handleRetrieve(client2, args) {
|
|
|
443
445
|
return ok(await client2.getPendingApprovals());
|
|
444
446
|
case "unresolved_contradictions":
|
|
445
447
|
return ok(await client2.getContradictions());
|
|
448
|
+
case "preferences":
|
|
449
|
+
return ok(
|
|
450
|
+
await client2.retrieve({
|
|
451
|
+
action: "preferences",
|
|
452
|
+
...query ? { query, k: limit } : {},
|
|
453
|
+
limit,
|
|
454
|
+
agent_id
|
|
455
|
+
})
|
|
456
|
+
);
|
|
446
457
|
case "layer":
|
|
447
458
|
if (!layer) return err("layer is required for layer retrieval");
|
|
448
459
|
return ok(
|
|
@@ -588,6 +599,124 @@ async function handleSynthesize(client2, args) {
|
|
|
588
599
|
return err(`Unknown synthesize action: ${action}`);
|
|
589
600
|
}
|
|
590
601
|
}
|
|
602
|
+
async function handleOntology(client2, args) {
|
|
603
|
+
const {
|
|
604
|
+
action,
|
|
605
|
+
schema_id,
|
|
606
|
+
query,
|
|
607
|
+
object_types,
|
|
608
|
+
object_type,
|
|
609
|
+
uid,
|
|
610
|
+
depth,
|
|
611
|
+
include_cognitive_context,
|
|
612
|
+
include_sources,
|
|
613
|
+
limit,
|
|
614
|
+
status,
|
|
615
|
+
proposal_id,
|
|
616
|
+
feedback,
|
|
617
|
+
reason,
|
|
618
|
+
from_uid,
|
|
619
|
+
to_uid,
|
|
620
|
+
relation_type,
|
|
621
|
+
fields,
|
|
622
|
+
source_uids,
|
|
623
|
+
agent_id
|
|
624
|
+
} = args;
|
|
625
|
+
switch (action) {
|
|
626
|
+
case "schemas":
|
|
627
|
+
return ok(await client2.listOntologySchemas());
|
|
628
|
+
case "schema":
|
|
629
|
+
if (!schema_id) return err("schema_id is required for action='schema'");
|
|
630
|
+
return ok(await client2.getOntologySchema(schema_id));
|
|
631
|
+
case "query": {
|
|
632
|
+
if (!query) return err("query is required for action='query'");
|
|
633
|
+
if (!schema_id) {
|
|
634
|
+
return err(
|
|
635
|
+
"schema_id is required for action='query' (use action='schemas' to find the active schema)"
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
return ok(
|
|
639
|
+
await client2.queryOntology({
|
|
640
|
+
query,
|
|
641
|
+
schema_id,
|
|
642
|
+
object_types,
|
|
643
|
+
include_cognitive_context: include_cognitive_context ?? true,
|
|
644
|
+
include_sources: include_sources ?? true,
|
|
645
|
+
depth,
|
|
646
|
+
limit
|
|
647
|
+
})
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
case "search":
|
|
651
|
+
if (!query) return err("query is required for action='search'");
|
|
652
|
+
return ok(
|
|
653
|
+
await client2.searchDomainObjects(query, {
|
|
654
|
+
schema_id,
|
|
655
|
+
object_types,
|
|
656
|
+
limit
|
|
657
|
+
})
|
|
658
|
+
);
|
|
659
|
+
case "objects":
|
|
660
|
+
if (!schema_id) return err("schema_id is required for action='objects'");
|
|
661
|
+
return ok(
|
|
662
|
+
await client2.listDomainObjects({ schema_id, object_type, limit })
|
|
663
|
+
);
|
|
664
|
+
case "object":
|
|
665
|
+
if (!uid) return err("uid is required for action='object'");
|
|
666
|
+
return ok(await client2.getDomainObject(uid));
|
|
667
|
+
case "object_context":
|
|
668
|
+
if (!uid) return err("uid is required for action='object_context'");
|
|
669
|
+
return ok(await client2.getDomainObjectContext(uid, depth));
|
|
670
|
+
case "proposals":
|
|
671
|
+
return ok(
|
|
672
|
+
await client2.listOntologyProposals({
|
|
673
|
+
status: status ?? "pending",
|
|
674
|
+
schema_id,
|
|
675
|
+
object_type,
|
|
676
|
+
limit
|
|
677
|
+
})
|
|
678
|
+
);
|
|
679
|
+
case "proposal":
|
|
680
|
+
if (!proposal_id) return err("proposal_id is required for action='proposal'");
|
|
681
|
+
return ok(await client2.getOntologyProposal(proposal_id));
|
|
682
|
+
case "approve":
|
|
683
|
+
if (!proposal_id) return err("proposal_id is required for action='approve'");
|
|
684
|
+
return ok(await client2.approveOntologyProposal(proposal_id, { feedback }));
|
|
685
|
+
case "reject":
|
|
686
|
+
if (!proposal_id) return err("proposal_id is required for action='reject'");
|
|
687
|
+
return ok(await client2.rejectOntologyProposal(proposal_id, reason));
|
|
688
|
+
case "link": {
|
|
689
|
+
if (!from_uid || !to_uid || !relation_type) {
|
|
690
|
+
return err(
|
|
691
|
+
"from_uid, to_uid, and relation_type are required for action='link'"
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
return ok(
|
|
695
|
+
await client2.linkDomainObjects({
|
|
696
|
+
from_uid,
|
|
697
|
+
to_uid,
|
|
698
|
+
relation_type,
|
|
699
|
+
fields,
|
|
700
|
+
agent_id
|
|
701
|
+
})
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
case "extract": {
|
|
705
|
+
if (!schema_id) return err("schema_id is required for action='extract'");
|
|
706
|
+
if (!source_uids?.length) {
|
|
707
|
+
return err("source_uids is required for action='extract'");
|
|
708
|
+
}
|
|
709
|
+
return ok(
|
|
710
|
+
await client2.extractOntology({
|
|
711
|
+
ontology_schema_id: schema_id,
|
|
712
|
+
source_uids
|
|
713
|
+
})
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
default:
|
|
717
|
+
return err(`Unknown ontology action: ${action}`);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
591
720
|
var TOOLS;
|
|
592
721
|
var init_tools = __esm({
|
|
593
722
|
"src/tools.ts"() {
|
|
@@ -882,7 +1011,7 @@ var init_tools = __esm({
|
|
|
882
1011
|
},
|
|
883
1012
|
{
|
|
884
1013
|
name: "mindgraph_retrieve",
|
|
885
|
-
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.",
|
|
1014
|
+
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. Use 'preferences' for advice or recommendation requests ('suggest a hotel', 'what should I read?') \u2014 it returns the user's stated/learned preferences relevant to the query (pass the topic as 'query'), so your answer reflects what they actually like instead of being generic. Other structured actions ('active_goals', 'open_questions', etc.) only when the user explicitly asks.",
|
|
886
1015
|
inputSchema: {
|
|
887
1016
|
type: "object",
|
|
888
1017
|
properties: {
|
|
@@ -898,6 +1027,7 @@ var init_tools = __esm({
|
|
|
898
1027
|
"weak_claims",
|
|
899
1028
|
"pending_approvals",
|
|
900
1029
|
"unresolved_contradictions",
|
|
1030
|
+
"preferences",
|
|
901
1031
|
"layer",
|
|
902
1032
|
"recent",
|
|
903
1033
|
"chain",
|
|
@@ -1068,6 +1198,114 @@ var init_tools = __esm({
|
|
|
1068
1198
|
},
|
|
1069
1199
|
required: ["action"]
|
|
1070
1200
|
}
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
name: "mindgraph_ontology",
|
|
1204
|
+
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.",
|
|
1205
|
+
inputSchema: {
|
|
1206
|
+
type: "object",
|
|
1207
|
+
properties: {
|
|
1208
|
+
action: {
|
|
1209
|
+
type: "string",
|
|
1210
|
+
enum: [
|
|
1211
|
+
"schemas",
|
|
1212
|
+
"schema",
|
|
1213
|
+
"query",
|
|
1214
|
+
"search",
|
|
1215
|
+
"objects",
|
|
1216
|
+
"object",
|
|
1217
|
+
"object_context",
|
|
1218
|
+
"proposals",
|
|
1219
|
+
"proposal",
|
|
1220
|
+
"approve",
|
|
1221
|
+
"reject",
|
|
1222
|
+
"link",
|
|
1223
|
+
"extract"
|
|
1224
|
+
],
|
|
1225
|
+
description: "Ontology operation"
|
|
1226
|
+
},
|
|
1227
|
+
schema_id: {
|
|
1228
|
+
type: "string",
|
|
1229
|
+
description: "Ontology schema ID (required for query/objects/extract; optional filter for proposals). Get it from action='schemas'."
|
|
1230
|
+
},
|
|
1231
|
+
query: {
|
|
1232
|
+
type: "string",
|
|
1233
|
+
description: "Natural-language query (for action=query) or search text (for action=search)"
|
|
1234
|
+
},
|
|
1235
|
+
object_types: {
|
|
1236
|
+
type: "array",
|
|
1237
|
+
items: { type: "string" },
|
|
1238
|
+
description: "Restrict to these object type names, e.g. ['Client'] (for query/search)"
|
|
1239
|
+
},
|
|
1240
|
+
object_type: {
|
|
1241
|
+
type: "string",
|
|
1242
|
+
description: "Single object type name filter (for objects/proposals)"
|
|
1243
|
+
},
|
|
1244
|
+
uid: {
|
|
1245
|
+
type: "string",
|
|
1246
|
+
description: "Domain object UID (for object/object_context)"
|
|
1247
|
+
},
|
|
1248
|
+
depth: {
|
|
1249
|
+
type: "number",
|
|
1250
|
+
description: "Traversal depth for context (for query/object_context, default 1)"
|
|
1251
|
+
},
|
|
1252
|
+
include_cognitive_context: {
|
|
1253
|
+
type: "boolean",
|
|
1254
|
+
description: "Include linked cognitive nodes \u2014 claims, decisions, risks (for action=query, default true)"
|
|
1255
|
+
},
|
|
1256
|
+
include_sources: {
|
|
1257
|
+
type: "boolean",
|
|
1258
|
+
description: "Include source provenance entries (for action=query, default true)"
|
|
1259
|
+
},
|
|
1260
|
+
limit: {
|
|
1261
|
+
type: "number",
|
|
1262
|
+
description: "Max results (for query/search/objects/proposals)"
|
|
1263
|
+
},
|
|
1264
|
+
status: {
|
|
1265
|
+
type: "string",
|
|
1266
|
+
enum: ["pending", "approved", "approval_required", "rejected", "applied", "apply_failed"],
|
|
1267
|
+
description: "Review-status filter (for action=proposals, default 'pending')"
|
|
1268
|
+
},
|
|
1269
|
+
proposal_id: {
|
|
1270
|
+
type: "string",
|
|
1271
|
+
description: "Proposal ID (for proposal/approve/reject)"
|
|
1272
|
+
},
|
|
1273
|
+
feedback: {
|
|
1274
|
+
type: "string",
|
|
1275
|
+
description: "Reviewer feedback to record (for action=approve)"
|
|
1276
|
+
},
|
|
1277
|
+
reason: {
|
|
1278
|
+
type: "string",
|
|
1279
|
+
description: "Rejection reason (for action=reject)"
|
|
1280
|
+
},
|
|
1281
|
+
from_uid: {
|
|
1282
|
+
type: "string",
|
|
1283
|
+
description: "Source domain object UID (for action=link)"
|
|
1284
|
+
},
|
|
1285
|
+
to_uid: {
|
|
1286
|
+
type: "string",
|
|
1287
|
+
description: "Target domain object UID (for action=link)"
|
|
1288
|
+
},
|
|
1289
|
+
relation_type: {
|
|
1290
|
+
type: "string",
|
|
1291
|
+
description: "Relation type name from the schema (for action=link)"
|
|
1292
|
+
},
|
|
1293
|
+
fields: {
|
|
1294
|
+
type: "object",
|
|
1295
|
+
description: "Relation field values (for action=link)"
|
|
1296
|
+
},
|
|
1297
|
+
source_uids: {
|
|
1298
|
+
type: "array",
|
|
1299
|
+
items: { type: "string" },
|
|
1300
|
+
description: "Chunk/document UIDs to extract from (for action=extract)"
|
|
1301
|
+
},
|
|
1302
|
+
agent_id: {
|
|
1303
|
+
type: "string",
|
|
1304
|
+
description: "Agent identity"
|
|
1305
|
+
}
|
|
1306
|
+
},
|
|
1307
|
+
required: ["action"]
|
|
1308
|
+
}
|
|
1071
1309
|
}
|
|
1072
1310
|
];
|
|
1073
1311
|
}
|
|
@@ -1155,6 +1393,7 @@ If keyword search returns no results, escalate:
|
|
|
1155
1393
|
- User asks "what documents are in my graph?" \u2192 action "document_index"
|
|
1156
1394
|
- User explicitly asks "what are my goals?" \u2192 action "active_goals"
|
|
1157
1395
|
- User explicitly asks about open questions \u2192 action "open_questions"
|
|
1396
|
+
- User asks for advice or a recommendation ("suggest a hotel", "what should I read?") \u2192 action "preferences", query "topic keywords" \u2014 tailor the answer to what they like
|
|
1158
1397
|
- Explore around a known node \u2192 action "neighborhood" with start_uid
|
|
1159
1398
|
- Find connections between nodes \u2192 action "path" with start_uid + end_uid
|
|
1160
1399
|
|
package/dist/index.js
CHANGED
|
@@ -297,7 +297,7 @@ var TOOLS = [
|
|
|
297
297
|
},
|
|
298
298
|
{
|
|
299
299
|
name: "mindgraph_retrieve",
|
|
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.",
|
|
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. Use 'preferences' for advice or recommendation requests ('suggest a hotel', 'what should I read?') \u2014 it returns the user's stated/learned preferences relevant to the query (pass the topic as 'query'), so your answer reflects what they actually like instead of being generic. Other structured actions ('active_goals', 'open_questions', etc.) only when the user explicitly asks.",
|
|
301
301
|
inputSchema: {
|
|
302
302
|
type: "object",
|
|
303
303
|
properties: {
|
|
@@ -313,6 +313,7 @@ var TOOLS = [
|
|
|
313
313
|
"weak_claims",
|
|
314
314
|
"pending_approvals",
|
|
315
315
|
"unresolved_contradictions",
|
|
316
|
+
"preferences",
|
|
316
317
|
"layer",
|
|
317
318
|
"recent",
|
|
318
319
|
"chain",
|
|
@@ -483,6 +484,114 @@ var TOOLS = [
|
|
|
483
484
|
},
|
|
484
485
|
required: ["action"]
|
|
485
486
|
}
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "mindgraph_ontology",
|
|
490
|
+
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.",
|
|
491
|
+
inputSchema: {
|
|
492
|
+
type: "object",
|
|
493
|
+
properties: {
|
|
494
|
+
action: {
|
|
495
|
+
type: "string",
|
|
496
|
+
enum: [
|
|
497
|
+
"schemas",
|
|
498
|
+
"schema",
|
|
499
|
+
"query",
|
|
500
|
+
"search",
|
|
501
|
+
"objects",
|
|
502
|
+
"object",
|
|
503
|
+
"object_context",
|
|
504
|
+
"proposals",
|
|
505
|
+
"proposal",
|
|
506
|
+
"approve",
|
|
507
|
+
"reject",
|
|
508
|
+
"link",
|
|
509
|
+
"extract"
|
|
510
|
+
],
|
|
511
|
+
description: "Ontology operation"
|
|
512
|
+
},
|
|
513
|
+
schema_id: {
|
|
514
|
+
type: "string",
|
|
515
|
+
description: "Ontology schema ID (required for query/objects/extract; optional filter for proposals). Get it from action='schemas'."
|
|
516
|
+
},
|
|
517
|
+
query: {
|
|
518
|
+
type: "string",
|
|
519
|
+
description: "Natural-language query (for action=query) or search text (for action=search)"
|
|
520
|
+
},
|
|
521
|
+
object_types: {
|
|
522
|
+
type: "array",
|
|
523
|
+
items: { type: "string" },
|
|
524
|
+
description: "Restrict to these object type names, e.g. ['Client'] (for query/search)"
|
|
525
|
+
},
|
|
526
|
+
object_type: {
|
|
527
|
+
type: "string",
|
|
528
|
+
description: "Single object type name filter (for objects/proposals)"
|
|
529
|
+
},
|
|
530
|
+
uid: {
|
|
531
|
+
type: "string",
|
|
532
|
+
description: "Domain object UID (for object/object_context)"
|
|
533
|
+
},
|
|
534
|
+
depth: {
|
|
535
|
+
type: "number",
|
|
536
|
+
description: "Traversal depth for context (for query/object_context, default 1)"
|
|
537
|
+
},
|
|
538
|
+
include_cognitive_context: {
|
|
539
|
+
type: "boolean",
|
|
540
|
+
description: "Include linked cognitive nodes \u2014 claims, decisions, risks (for action=query, default true)"
|
|
541
|
+
},
|
|
542
|
+
include_sources: {
|
|
543
|
+
type: "boolean",
|
|
544
|
+
description: "Include source provenance entries (for action=query, default true)"
|
|
545
|
+
},
|
|
546
|
+
limit: {
|
|
547
|
+
type: "number",
|
|
548
|
+
description: "Max results (for query/search/objects/proposals)"
|
|
549
|
+
},
|
|
550
|
+
status: {
|
|
551
|
+
type: "string",
|
|
552
|
+
enum: ["pending", "approved", "approval_required", "rejected", "applied", "apply_failed"],
|
|
553
|
+
description: "Review-status filter (for action=proposals, default 'pending')"
|
|
554
|
+
},
|
|
555
|
+
proposal_id: {
|
|
556
|
+
type: "string",
|
|
557
|
+
description: "Proposal ID (for proposal/approve/reject)"
|
|
558
|
+
},
|
|
559
|
+
feedback: {
|
|
560
|
+
type: "string",
|
|
561
|
+
description: "Reviewer feedback to record (for action=approve)"
|
|
562
|
+
},
|
|
563
|
+
reason: {
|
|
564
|
+
type: "string",
|
|
565
|
+
description: "Rejection reason (for action=reject)"
|
|
566
|
+
},
|
|
567
|
+
from_uid: {
|
|
568
|
+
type: "string",
|
|
569
|
+
description: "Source domain object UID (for action=link)"
|
|
570
|
+
},
|
|
571
|
+
to_uid: {
|
|
572
|
+
type: "string",
|
|
573
|
+
description: "Target domain object UID (for action=link)"
|
|
574
|
+
},
|
|
575
|
+
relation_type: {
|
|
576
|
+
type: "string",
|
|
577
|
+
description: "Relation type name from the schema (for action=link)"
|
|
578
|
+
},
|
|
579
|
+
fields: {
|
|
580
|
+
type: "object",
|
|
581
|
+
description: "Relation field values (for action=link)"
|
|
582
|
+
},
|
|
583
|
+
source_uids: {
|
|
584
|
+
type: "array",
|
|
585
|
+
items: { type: "string" },
|
|
586
|
+
description: "Chunk/document UIDs to extract from (for action=extract)"
|
|
587
|
+
},
|
|
588
|
+
agent_id: {
|
|
589
|
+
type: "string",
|
|
590
|
+
description: "Agent identity"
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
required: ["action"]
|
|
594
|
+
}
|
|
486
595
|
}
|
|
487
596
|
];
|
|
488
597
|
function ok(data) {
|
|
@@ -513,6 +622,8 @@ async function handleTool(client2, name, args) {
|
|
|
513
622
|
return await handleIngest(client2, args);
|
|
514
623
|
case "mindgraph_synthesize":
|
|
515
624
|
return await handleSynthesize(client2, args);
|
|
625
|
+
case "mindgraph_ontology":
|
|
626
|
+
return await handleOntology(client2, args);
|
|
516
627
|
default:
|
|
517
628
|
return err(`Unknown tool: ${name}`);
|
|
518
629
|
}
|
|
@@ -901,6 +1012,15 @@ async function handleRetrieve(client2, args) {
|
|
|
901
1012
|
return ok(await client2.getPendingApprovals());
|
|
902
1013
|
case "unresolved_contradictions":
|
|
903
1014
|
return ok(await client2.getContradictions());
|
|
1015
|
+
case "preferences":
|
|
1016
|
+
return ok(
|
|
1017
|
+
await client2.retrieve({
|
|
1018
|
+
action: "preferences",
|
|
1019
|
+
...query ? { query, k: limit } : {},
|
|
1020
|
+
limit,
|
|
1021
|
+
agent_id
|
|
1022
|
+
})
|
|
1023
|
+
);
|
|
904
1024
|
case "layer":
|
|
905
1025
|
if (!layer) return err("layer is required for layer retrieval");
|
|
906
1026
|
return ok(
|
|
@@ -1046,6 +1166,124 @@ async function handleSynthesize(client2, args) {
|
|
|
1046
1166
|
return err(`Unknown synthesize action: ${action}`);
|
|
1047
1167
|
}
|
|
1048
1168
|
}
|
|
1169
|
+
async function handleOntology(client2, args) {
|
|
1170
|
+
const {
|
|
1171
|
+
action,
|
|
1172
|
+
schema_id,
|
|
1173
|
+
query,
|
|
1174
|
+
object_types,
|
|
1175
|
+
object_type,
|
|
1176
|
+
uid,
|
|
1177
|
+
depth,
|
|
1178
|
+
include_cognitive_context,
|
|
1179
|
+
include_sources,
|
|
1180
|
+
limit,
|
|
1181
|
+
status,
|
|
1182
|
+
proposal_id,
|
|
1183
|
+
feedback,
|
|
1184
|
+
reason,
|
|
1185
|
+
from_uid,
|
|
1186
|
+
to_uid,
|
|
1187
|
+
relation_type,
|
|
1188
|
+
fields,
|
|
1189
|
+
source_uids,
|
|
1190
|
+
agent_id
|
|
1191
|
+
} = args;
|
|
1192
|
+
switch (action) {
|
|
1193
|
+
case "schemas":
|
|
1194
|
+
return ok(await client2.listOntologySchemas());
|
|
1195
|
+
case "schema":
|
|
1196
|
+
if (!schema_id) return err("schema_id is required for action='schema'");
|
|
1197
|
+
return ok(await client2.getOntologySchema(schema_id));
|
|
1198
|
+
case "query": {
|
|
1199
|
+
if (!query) return err("query is required for action='query'");
|
|
1200
|
+
if (!schema_id) {
|
|
1201
|
+
return err(
|
|
1202
|
+
"schema_id is required for action='query' (use action='schemas' to find the active schema)"
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
return ok(
|
|
1206
|
+
await client2.queryOntology({
|
|
1207
|
+
query,
|
|
1208
|
+
schema_id,
|
|
1209
|
+
object_types,
|
|
1210
|
+
include_cognitive_context: include_cognitive_context ?? true,
|
|
1211
|
+
include_sources: include_sources ?? true,
|
|
1212
|
+
depth,
|
|
1213
|
+
limit
|
|
1214
|
+
})
|
|
1215
|
+
);
|
|
1216
|
+
}
|
|
1217
|
+
case "search":
|
|
1218
|
+
if (!query) return err("query is required for action='search'");
|
|
1219
|
+
return ok(
|
|
1220
|
+
await client2.searchDomainObjects(query, {
|
|
1221
|
+
schema_id,
|
|
1222
|
+
object_types,
|
|
1223
|
+
limit
|
|
1224
|
+
})
|
|
1225
|
+
);
|
|
1226
|
+
case "objects":
|
|
1227
|
+
if (!schema_id) return err("schema_id is required for action='objects'");
|
|
1228
|
+
return ok(
|
|
1229
|
+
await client2.listDomainObjects({ schema_id, object_type, limit })
|
|
1230
|
+
);
|
|
1231
|
+
case "object":
|
|
1232
|
+
if (!uid) return err("uid is required for action='object'");
|
|
1233
|
+
return ok(await client2.getDomainObject(uid));
|
|
1234
|
+
case "object_context":
|
|
1235
|
+
if (!uid) return err("uid is required for action='object_context'");
|
|
1236
|
+
return ok(await client2.getDomainObjectContext(uid, depth));
|
|
1237
|
+
case "proposals":
|
|
1238
|
+
return ok(
|
|
1239
|
+
await client2.listOntologyProposals({
|
|
1240
|
+
status: status ?? "pending",
|
|
1241
|
+
schema_id,
|
|
1242
|
+
object_type,
|
|
1243
|
+
limit
|
|
1244
|
+
})
|
|
1245
|
+
);
|
|
1246
|
+
case "proposal":
|
|
1247
|
+
if (!proposal_id) return err("proposal_id is required for action='proposal'");
|
|
1248
|
+
return ok(await client2.getOntologyProposal(proposal_id));
|
|
1249
|
+
case "approve":
|
|
1250
|
+
if (!proposal_id) return err("proposal_id is required for action='approve'");
|
|
1251
|
+
return ok(await client2.approveOntologyProposal(proposal_id, { feedback }));
|
|
1252
|
+
case "reject":
|
|
1253
|
+
if (!proposal_id) return err("proposal_id is required for action='reject'");
|
|
1254
|
+
return ok(await client2.rejectOntologyProposal(proposal_id, reason));
|
|
1255
|
+
case "link": {
|
|
1256
|
+
if (!from_uid || !to_uid || !relation_type) {
|
|
1257
|
+
return err(
|
|
1258
|
+
"from_uid, to_uid, and relation_type are required for action='link'"
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1261
|
+
return ok(
|
|
1262
|
+
await client2.linkDomainObjects({
|
|
1263
|
+
from_uid,
|
|
1264
|
+
to_uid,
|
|
1265
|
+
relation_type,
|
|
1266
|
+
fields,
|
|
1267
|
+
agent_id
|
|
1268
|
+
})
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
case "extract": {
|
|
1272
|
+
if (!schema_id) return err("schema_id is required for action='extract'");
|
|
1273
|
+
if (!source_uids?.length) {
|
|
1274
|
+
return err("source_uids is required for action='extract'");
|
|
1275
|
+
}
|
|
1276
|
+
return ok(
|
|
1277
|
+
await client2.extractOntology({
|
|
1278
|
+
ontology_schema_id: schema_id,
|
|
1279
|
+
source_uids
|
|
1280
|
+
})
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
default:
|
|
1284
|
+
return err(`Unknown ontology action: ${action}`);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1049
1287
|
|
|
1050
1288
|
// src/index.ts
|
|
1051
1289
|
var API_KEY = process.env.MINDGRAPH_API_KEY;
|
|
@@ -1112,6 +1350,7 @@ If keyword search returns no results, escalate:
|
|
|
1112
1350
|
- User asks "what documents are in my graph?" \u2192 action "document_index"
|
|
1113
1351
|
- User explicitly asks "what are my goals?" \u2192 action "active_goals"
|
|
1114
1352
|
- User explicitly asks about open questions \u2192 action "open_questions"
|
|
1353
|
+
- User asks for advice or a recommendation ("suggest a hotel", "what should I read?") \u2192 action "preferences", query "topic keywords" \u2014 tailor the answer to what they like
|
|
1115
1354
|
- Explore around a known node \u2192 action "neighborhood" with start_uid
|
|
1116
1355
|
- Find connections between nodes \u2192 action "path" with start_uid + end_uid
|
|
1117
1356
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindgraph-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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.
|
|
30
|
+
"mindgraph": "^0.5.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|