mindgraph-mcp 0.14.2 → 0.14.3

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/dist/cli.js CHANGED
@@ -26,6 +26,895 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
 
29
+ // node_modules/mindgraph/dist/index.mjs
30
+ function seg(value) {
31
+ return encodeURIComponent(String(value));
32
+ }
33
+ function createRequestId() {
34
+ if (typeof globalThis.crypto?.randomUUID === "function") {
35
+ return globalThis.crypto.randomUUID();
36
+ }
37
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
38
+ }
39
+ var MindGraphError, MindGraph;
40
+ var init_dist = __esm({
41
+ "node_modules/mindgraph/dist/index.mjs"() {
42
+ "use strict";
43
+ MindGraphError = class extends Error {
44
+ constructor(message, status, body) {
45
+ super(message);
46
+ this.status = status;
47
+ this.body = body;
48
+ this.name = "MindGraphError";
49
+ }
50
+ };
51
+ MindGraph = class {
52
+ constructor(config) {
53
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
54
+ this.headers = { "Content-Type": "application/json" };
55
+ if (config.apiKey) {
56
+ this.headers["Authorization"] = `Bearer ${config.apiKey}`;
57
+ } else if (config.jwt) {
58
+ this.headers["Authorization"] = `Bearer ${config.jwt}`;
59
+ }
60
+ if (config.orgId) {
61
+ this.headers["X-MindGraph-Org"] = config.orgId;
62
+ }
63
+ this.telemetrySurface = config.telemetrySurface;
64
+ this.maxRetries = config.maxRetries ?? 3;
65
+ this.retryBackoffMs = config.retryBackoffMs ?? 1e3;
66
+ }
67
+ // ---- HTTP helpers ----
68
+ async request(method, path6, body) {
69
+ const url = `${this.baseUrl}${path6}`;
70
+ const requestId = createRequestId();
71
+ const init = {
72
+ method,
73
+ headers: {
74
+ ...this.headers,
75
+ "X-MindGraph-Request-ID": requestId,
76
+ ...this.telemetrySurface ? { "X-MindGraph-Surface": this.telemetrySurface } : {}
77
+ }
78
+ };
79
+ if (body !== void 0) {
80
+ init.body = JSON.stringify(body);
81
+ }
82
+ let lastError;
83
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
84
+ const res = await fetch(url, init);
85
+ if (!res.ok) {
86
+ const text2 = await res.text().catch(() => "");
87
+ let parsed;
88
+ try {
89
+ parsed = JSON.parse(text2);
90
+ } catch {
91
+ parsed = text2;
92
+ }
93
+ const err5 = new MindGraphError(
94
+ `${method} ${path6} failed: ${res.status}`,
95
+ res.status,
96
+ parsed
97
+ );
98
+ if (res.status === 503 && attempt < this.maxRetries) {
99
+ lastError = err5;
100
+ const delay = this.retryBackoffMs * 2 ** attempt;
101
+ await new Promise((r) => setTimeout(r, delay));
102
+ continue;
103
+ }
104
+ throw err5;
105
+ }
106
+ const text = await res.text();
107
+ if (!text) return void 0;
108
+ return JSON.parse(text);
109
+ }
110
+ throw lastError;
111
+ }
112
+ get(path6) {
113
+ return this.request("GET", path6);
114
+ }
115
+ post(path6, body) {
116
+ return this.request("POST", path6, body);
117
+ }
118
+ patch(path6, body) {
119
+ return this.request("PATCH", path6, body);
120
+ }
121
+ del(path6) {
122
+ return this.request("DELETE", path6);
123
+ }
124
+ // ---- Health ----
125
+ async health() {
126
+ return this.get("/health");
127
+ }
128
+ async stats() {
129
+ return this.get("/stats");
130
+ }
131
+ /**
132
+ * Schema fill-rate report (measure-first tiering): per live node type,
133
+ * the exact live count and sampled per-field fill rates; near-empty
134
+ * fields flagged below 5%. `sample` caps per-type sampling (default
135
+ * 1000); `layer` restricts (e.g. "epistemic").
136
+ */
137
+ async schemaFillStats(params) {
138
+ const q = new URLSearchParams();
139
+ if (params?.sample !== void 0) q.set("sample", String(params.sample));
140
+ if (params?.layer) q.set("layer", params.layer);
141
+ const qs = q.toString();
142
+ return this.get(`/stats/schema-fill${qs ? `?${qs}` : ""}`);
143
+ }
144
+ // ---- Reality Layer ----
145
+ async capture(req) {
146
+ return this.post("/reality/capture", req);
147
+ }
148
+ async entity(req) {
149
+ return this.post("/reality/entity", req);
150
+ }
151
+ /** Convenience: create or find an entity by label. */
152
+ async findOrCreateEntity(label, props, agentId) {
153
+ return this.post("/reality/entity", {
154
+ action: "create",
155
+ label,
156
+ props: { entity_type: "other", ...props },
157
+ agent_id: agentId
158
+ });
159
+ }
160
+ /** Convenience: create or find a Person entity by label. */
161
+ async findOrCreatePerson(label, props, agentId) {
162
+ return this.findOrCreateEntity(label, { entity_type: "person", ...props }, agentId);
163
+ }
164
+ /** Convenience: create or find an Organization entity by label. */
165
+ async findOrCreateOrganization(label, props, agentId) {
166
+ return this.findOrCreateEntity(label, { entity_type: "organization", ...props }, agentId);
167
+ }
168
+ /** Convenience: create or find a Nation entity by label. */
169
+ async findOrCreateNation(label, props, agentId) {
170
+ return this.findOrCreateEntity(label, { entity_type: "nation", ...props }, agentId);
171
+ }
172
+ /** Convenience: create or find an Event entity by label. */
173
+ async findOrCreateEvent(label, props, agentId) {
174
+ return this.findOrCreateEntity(label, { entity_type: "event", ...props }, agentId);
175
+ }
176
+ /** Convenience: create or find a Place entity by label. */
177
+ async findOrCreatePlace(label, props, agentId) {
178
+ return this.findOrCreateEntity(label, { entity_type: "place", ...props }, agentId);
179
+ }
180
+ /** Convenience: create or find a Concept entity by label. */
181
+ async findOrCreateConcept(label, props, agentId) {
182
+ return this.findOrCreateEntity(label, { entity_type: "concept", ...props }, agentId);
183
+ }
184
+ /**
185
+ * Resolve text to an existing entity via alias matching.
186
+ * Returns `{ uid: string | null }`.
187
+ */
188
+ async resolveEntity(text, agentId) {
189
+ return this.post("/reality/entity", {
190
+ action: "resolve",
191
+ text,
192
+ agent_id: agentId
193
+ });
194
+ }
195
+ /**
196
+ * Fuzzy-match text against existing entities.
197
+ * Returns `{ matches: [{ uid, label, score }] }`.
198
+ */
199
+ async fuzzyResolveEntity(text, limit = 5, agentId) {
200
+ return this.post("/reality/entity", {
201
+ action: "fuzzy_resolve",
202
+ text,
203
+ limit,
204
+ agent_id: agentId
205
+ });
206
+ }
207
+ // ---- Epistemic Layer ----
208
+ async argue(req) {
209
+ return this.post("/epistemic/argument", req);
210
+ }
211
+ async inquire(req) {
212
+ return this.post("/epistemic/inquiry", req);
213
+ }
214
+ async structure(req) {
215
+ return this.post("/epistemic/structure", req);
216
+ }
217
+ /**
218
+ * Convenience: create a Claim node via the argument endpoint.
219
+ * Returns the full argument response including `claim_uid`.
220
+ */
221
+ async addClaim(label, content, confidence, agentId) {
222
+ return this.post("/epistemic/argument", {
223
+ claim: {
224
+ label,
225
+ confidence,
226
+ props: { content }
227
+ },
228
+ agent_id: agentId
229
+ });
230
+ }
231
+ /**
232
+ * Convenience: create an Evidence node attached to a claim via the argument endpoint.
233
+ * If `claimLabel` and `claimConfidence` are provided, also creates the claim.
234
+ */
235
+ async addEvidence(label, description, agentId) {
236
+ return this.post("/epistemic/argument", {
237
+ claim: { label: `Claim for: ${label}` },
238
+ evidence: [{ label, props: { description } }],
239
+ agent_id: agentId
240
+ });
241
+ }
242
+ /** Convenience: create an Observation node via the reality capture endpoint. */
243
+ async addObservation(label, description, agentId) {
244
+ return this.post("/reality/capture", {
245
+ action: "observation",
246
+ label,
247
+ summary: description,
248
+ agent_id: agentId
249
+ });
250
+ }
251
+ // ---- Intent Layer ----
252
+ async commit(req) {
253
+ return this.post("/intent/commitment", req);
254
+ }
255
+ async deliberate(req) {
256
+ return this.post("/intent/deliberation", req);
257
+ }
258
+ /** Open a new decision for deliberation. Returns the Decision node. */
259
+ async openDecision(label, opts) {
260
+ return this.post("/intent/deliberation", {
261
+ action: "open_decision",
262
+ label,
263
+ ...opts
264
+ });
265
+ }
266
+ /** Add an option to an open decision. Returns the Option node. */
267
+ async addOption(decisionUid, label, opts) {
268
+ return this.post("/intent/deliberation", {
269
+ action: "add_option",
270
+ decision_uid: decisionUid,
271
+ label,
272
+ ...opts
273
+ });
274
+ }
275
+ /**
276
+ * Resolve a decision by choosing an option.
277
+ * `chosenOptionUid` must be the uid of an option added via `addOption()`.
278
+ */
279
+ async resolveDecision(decisionUid, chosenOptionUid, opts) {
280
+ return this.post("/intent/deliberation", {
281
+ action: "resolve",
282
+ decision_uid: decisionUid,
283
+ chosen_option_uid: chosenOptionUid,
284
+ ...opts
285
+ });
286
+ }
287
+ // ---- Action Layer ----
288
+ async procedure(req) {
289
+ return this.post("/action/procedure", req);
290
+ }
291
+ async risk(req) {
292
+ return this.post("/action/risk", req);
293
+ }
294
+ // ---- Memory Layer ----
295
+ async session(req) {
296
+ return this.post("/memory/session", req);
297
+ }
298
+ async journal(label, props, options) {
299
+ return this.post("/memory/session", {
300
+ action: "journal",
301
+ label,
302
+ props,
303
+ ...options
304
+ });
305
+ }
306
+ async distill(req) {
307
+ return this.post("/memory/distill", req);
308
+ }
309
+ async memoryConfig(req) {
310
+ return this.post("/memory/config", req);
311
+ }
312
+ async memorySync(req) {
313
+ return this.post("/memory/sync", req);
314
+ }
315
+ // ---- Agent Layer ----
316
+ async plan(req) {
317
+ return this.post("/agent/plan", req);
318
+ }
319
+ async governance(req) {
320
+ return this.post("/agent/governance", req);
321
+ }
322
+ async execution(req) {
323
+ return this.post("/agent/execution", req);
324
+ }
325
+ // ---- Cross-cutting ----
326
+ /** Returns an array of results. Shape varies by action. */
327
+ async retrieve(req) {
328
+ return this.post("/retrieve", req);
329
+ }
330
+ async traverse(req) {
331
+ return this.post("/traverse", req);
332
+ }
333
+ async evolve(req) {
334
+ return this.post("/evolve", req);
335
+ }
336
+ // ---- Node CRUD ----
337
+ async getNode(uid) {
338
+ return this.get(`/node/${seg(uid)}`);
339
+ }
340
+ /**
341
+ * Create a node via the low-level CRUD endpoint.
342
+ *
343
+ * The server requires `props._type` to determine the node variant.
344
+ * If `node_type` is provided and `_type` is not already in `props`,
345
+ * it is injected automatically.
346
+ */
347
+ async addNode(body) {
348
+ const props = { ...body.props };
349
+ if (body.node_type && !("_type" in props)) {
350
+ props._type = body.node_type;
351
+ }
352
+ return this.post("/node", { ...body, props });
353
+ }
354
+ async updateNode(uid, body) {
355
+ return this.patch(`/node/${seg(uid)}`, body);
356
+ }
357
+ async deleteNode(uid) {
358
+ await this.del(`/node/${seg(uid)}`);
359
+ }
360
+ async batchDeleteNodes(params) {
361
+ const body = {};
362
+ if (params.uids) body.uids = params.uids;
363
+ if (params.agentId) body.agent_id = params.agentId;
364
+ if (params.filter) {
365
+ body.filter = {
366
+ node_type: params.filter.nodeType,
367
+ node_types: params.filter.nodeTypes,
368
+ layer: params.filter.layer,
369
+ label_contains: params.filter.labelContains,
370
+ prop_equals: params.filter.propEquals
371
+ };
372
+ }
373
+ if (params.reason) body.reason = params.reason;
374
+ if (params.by) body.by = params.by;
375
+ if (params.hardPurge) body.hard_purge = params.hardPurge;
376
+ return this.post("/nodes/delete", body);
377
+ }
378
+ async getNodeHistory(uid) {
379
+ return this.get(`/node/${seg(uid)}/history`);
380
+ }
381
+ async getNodeAtVersion(uid, version) {
382
+ return this.get(`/node/${seg(uid)}/history/${seg(version)}`);
383
+ }
384
+ // ---- Edge CRUD ----
385
+ async addLink(body) {
386
+ return this.post("/link", body);
387
+ }
388
+ /**
389
+ * Create an edge via the low-level CRUD endpoint.
390
+ *
391
+ * The server requires `props._type` to determine the edge variant.
392
+ * If `edge_type` is provided and `_type` is not already in `props`,
393
+ * it is injected automatically.
394
+ */
395
+ async addEdge(body) {
396
+ const props = { ...body.props };
397
+ if (body.edge_type && !("_type" in props)) {
398
+ props._type = body.edge_type;
399
+ }
400
+ return this.post("/edge", { ...body, props });
401
+ }
402
+ async updateEdge(uid, body) {
403
+ return this.patch(`/edge/${seg(uid)}`, body);
404
+ }
405
+ async deleteEdge(uid) {
406
+ await this.del(`/edge/${seg(uid)}`);
407
+ }
408
+ async getEdgeHistory(uid) {
409
+ return this.get(`/edge/${seg(uid)}/history`);
410
+ }
411
+ /**
412
+ * List edges filtered by source and/or target node.
413
+ * At least one of `from_uid` or `to_uid` is **required** —
414
+ * the server returns 400 if neither is provided.
415
+ */
416
+ async getEdges(params) {
417
+ if (!params.from_uid && !params.to_uid) {
418
+ throw new Error("at least one of from_uid or to_uid is required");
419
+ }
420
+ const qs = new URLSearchParams();
421
+ if (params.from_uid) qs.set("from_uid", params.from_uid);
422
+ if (params.to_uid) qs.set("to_uid", params.to_uid);
423
+ return this.get(`/edges?${qs}`);
424
+ }
425
+ async getEdgeBetween(params) {
426
+ const qs = new URLSearchParams();
427
+ qs.set("from_uid", params.from_uid);
428
+ qs.set("to_uid", params.to_uid);
429
+ if (params.edge_type) qs.set("edge_type", params.edge_type);
430
+ return this.get(`/edge/between?${qs}`);
431
+ }
432
+ // ---- Search ----
433
+ async search(query, opts) {
434
+ return this.post("/search", { query, ...opts });
435
+ }
436
+ /**
437
+ * Hybrid BM25 + vector search with reciprocal rank fusion. Pass
438
+ * `explain: true` to get per-leg contributions (`legs`) on each result —
439
+ * the "why retrieved" detail (server ≥ 1.2.0; older servers ignore it).
440
+ */
441
+ async hybridSearch(query, opts) {
442
+ return this.post("/retrieve", {
443
+ action: "hybrid",
444
+ query,
445
+ ...opts
446
+ });
447
+ }
448
+ // ---- Nodes listing ----
449
+ async getNodes(params) {
450
+ const qs = new URLSearchParams();
451
+ if (params?.node_type) qs.set("node_type", params.node_type);
452
+ if (params?.layer) qs.set("layer", params.layer);
453
+ if (params?.limit != null) qs.set("limit", String(params.limit));
454
+ if (params?.offset != null) qs.set("offset", String(params.offset));
455
+ return this.get(`/nodes?${qs}`);
456
+ }
457
+ async getAgentNodes(agentId) {
458
+ return this.get(`/agent/${seg(agentId)}/nodes`);
459
+ }
460
+ // ---- Batch ----
461
+ async batch(req) {
462
+ return this.post("/batch", req);
463
+ }
464
+ /** Fetch multiple nodes by UID in a single request. */
465
+ async getNodesBatch(uids) {
466
+ return this.post("/nodes/batch", { uids });
467
+ }
468
+ /** Fetch all edges between a set of node UIDs. */
469
+ async getEdgesBatch(uids) {
470
+ return this.post("/edges/batch", { uids });
471
+ }
472
+ // ---- Embeddings ----
473
+ async configureEmbeddings(body) {
474
+ return this.post("/embeddings/configure", body);
475
+ }
476
+ async embeddingSearch(body) {
477
+ return this.post("/embeddings/search", body);
478
+ }
479
+ async embeddingSearchText(body) {
480
+ return this.post("/embeddings/search-text", body);
481
+ }
482
+ async getEmbedding(uid) {
483
+ return this.get(`/node/${seg(uid)}/embedding`);
484
+ }
485
+ async setEmbedding(uid, vector) {
486
+ await this.request("PUT", `/node/${seg(uid)}/embedding`, { vector });
487
+ }
488
+ async deleteEmbedding(uid) {
489
+ await this.del(`/node/${seg(uid)}/embedding`);
490
+ }
491
+ // ---- Entity resolution ----
492
+ async mergeEntities(body) {
493
+ return this.post("/entities/merge", body);
494
+ }
495
+ async addAlias(body) {
496
+ return this.post("/alias", body);
497
+ }
498
+ async getAliases(uid) {
499
+ return this.get(`/aliases/${seg(uid)}`);
500
+ }
501
+ async resolveAlias(text) {
502
+ return this.get(`/resolve?text=${encodeURIComponent(text)}`);
503
+ }
504
+ // ---- Export / Import ----
505
+ async exportGraph() {
506
+ return this.get("/export");
507
+ }
508
+ /**
509
+ * Export one document's extraction provenance as JSON-LD: PROV-O
510
+ * entities/agents, CiTO relations between extracted claims, and the
511
+ * citation anchors as W3C Web Annotations (TextQuoteSelector +
512
+ * TextPositionSelector; positions are chunk-relative UTF-8 byte offsets,
513
+ * flagged via `mg:offsetUnit`).
514
+ */
515
+ async exportProvenance(documentUid) {
516
+ return this.get(
517
+ `/export/prov?document_uid=${encodeURIComponent(documentUid)}`
518
+ );
519
+ }
520
+ async importGraph(data) {
521
+ return this.post("/import", data);
522
+ }
523
+ // ---- Lifecycle ----
524
+ async decay(req) {
525
+ return this.post("/decay", req);
526
+ }
527
+ async purge(req) {
528
+ return this.post("/purge", req ?? {});
529
+ }
530
+ // ---- Traversal shortcuts ----
531
+ async reasoningChain(uid, maxDepth = 5) {
532
+ const r = await this.post("/traverse", {
533
+ action: "chain",
534
+ start_uid: uid,
535
+ max_depth: maxDepth
536
+ });
537
+ return r?.steps ?? r;
538
+ }
539
+ async neighborhood(uid, maxDepth = 1) {
540
+ const r = await this.post("/traverse", {
541
+ action: "neighborhood",
542
+ start_uid: uid,
543
+ max_depth: maxDepth
544
+ });
545
+ return r?.steps ?? r;
546
+ }
547
+ async subgraph(uid, opts) {
548
+ return this.post("/subgraph", { start_uids: [uid], ...opts });
549
+ }
550
+ // ---- Lifecycle shortcuts ----
551
+ async tombstone(uid, reason, agentId) {
552
+ return this.post("/evolve", {
553
+ action: "tombstone",
554
+ uid,
555
+ reason,
556
+ agent_id: agentId
557
+ });
558
+ }
559
+ async restore(uid, agentId) {
560
+ return this.post("/evolve", {
561
+ action: "restore",
562
+ uid,
563
+ agent_id: agentId
564
+ });
565
+ }
566
+ // ---- Epistemic queries ----
567
+ async getGoals() {
568
+ return this.get("/goals");
569
+ }
570
+ async getOpenDecisions() {
571
+ return this.get("/decisions");
572
+ }
573
+ async getOpenQuestions() {
574
+ return this.get("/questions");
575
+ }
576
+ async getWeakClaims() {
577
+ return this.get("/claims/weak");
578
+ }
579
+ async getContradictions() {
580
+ return this.get("/contradictions");
581
+ }
582
+ /**
583
+ * Pending merge candidates: suspected duplicate pairs recorded by the dedup
584
+ * pipeline's ambiguous zone as PossibleDuplicate edges, awaiting a human
585
+ * merge/dismiss decision (server >= 1.3).
586
+ */
587
+ async getMergeCandidates() {
588
+ return this.post("/retrieve", { action: "merge_candidates" });
589
+ }
590
+ /** Load-bearing conclusions awaiting repair after a premise changed. */
591
+ async getStaleDerivations(limit = 50, offset = 0) {
592
+ return this.post("/retrieve", { action: "stale_derivations", limit, offset });
593
+ }
594
+ async getPendingApprovals() {
595
+ return this.get("/approvals/pending");
596
+ }
597
+ // ---- Ingestion & Retrieval ----
598
+ async ingestChunk(req) {
599
+ return this.post("/ingest/chunk", req);
600
+ }
601
+ async ingestDocument(req) {
602
+ return this.post("/ingest/document", req);
603
+ }
604
+ async ingestSession(req) {
605
+ return this.post("/ingest/session", req);
606
+ }
607
+ async retrieveContext(req) {
608
+ return this.post("/retrieve/context", req);
609
+ }
610
+ /** Backfill node_source provenance for existing graphs. */
611
+ async backfillNodeSources() {
612
+ return this.post("/backfill/node-sources", {});
613
+ }
614
+ /** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
615
+ async backfillAnchors() {
616
+ return this.post("/backfill/anchors", {});
617
+ }
618
+ async listJobs() {
619
+ return this.get("/jobs");
620
+ }
621
+ async getJob(id) {
622
+ return this.get(`/jobs/${seg(id)}`);
623
+ }
624
+ async cancelJob(id) {
625
+ return this.post(`/jobs/${seg(id)}/cancel`, {});
626
+ }
627
+ /** Resume ingestion of a document that has failed chunks. */
628
+ async resumeDocument(docUid, opts) {
629
+ return this.post(`/ingest/resume/${seg(docUid)}`, opts ?? {});
630
+ }
631
+ /** Delete a document and all its chunks and extracted nodes. */
632
+ async deleteDocument(uid) {
633
+ return this.del(`/ingest/document/${seg(uid)}`);
634
+ }
635
+ async cleanupOrphans() {
636
+ return this.post("/ingest/cleanup", {});
637
+ }
638
+ async embedAll() {
639
+ return this.post("/ingest/embed-all", {});
640
+ }
641
+ async clearGraph() {
642
+ return this.post("/clear", {});
643
+ }
644
+ // ── Wiki ──────────────────────────────────────────────────────────────
645
+ /** List wiki articles with optional filters. */
646
+ async listArticles(params) {
647
+ const q = new URLSearchParams();
648
+ if (params?.article_type) q.set("article_type", params.article_type);
649
+ if (params?.covers_node_type) q.set("covers_node_type", params.covers_node_type);
650
+ if (params?.search) q.set("search", params.search);
651
+ if (params?.limit) q.set("limit", String(params.limit));
652
+ if (params?.offset) q.set("offset", String(params.offset));
653
+ return this.get(`/wiki/articles?${q}`);
654
+ }
655
+ /** Get a single wiki article by UID. */
656
+ async getArticle(uid) {
657
+ return this.get(`/wiki/article/${seg(uid)}`);
658
+ }
659
+ /** Find the article that covers or summarizes a given entity/document UID. */
660
+ async getArticleBySubject(subjectUid) {
661
+ try {
662
+ return await this.get(`/wiki/article/by-subject/${seg(subjectUid)}`);
663
+ } catch {
664
+ return null;
665
+ }
666
+ }
667
+ /** Update an article's markdown content (user editing). */
668
+ async updateArticle(uid, content) {
669
+ return this.patch(`/wiki/article/${seg(uid)}`, { content });
670
+ }
671
+ /** Trigger wiki compilation for a specific document. */
672
+ async compileDocument(docUid) {
673
+ return this.post(`/wiki/compile/${seg(docUid)}`, {});
674
+ }
675
+ /** Trigger wiki compilation for a specific entity. */
676
+ async compileEntity(entityUid) {
677
+ return this.post(`/wiki/compile/entity/${seg(entityUid)}`, {});
678
+ }
679
+ /** Backfill: compile articles for all documents and eligible entities. */
680
+ async compileAll() {
681
+ return this.post("/wiki/compile/all", {});
682
+ }
683
+ // ── Synthesis (Projects) ──────────────────────────────────────────────
684
+ /**
685
+ * Mine structural synthesis signals for a project's document corpus.
686
+ *
687
+ * Returns candidate surface for downstream synthesis — entity bridges
688
+ * across documents, claim hubs, clustered claim hubs, theory support
689
+ * gaps, concept clusters, analogy candidates, and dialectical pairs.
690
+ *
691
+ * Blocking operation. No LLM calls; Datalog + embedding clustering only.
692
+ */
693
+ async signals(projectUid, opts) {
694
+ const q = new URLSearchParams();
695
+ if (opts?.signals) q.set("signals", opts.signals);
696
+ if (opts?.target_types) q.set("target_types", opts.target_types);
697
+ const qs = q.toString();
698
+ return this.get(`/synthesis/signals/${seg(projectUid)}${qs ? `?${qs}` : ""}`);
699
+ }
700
+ /**
701
+ * Spawn a background synthesis job for a project: mines signals,
702
+ * selects top idea clusters, runs LLM synthesis, and persists
703
+ * candidate Article nodes linked via `Covers` edges.
704
+ *
705
+ * Returns a `job_id` immediately; poll `getJob(id)` for progress.
706
+ */
707
+ async runSynthesis(projectUid) {
708
+ return this.post(`/synthesis/run/${seg(projectUid)}`, {});
709
+ }
710
+ // ============================================================================
711
+ // Operational Ontology Layer (Layer 7)
712
+ // ============================================================================
713
+ // ---- Schema management (cloud Postgres) ----
714
+ async listOntologySchemas() {
715
+ return this.get("/v1/ontology/schemas");
716
+ }
717
+ async getOntologySchema(id) {
718
+ return this.get(`/v1/ontology/schemas/${seg(id)}`);
719
+ }
720
+ async createOntologySchema(req) {
721
+ return this.post("/v1/ontology/schemas", req);
722
+ }
723
+ async updateOntologySchema(id, req) {
724
+ return this.patch(`/v1/ontology/schemas/${seg(id)}`, req);
725
+ }
726
+ async activateOntologySchema(id) {
727
+ return this.post(`/v1/ontology/schemas/${seg(id)}/activate`, {});
728
+ }
729
+ async deprecateOntologySchema(id) {
730
+ return this.post(`/v1/ontology/schemas/${seg(id)}/deprecate`, {});
731
+ }
732
+ async archiveOntologySchema(id) {
733
+ return this.del(`/v1/ontology/schemas/${seg(id)}`);
734
+ }
735
+ /**
736
+ * Kick off an LLM-driven schema proposal job.
737
+ * Returns immediately with `{ schema_id, job_id }`; poll
738
+ * `getOntologySchema(schema_id)` for streaming progress.
739
+ */
740
+ async proposeOntologySchema(req) {
741
+ return this.post("/v1/ontology/propose-schema", req);
742
+ }
743
+ async testOntologySchema(id, opts) {
744
+ return this.post(`/v1/ontology/schemas/${seg(id)}/test`, opts ?? {});
745
+ }
746
+ // ---- Schema sub-resources ----
747
+ async addOntologyObjectType(schemaId, req) {
748
+ return this.post(`/v1/ontology/schemas/${seg(schemaId)}/object-types`, req);
749
+ }
750
+ async updateOntologyObjectType(schemaId, typeId, req) {
751
+ return this.patch(
752
+ `/v1/ontology/schemas/${seg(schemaId)}/object-types/${seg(typeId)}`,
753
+ req
754
+ );
755
+ }
756
+ async deleteOntologyObjectType(schemaId, typeId) {
757
+ return this.del(
758
+ `/v1/ontology/schemas/${seg(schemaId)}/object-types/${seg(typeId)}`
759
+ );
760
+ }
761
+ async addOntologyRelationType(schemaId, req) {
762
+ return this.post(`/v1/ontology/schemas/${seg(schemaId)}/relation-types`, req);
763
+ }
764
+ async updateOntologyRelationType(schemaId, typeId, req) {
765
+ return this.patch(
766
+ `/v1/ontology/schemas/${seg(schemaId)}/relation-types/${seg(typeId)}`,
767
+ req
768
+ );
769
+ }
770
+ async deleteOntologyRelationType(schemaId, typeId) {
771
+ return this.del(
772
+ `/v1/ontology/schemas/${seg(schemaId)}/relation-types/${seg(typeId)}`
773
+ );
774
+ }
775
+ /** Generate inert semantic classifications for individual human review. */
776
+ async analyzeOntologySemanticGuidance(schemaId) {
777
+ return this.post(
778
+ `/v1/ontology/schemas/${seg(schemaId)}/semantic-guidance/analyze`,
779
+ {}
780
+ );
781
+ }
782
+ /** Read-only exact-identity collision audit; never merges graph data. */
783
+ async auditOntologyDuplicates(schemaId) {
784
+ return this.post(`/v1/ontology/schemas/${seg(schemaId)}/duplicates/audit`, {});
785
+ }
786
+ // ---- Proposals ----
787
+ async listOntologyProposals(opts) {
788
+ const q = new URLSearchParams();
789
+ if (opts?.status) q.set("status", opts.status);
790
+ if (opts?.schema_id) q.set("schema_id", opts.schema_id);
791
+ if (opts?.object_type) q.set("object_type", opts.object_type);
792
+ if (opts?.proposal_type) q.set("proposal_type", opts.proposal_type);
793
+ if (opts?.extract_job_id) q.set("extract_job_id", opts.extract_job_id);
794
+ if (opts?.limit != null) q.set("limit", String(opts.limit));
795
+ if (opts?.offset != null) q.set("offset", String(opts.offset));
796
+ const qs = q.toString();
797
+ return this.get(`/v1/ontology/proposals${qs ? `?${qs}` : ""}`);
798
+ }
799
+ async getOntologyProposal(id) {
800
+ return this.get(`/v1/ontology/proposals/${seg(id)}`);
801
+ }
802
+ async patchOntologyProposal(id, req) {
803
+ return this.patch(`/v1/ontology/proposals/${seg(id)}`, req);
804
+ }
805
+ async approveOntologyProposal(id, opts) {
806
+ return this.post(`/v1/ontology/proposals/${seg(id)}/approve`, opts ?? {});
807
+ }
808
+ async rejectOntologyProposal(id, reason) {
809
+ return this.post(`/v1/ontology/proposals/${seg(id)}/reject`, { reason });
810
+ }
811
+ async applyOntologyProposal(id) {
812
+ return this.post(`/v1/ontology/proposals/${seg(id)}/apply`, {});
813
+ }
814
+ async batchApproveOntologyProposals(ids, feedback) {
815
+ return this.post("/v1/ontology/proposals/batch-approve", { ids, feedback });
816
+ }
817
+ async batchRejectOntologyProposals(ids, reason) {
818
+ return this.post("/v1/ontology/proposals/batch-reject", { ids, reason });
819
+ }
820
+ // ---- Retrieval (graph server) ----
821
+ async queryOntology(req) {
822
+ return this.post("/ontology/query", req);
823
+ }
824
+ async queryDomainStructured(req) {
825
+ return this.post("/ontology/query/structured", req);
826
+ }
827
+ async queryRelatedDomainObjects(req) {
828
+ return this.queryDomainStructured({
829
+ schema_id: req.schema_id,
830
+ select: req.far_type,
831
+ ...req.project_uid ? { project_uid: req.project_uid } : {},
832
+ anchor: { type: req.entry_type, uid: req.uid },
833
+ path: [{
834
+ relation: req.relation,
835
+ entry_role: req.entry_role
836
+ }],
837
+ ...req.where ? { where: req.where } : {},
838
+ ...req.include_provenance ? { include: { provenance: true } } : {},
839
+ page: {
840
+ ...req.limit != null ? { limit: req.limit } : {},
841
+ ...req.offset != null ? { offset: req.offset } : {}
842
+ }
843
+ });
844
+ }
845
+ /**
846
+ * Schema-qualified read-tool descriptors generated from every active
847
+ * ontology. Includes per-object discovery/point/context tools,
848
+ * relation-and-role-specific related tools, and one structured composite.
849
+ */
850
+ async listOntologyTools() {
851
+ return this.get("/v1/ontology/tools");
852
+ }
853
+ async getDomainObject(uid, binding) {
854
+ const query = new URLSearchParams();
855
+ if (binding) {
856
+ query.set("schema_id", binding.schema_id);
857
+ query.set("object_type", binding.object_type);
858
+ if (binding.project_uid) query.set("project_uid", binding.project_uid);
859
+ }
860
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
861
+ return this.get(`/ontology/object/${seg(uid)}${suffix}`);
862
+ }
863
+ async getDomainObjectContext(uid, depth, binding) {
864
+ const query = new URLSearchParams();
865
+ if (depth != null) query.set("depth", String(depth));
866
+ if (binding) {
867
+ query.set("schema_id", binding.schema_id);
868
+ query.set("object_type", binding.object_type);
869
+ if (binding.project_uid) query.set("project_uid", binding.project_uid);
870
+ }
871
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
872
+ return this.get(`/ontology/object/${seg(uid)}/context${suffix}`);
873
+ }
874
+ async getDomainObjectHistory(uid) {
875
+ return this.get(`/ontology/object/${seg(uid)}/history`);
876
+ }
877
+ async listDomainObjects(opts) {
878
+ const q = new URLSearchParams();
879
+ q.set("schema_id", opts.schema_id);
880
+ if (opts.object_type) q.set("object_type", opts.object_type);
881
+ if (opts.limit != null) q.set("limit", String(opts.limit));
882
+ if (opts.offset != null) q.set("offset", String(opts.offset));
883
+ if (opts.sort) q.set("sort", opts.sort);
884
+ return this.get(`/ontology/objects?${q.toString()}`);
885
+ }
886
+ async searchDomainObjects(query, opts) {
887
+ return this.post("/ontology/objects/search", { query, ...opts ?? {} });
888
+ }
889
+ /**
890
+ * Per-object-type coverage stats for a schema (C2f): field fill rates
891
+ * (with a `near_empty` flag < 5%) and identity collisions, over a bounded
892
+ * per-type sample (default 500, max 2000).
893
+ */
894
+ async ontologyStats(schemaId, sample) {
895
+ const q = new URLSearchParams({ schema_id: schemaId });
896
+ if (sample != null) q.set("sample", String(sample));
897
+ return this.get(`/ontology/stats?${q.toString()}`);
898
+ }
899
+ /**
900
+ * Create a domain object by hand (auto-approved). Returns the created node
901
+ * uid + the audit proposal id. Throws 409 if an object of the same type +
902
+ * canonical_name already exists, unless `allow_duplicate` is set.
903
+ */
904
+ async createDomainObject(req) {
905
+ return this.post("/v1/ontology/objects", req);
906
+ }
907
+ async linkDomainObjects(req) {
908
+ return this.post("/ontology/relation", { action: "create", ...req });
909
+ }
910
+ // ---- Extraction ----
911
+ async extractOntology(req) {
912
+ return this.post("/ontology/extract", req);
913
+ }
914
+ };
915
+ }
916
+ });
917
+
29
918
  // src/codegraph.ts
30
919
  function normalizePath(path6) {
31
920
  return path6.replaceAll("\\", "/").replace(/^\.\//, "");
@@ -712,17 +1601,16 @@ var init_codegraph = __esm({
712
1601
 
713
1602
  // src/error-detail.ts
714
1603
  function errorDetail(e) {
715
- if (e instanceof import_mindgraph.MindGraphError && e.body !== void 0) {
1604
+ if (e instanceof MindGraphError && e.body !== void 0) {
716
1605
  const detail = typeof e.body === "string" ? e.body : JSON.stringify(e.body);
717
1606
  return `${e.message} \u2014 ${detail}`;
718
1607
  }
719
1608
  return e instanceof Error ? e.message : String(e);
720
1609
  }
721
- var import_mindgraph;
722
1610
  var init_error_detail = __esm({
723
1611
  "src/error-detail.ts"() {
724
1612
  "use strict";
725
- import_mindgraph = require("mindgraph");
1613
+ init_dist();
726
1614
  }
727
1615
  });
728
1616
 
@@ -3874,14 +4762,14 @@ async function main() {
3874
4762
  `MindGraph MCP server v0.7.1 running on stdio (${BASE_URL})`
3875
4763
  );
3876
4764
  }
3877
- var import_server, import_stdio, import_types, import_mindgraph2, API_KEY, BASE_URL, AGENT_ID, ORG_ID, PROFILE, HARNESS, client, INSTRUCTIONS, server, GOVERNANCE_CONFIG, PROMPTS;
4765
+ var import_server, import_stdio, import_types, API_KEY, BASE_URL, AGENT_ID, ORG_ID, PROFILE, HARNESS, client, INSTRUCTIONS, server, GOVERNANCE_CONFIG, PROMPTS;
3878
4766
  var init_src = __esm({
3879
4767
  "src/index.ts"() {
3880
4768
  "use strict";
3881
4769
  import_server = require("@modelcontextprotocol/sdk/server/index.js");
3882
4770
  import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
3883
4771
  import_types = require("@modelcontextprotocol/sdk/types.js");
3884
- import_mindgraph2 = require("mindgraph");
4772
+ init_dist();
3885
4773
  init_tools();
3886
4774
  init_generated_tools();
3887
4775
  init_governance();
@@ -3898,7 +4786,7 @@ var init_src = __esm({
3898
4786
  );
3899
4787
  process.exit(1);
3900
4788
  }
3901
- client = new import_mindgraph2.MindGraph({
4789
+ client = new MindGraph({
3902
4790
  baseUrl: BASE_URL,
3903
4791
  apiKey: API_KEY,
3904
4792
  orgId: ORG_ID,
@@ -4005,7 +4893,7 @@ Capture knowledge when the user shares something worth remembering:
4005
4893
  server = new import_server.Server(
4006
4894
  {
4007
4895
  name: "mindgraph",
4008
- version: "0.14.2"
4896
+ version: "0.14.3"
4009
4897
  },
4010
4898
  {
4011
4899
  capabilities: {
@@ -4228,7 +5116,7 @@ var path5 = __toESM(require("path"));
4228
5116
  var os4 = __toESM(require("os"));
4229
5117
  var crypto4 = __toESM(require("crypto"));
4230
5118
  var import_child_process = require("child_process");
4231
- var import_mindgraph3 = require("mindgraph");
5119
+ init_dist();
4232
5120
 
4233
5121
  // src/hook-env.ts
4234
5122
  var import_node_fs = __toESM(require("fs"));
@@ -5312,7 +6200,7 @@ async function main2() {
5312
6200
  }
5313
6201
  try {
5314
6202
  const input = await readHookInput();
5315
- const client2 = new import_mindgraph3.MindGraph({
6203
+ const client2 = new MindGraph({
5316
6204
  baseUrl: hookBaseUrl || "https://api.mindgraph.cloud",
5317
6205
  apiKey: hookApiKey,
5318
6206
  orgId: process.env.MINDGRAPH_ORG_ID,
package/dist/index.js CHANGED
@@ -3931,7 +3931,7 @@ if (PROFILE === "coding") {
3931
3931
  var server = new import_server.Server(
3932
3932
  {
3933
3933
  name: "mindgraph",
3934
- version: "0.14.2"
3934
+ version: "0.14.3"
3935
3935
  },
3936
3936
  {
3937
3937
  capabilities: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph-mcp",
3
- "version": "0.14.2",
3
+ "version": "0.14.3",
4
4
  "description": "MCP server for MindGraph — connect Claude Desktop, Claude Code, and any MCP client to your knowledge graph",
5
5
  "repository": {
6
6
  "type": "git",