mindgraph-mcp 0.7.0 → 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 +129 -0
- package/dist/cli.js +230 -2
- package/dist/index.js +230 -2
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# mindgraph-mcp
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/mindgraph-mcp)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
Model Context Protocol server for [MindGraph](https://mindgraph.cloud) — plug your persistent, structured knowledge graph into Claude Desktop, Claude Code, and any MCP-compatible client.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
The fastest way to install is the interactive setup:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx mindgraph-mcp init
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This walks you through:
|
|
17
|
+
|
|
18
|
+
1. Sign in via browser (or paste an existing API key).
|
|
19
|
+
2. Pick your client — Claude Desktop, Claude Code, or both.
|
|
20
|
+
3. The server is wired up automatically; restart your client to activate.
|
|
21
|
+
|
|
22
|
+
Don't have a MindGraph account yet? Sign up at [mindgraph.cloud](https://mindgraph.cloud) first.
|
|
23
|
+
|
|
24
|
+
### Manual install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Claude Desktop
|
|
28
|
+
npx mindgraph-mcp install --api-key mg_your_key_here
|
|
29
|
+
|
|
30
|
+
# Claude Code
|
|
31
|
+
npx mindgraph-mcp install-code --api-key mg_your_key_here
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or drop this into your Claude Desktop config by hand (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"mindgraph": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "mindgraph-mcp@latest"],
|
|
42
|
+
"env": {
|
|
43
|
+
"MINDGRAPH_API_KEY": "mg_your_key_here"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## What You Get
|
|
51
|
+
|
|
52
|
+
**8 tools** covering the full knowledge-graph workflow:
|
|
53
|
+
|
|
54
|
+
| Tool | Purpose |
|
|
55
|
+
|------|---------|
|
|
56
|
+
| `mindgraph_capture` | Entities, observations, sources, snippets, concepts, journal entries |
|
|
57
|
+
| `mindgraph_reason` | Claims with evidence, open questions, hypotheses, theories, anomalies |
|
|
58
|
+
| `mindgraph_commit` | Goals, projects, decisions, options, milestones |
|
|
59
|
+
| `mindgraph_plan` | Plans, tasks, procedures, governance policies, risk assessments, executions |
|
|
60
|
+
| `mindgraph_retrieve` | BM25 / semantic / hybrid search, traversal (chain, neighborhood, path, subgraph), document index |
|
|
61
|
+
| `mindgraph_ingest` | Chunk / document / session ingestion with LLM-powered extraction |
|
|
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 |
|
|
64
|
+
|
|
65
|
+
**7 prompt templates** for common workflows:
|
|
66
|
+
|
|
67
|
+
`graph-summary`, `active-goals`, `open-questions`, `review-contradictions`, `knowledge-about`, `daily-briefing`, `capture-conversation`.
|
|
68
|
+
|
|
69
|
+
**Resources** (static + dynamic URIs):
|
|
70
|
+
|
|
71
|
+
- `mindgraph://stats`, `mindgraph://goals`, `mindgraph://questions`, `mindgraph://contradictions`, `mindgraph://decisions`
|
|
72
|
+
- `mindgraph://node/{uid}` — a node with all its outgoing and incoming edges
|
|
73
|
+
- `mindgraph://search/{query}` — BM25 search results
|
|
74
|
+
- `mindgraph://layer/{layer}` — all nodes in a cognitive layer (reality, epistemic, intent, action, memory, agent)
|
|
75
|
+
|
|
76
|
+
## CLI
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
mindgraph-mcp Start the MCP server (stdio transport)
|
|
80
|
+
mindgraph-mcp init Interactive setup
|
|
81
|
+
mindgraph-mcp install Install into Claude Desktop config
|
|
82
|
+
mindgraph-mcp install-code Install into Claude Code
|
|
83
|
+
mindgraph-mcp uninstall Remove from Claude Desktop config
|
|
84
|
+
mindgraph-mcp uninstall-code Remove from Claude Code
|
|
85
|
+
mindgraph-mcp status Show installation status
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Options: `--api-key <key>`, `--base-url <url>`, `--help`.
|
|
89
|
+
|
|
90
|
+
## Environment
|
|
91
|
+
|
|
92
|
+
| Variable | Default | Purpose |
|
|
93
|
+
|----------|---------|---------|
|
|
94
|
+
| `MINDGRAPH_API_KEY` | *(required)* | Your MindGraph API key (`mg_…`) |
|
|
95
|
+
| `MINDGRAPH_BASE_URL` | `https://api.mindgraph.cloud` | Override for self-hosted deployments |
|
|
96
|
+
| `MINDGRAPH_AGENT_ID` | `mcp` | Stamped onto every node/edge written by the MCP — useful for provenance across multiple agents |
|
|
97
|
+
| `MINDGRAPH_ORG_ID` | *(unset)* | Pin operations to a specific organization when a key has access to more than one |
|
|
98
|
+
|
|
99
|
+
## Usage in Claude
|
|
100
|
+
|
|
101
|
+
Once installed, start asking Claude about your knowledge graph naturally:
|
|
102
|
+
|
|
103
|
+
> "What did I capture about climate policy last week?"
|
|
104
|
+
> "Summarize my active goals and open decisions."
|
|
105
|
+
> "Ingest this PDF and extract the main claims."
|
|
106
|
+
> "Find entities mentioned across multiple project documents, then spin up a synthesis."
|
|
107
|
+
|
|
108
|
+
The server auto-injects `agent_id: "mcp"` on every write so you always know which nodes came from your MCP sessions.
|
|
109
|
+
|
|
110
|
+
## Architecture
|
|
111
|
+
|
|
112
|
+
This MCP server is a thin wrapper over the [mindgraph](https://www.npmjs.com/package/mindgraph) TypeScript SDK. It exposes cognitive-layer abstractions (Reality, Epistemic, Intent, Action, Memory, Agent) as consolidated tools rather than one-tool-per-endpoint, which keeps the tool surface compact enough for high-quality tool selection by the model.
|
|
113
|
+
|
|
114
|
+
Search strategy is **keyword-first**: `mindgraph_retrieve` defaults to `action: "context"` which uses BM25. Escalate to `semantic` or `hybrid` only when keywords fail.
|
|
115
|
+
|
|
116
|
+
## Development
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
git clone https://github.com/shuruheel/mindgraph-mcp
|
|
120
|
+
cd mindgraph-mcp
|
|
121
|
+
npm install
|
|
122
|
+
npm run build # build with tsup (CJS + .d.ts)
|
|
123
|
+
npm run lint # tsc --noEmit
|
|
124
|
+
npm run dev # tsup --watch
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
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
|
}
|
|
@@ -1079,7 +1307,7 @@ async function main() {
|
|
|
1079
1307
|
const transport = new import_stdio.StdioServerTransport();
|
|
1080
1308
|
await server.connect(transport);
|
|
1081
1309
|
console.error(
|
|
1082
|
-
`MindGraph MCP server v0.7.
|
|
1310
|
+
`MindGraph MCP server v0.7.1 running on stdio (${BASE_URL})`
|
|
1083
1311
|
);
|
|
1084
1312
|
}
|
|
1085
1313
|
var import_server, import_stdio, import_types, import_mindgraph, API_KEY, BASE_URL, AGENT_ID, ORG_ID, client, INSTRUCTIONS, server, PROMPTS;
|
|
@@ -1183,7 +1411,7 @@ Capture knowledge when the user shares something worth remembering:
|
|
|
1183
1411
|
server = new import_server.Server(
|
|
1184
1412
|
{
|
|
1185
1413
|
name: "mindgraph",
|
|
1186
|
-
version: "0.7.
|
|
1414
|
+
version: "0.7.1"
|
|
1187
1415
|
},
|
|
1188
1416
|
{
|
|
1189
1417
|
capabilities: {
|
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;
|
|
@@ -1140,7 +1368,7 @@ Capture knowledge when the user shares something worth remembering:
|
|
|
1140
1368
|
var server = new import_server.Server(
|
|
1141
1369
|
{
|
|
1142
1370
|
name: "mindgraph",
|
|
1143
|
-
version: "0.7.
|
|
1371
|
+
version: "0.7.1"
|
|
1144
1372
|
},
|
|
1145
1373
|
{
|
|
1146
1374
|
capabilities: {
|
|
@@ -1496,7 +1724,7 @@ async function main() {
|
|
|
1496
1724
|
const transport = new import_stdio.StdioServerTransport();
|
|
1497
1725
|
await server.connect(transport);
|
|
1498
1726
|
console.error(
|
|
1499
|
-
`MindGraph MCP server v0.7.
|
|
1727
|
+
`MindGraph MCP server v0.7.1 running on stdio (${BASE_URL})`
|
|
1500
1728
|
);
|
|
1501
1729
|
}
|
|
1502
1730
|
main().catch((error) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindgraph-mcp",
|
|
3
|
-
"version": "0.
|
|
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.
|
|
30
|
+
"mindgraph": "^0.5.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|