mindgraph-mcp 0.16.0 → 0.17.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 +4 -4
- package/dist/cli.js +307 -79
- package/dist/index.js +302 -75
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2123,13 +2123,13 @@ var init_code_tool = __esm({
|
|
|
2123
2123
|
init_error_detail();
|
|
2124
2124
|
init_codegraph();
|
|
2125
2125
|
ok = (data) => ({
|
|
2126
|
-
content: [{ type: "text", text: JSON.stringify(data
|
|
2126
|
+
content: [{ type: "text", text: JSON.stringify(data) }]
|
|
2127
2127
|
});
|
|
2128
2128
|
err = (code, message, details) => ({
|
|
2129
2129
|
content: [
|
|
2130
2130
|
{
|
|
2131
2131
|
type: "text",
|
|
2132
|
-
text: JSON.stringify({ error: message, code, details }
|
|
2132
|
+
text: JSON.stringify({ error: message, code, details })
|
|
2133
2133
|
}
|
|
2134
2134
|
],
|
|
2135
2135
|
isError: true
|
|
@@ -2335,7 +2335,7 @@ var init_sync_tool = __esm({
|
|
|
2335
2335
|
init_codegraph();
|
|
2336
2336
|
init_error_detail();
|
|
2337
2337
|
ok2 = (data) => ({
|
|
2338
|
-
content: [{ type: "text", text: JSON.stringify(data
|
|
2338
|
+
content: [{ type: "text", text: JSON.stringify(data) }]
|
|
2339
2339
|
});
|
|
2340
2340
|
err2 = (code, message) => ({
|
|
2341
2341
|
content: [{ type: "text", text: JSON.stringify({ code, error: message }) }],
|
|
@@ -2431,12 +2431,23 @@ function clip(value, max, state) {
|
|
|
2431
2431
|
}
|
|
2432
2432
|
function isNodeShaped(value) {
|
|
2433
2433
|
const node = obj(value);
|
|
2434
|
-
return Boolean(
|
|
2434
|
+
return Boolean(
|
|
2435
|
+
node && str(node.uid) && (str(node.label) || str(node.node_type) || obj(node.node_type))
|
|
2436
|
+
);
|
|
2437
|
+
}
|
|
2438
|
+
function nodeDisplayType(node) {
|
|
2439
|
+
const props = obj(node.props);
|
|
2440
|
+
const plain = str(node.node_type);
|
|
2441
|
+
return (plain && plain !== "Custom" ? plain : void 0) ?? str(obj(node.node_type)?.Custom) ?? str(props?.object_type) ?? str(props?.type_name) ?? str(obj(props?.data)?.domain_type) ?? plain ?? "Node";
|
|
2442
|
+
}
|
|
2443
|
+
function nodeFields(node) {
|
|
2444
|
+
const props = obj(node.props);
|
|
2445
|
+
return obj(props?.fields) ?? obj(obj(props?.data)?.fields);
|
|
2435
2446
|
}
|
|
2436
2447
|
function unwrapSearchResult(value) {
|
|
2437
2448
|
if (isNodeShaped(value)) return value;
|
|
2438
2449
|
const wrapper = obj(value);
|
|
2439
|
-
const inner = obj(wrapper?.node);
|
|
2450
|
+
const inner = obj(wrapper?.node) ?? obj(wrapper?.object);
|
|
2440
2451
|
if (inner && isNodeShaped(inner)) {
|
|
2441
2452
|
const score = num(wrapper.score);
|
|
2442
2453
|
return score !== void 0 ? { ...inner, retrieval_score: score } : inner;
|
|
@@ -2474,7 +2485,7 @@ function sourceTag(node) {
|
|
|
2474
2485
|
return `from: ${title}${extra}`;
|
|
2475
2486
|
}
|
|
2476
2487
|
function layer7Fields(node, state) {
|
|
2477
|
-
const fields =
|
|
2488
|
+
const fields = nodeFields(node);
|
|
2478
2489
|
if (!fields) return void 0;
|
|
2479
2490
|
const pairs = Object.entries(fields).filter(([, value]) => value !== null && value !== void 0 && value !== "").map(([key, value]) => `${key}: ${Array.isArray(value) ? value.join(", ") : String(value)}`);
|
|
2480
2491
|
if (pairs.length === 0) return void 0;
|
|
@@ -2486,7 +2497,7 @@ function nodeSummaryText(node, state) {
|
|
|
2486
2497
|
}
|
|
2487
2498
|
function nodeLines(node, state) {
|
|
2488
2499
|
const label = clip(node.label, LABEL_MAX, state) || "(unlabeled)";
|
|
2489
|
-
const type =
|
|
2500
|
+
const type = nodeDisplayType(node);
|
|
2490
2501
|
const confidence = num(node.confidence);
|
|
2491
2502
|
const score = num(node.retrieval_score);
|
|
2492
2503
|
const parenthetical = [
|
|
@@ -2505,19 +2516,19 @@ function nodeLines(node, state) {
|
|
|
2505
2516
|
if (source) lines.push(` - ${source}`);
|
|
2506
2517
|
const believers = Array.isArray(node.believed_by) ? node.believed_by : [];
|
|
2507
2518
|
if (believers.length > 0) {
|
|
2508
|
-
const
|
|
2519
|
+
const rendered2 = believers.slice(0, 3).map((raw) => {
|
|
2509
2520
|
const believer = obj(raw);
|
|
2510
2521
|
const conf = num(believer?.confidence);
|
|
2511
2522
|
return `${str(believer?.agent_label) || "?"}${conf !== void 0 ? ` (${conf})` : ""}`;
|
|
2512
2523
|
}).join(", ");
|
|
2513
|
-
lines.push(` - believed by: ${
|
|
2524
|
+
lines.push(` - believed by: ${rendered2}`);
|
|
2514
2525
|
}
|
|
2515
2526
|
return lines.join("\n");
|
|
2516
2527
|
}
|
|
2517
2528
|
function groupedNodeSections(nodes, state, headingPrefix = "") {
|
|
2518
2529
|
const groups = /* @__PURE__ */ new Map();
|
|
2519
2530
|
for (const node of nodes) {
|
|
2520
|
-
const type =
|
|
2531
|
+
const type = nodeDisplayType(node);
|
|
2521
2532
|
const group = groups.get(type) ?? [];
|
|
2522
2533
|
group.push(node);
|
|
2523
2534
|
groups.set(type, group);
|
|
@@ -2533,7 +2544,7 @@ function groupedNodeSections(nodes, state, headingPrefix = "") {
|
|
|
2533
2544
|
}
|
|
2534
2545
|
return sections;
|
|
2535
2546
|
}
|
|
2536
|
-
function relationshipItems(edges, labelByUid, state) {
|
|
2547
|
+
function relationshipItems(edges, labelByUid, state, options) {
|
|
2537
2548
|
const lines = [];
|
|
2538
2549
|
for (const raw of edges) {
|
|
2539
2550
|
const edge = obj(raw);
|
|
@@ -2543,8 +2554,8 @@ function relationshipItems(edges, labelByUid, state) {
|
|
|
2543
2554
|
const to = str(edge.to_uid);
|
|
2544
2555
|
if (CURATION_EDGE_TYPES.has(type)) continue;
|
|
2545
2556
|
if (!from || !to || from === to) continue;
|
|
2546
|
-
const fromLabel = labelByUid.get(from);
|
|
2547
|
-
const toLabel = labelByUid.get(to);
|
|
2557
|
+
const fromLabel = labelByUid.get(from) ?? (options?.fallbackToUid ? `[${from}]` : void 0);
|
|
2558
|
+
const toLabel = labelByUid.get(to) ?? (options?.fallbackToUid ? `[${to}]` : void 0);
|
|
2548
2559
|
if (!fromLabel || !toLabel) continue;
|
|
2549
2560
|
lines.push(`- ${fromLabel} \u2014${type}\u2192 ${toLabel}`);
|
|
2550
2561
|
}
|
|
@@ -2587,8 +2598,8 @@ function assemble(header, sections, state) {
|
|
|
2587
2598
|
sectionUsed += marker.length + 1;
|
|
2588
2599
|
}
|
|
2589
2600
|
lines.push(
|
|
2590
|
-
section.items.length === 0 ? section.heading : `${section.heading}
|
|
2591
|
-
${kept.join("\n")}`
|
|
2601
|
+
section.items.length === 0 ? section.heading : section.heading ? `${section.heading}
|
|
2602
|
+
${kept.join("\n")}` : kept.join("\n")
|
|
2592
2603
|
);
|
|
2593
2604
|
used += headingCost + sectionUsed;
|
|
2594
2605
|
}
|
|
@@ -2751,7 +2762,157 @@ function renderTraversal(response) {
|
|
|
2751
2762
|
}
|
|
2752
2763
|
return assemble("# Graph traversal", sections, state);
|
|
2753
2764
|
}
|
|
2754
|
-
|
|
2765
|
+
function neighborLine(value) {
|
|
2766
|
+
const node = obj(value);
|
|
2767
|
+
if (!node) return void 0;
|
|
2768
|
+
const label = str(node.label) || "(unlabeled)";
|
|
2769
|
+
const uid = str(node.uid);
|
|
2770
|
+
const type = str(node.node_type);
|
|
2771
|
+
return `- ${label}${uid ? ` [${uid}]` : ""}${type ? ` (${type})` : ""}`;
|
|
2772
|
+
}
|
|
2773
|
+
function renderOntologyAnswer(response) {
|
|
2774
|
+
const payload = obj(response);
|
|
2775
|
+
if (!payload) return void 0;
|
|
2776
|
+
const objects = Array.isArray(payload.objects) ? payload.objects.filter(isNodeShaped) : isNodeShaped(payload.object) ? [payload.object] : [];
|
|
2777
|
+
const cognitive = obj(payload.cognitive_context);
|
|
2778
|
+
const provenance = Array.isArray(payload.provenance) ? payload.provenance : [];
|
|
2779
|
+
const hasQuerySignature = Array.isArray(payload.objects) || obj(payload.confidence) !== void 0;
|
|
2780
|
+
const cognitiveEmpty = !cognitive || Object.values(cognitive).every((v) => !Array.isArray(v) || v.length === 0);
|
|
2781
|
+
if (objects.length === 0 && cognitiveEmpty && provenance.length === 0) {
|
|
2782
|
+
return hasQuerySignature ? "No matching domain objects." : void 0;
|
|
2783
|
+
}
|
|
2784
|
+
const state = { bounded: false };
|
|
2785
|
+
const sections = [];
|
|
2786
|
+
if (objects.length > 0) {
|
|
2787
|
+
sections.push(...groupedNodeSections(objects, state));
|
|
2788
|
+
}
|
|
2789
|
+
const labelByUid = /* @__PURE__ */ new Map();
|
|
2790
|
+
for (const node of objects) labelByUid.set(str(node.uid), str(node.label) || "?");
|
|
2791
|
+
const graph = obj(payload.graph);
|
|
2792
|
+
for (const raw of Array.isArray(graph?.nodes) ? graph.nodes : []) {
|
|
2793
|
+
const node = obj(raw);
|
|
2794
|
+
const uid = str(node?.uid);
|
|
2795
|
+
if (uid && !labelByUid.has(uid)) labelByUid.set(uid, str(node?.label) || "?");
|
|
2796
|
+
}
|
|
2797
|
+
if (cognitive) {
|
|
2798
|
+
for (const rawNodes of Object.values(cognitive)) {
|
|
2799
|
+
if (!Array.isArray(rawNodes)) continue;
|
|
2800
|
+
for (const raw of rawNodes) {
|
|
2801
|
+
const node = obj(raw);
|
|
2802
|
+
const uid = str(node?.uid);
|
|
2803
|
+
if (uid && !labelByUid.has(uid)) labelByUid.set(uid, str(node?.label) || "?");
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
const relations = Array.isArray(payload.relations) ? payload.relations : [];
|
|
2808
|
+
const relationLines = relationshipItems(relations, labelByUid, state, { fallbackToUid: true });
|
|
2809
|
+
if (relationLines.length > 0) {
|
|
2810
|
+
sections.push({ heading: "## Relations", items: relationLines });
|
|
2811
|
+
}
|
|
2812
|
+
if (cognitive) {
|
|
2813
|
+
for (const [category, rawNodes] of Object.entries(cognitive)) {
|
|
2814
|
+
if (!Array.isArray(rawNodes) || rawNodes.length === 0) continue;
|
|
2815
|
+
const items = rawNodes.map(neighborLine).filter((line) => Boolean(line));
|
|
2816
|
+
if (items.length > 0) {
|
|
2817
|
+
sections.push({ heading: `### Cognitive context \u2014 ${category}`, items });
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
if (provenance.length > 0) {
|
|
2822
|
+
const items = provenance.map((raw) => obj(raw)).filter((entry) => Boolean(entry)).map((entry) => {
|
|
2823
|
+
const span = clip(entry.text_span, QUOTE_MAX, state) || "";
|
|
2824
|
+
const by = str(entry.ingested_by_name);
|
|
2825
|
+
const suffix = `${by ? ` (ingested by ${by})` : ""} [source ${str(entry.source_uid) || "?"}]`;
|
|
2826
|
+
return str(entry.span_kind) === "anchor" ? `- "${span}"${suffix}` : `- context: ${span}${suffix}`;
|
|
2827
|
+
});
|
|
2828
|
+
sections.push({ heading: "## Sources", items });
|
|
2829
|
+
}
|
|
2830
|
+
const confidence = num(obj(payload.confidence)?.overall);
|
|
2831
|
+
const notes = [];
|
|
2832
|
+
if (confidence !== void 0) notes.push(`overall confidence ${confidence}`);
|
|
2833
|
+
if (payload.has_more === true) notes.push("more results exist (has_more)");
|
|
2834
|
+
if (payload.seed_cap_hit === true) notes.push("seed cap hit \u2014 narrow the query for a complete set");
|
|
2835
|
+
if (notes.length > 0) sections.push({ heading: `Note: ${notes.join("; ")}.`, items: [] });
|
|
2836
|
+
return assemble(
|
|
2837
|
+
`# Ontology results (${objects.length} object${objects.length === 1 ? "" : "s"})`,
|
|
2838
|
+
sections,
|
|
2839
|
+
state
|
|
2840
|
+
);
|
|
2841
|
+
}
|
|
2842
|
+
function renderObjectList(response, title) {
|
|
2843
|
+
const payload = obj(response);
|
|
2844
|
+
if (!payload) return void 0;
|
|
2845
|
+
const rawItems = Array.isArray(payload.items) ? payload.items : Array.isArray(payload.rows) && payload.rows.some((row) => unwrapSearchResult(row)) ? payload.rows : void 0;
|
|
2846
|
+
const items = (rawItems ?? []).map(unwrapSearchResult).filter((node) => Boolean(node));
|
|
2847
|
+
if (items.length === 0) {
|
|
2848
|
+
return rawItems ? `# ${title} (0 results)` : void 0;
|
|
2849
|
+
}
|
|
2850
|
+
const state = { bounded: false };
|
|
2851
|
+
const sections = groupedNodeSections(items, state);
|
|
2852
|
+
const total = num(payload.total_count);
|
|
2853
|
+
const truncations = Array.isArray(payload.truncation_reasons) ? payload.truncation_reasons.filter((reason) => typeof reason === "string") : [];
|
|
2854
|
+
const notes = [];
|
|
2855
|
+
if (payload.has_more === true) notes.push("more results exist");
|
|
2856
|
+
if (truncations.length > 0) notes.push(`truncated: ${truncations.join(", ")}`);
|
|
2857
|
+
if (notes.length > 0) sections.push({ heading: `Note: ${notes.join("; ")}.`, items: [] });
|
|
2858
|
+
const count = total !== void 0 && total !== items.length ? `${items.length} of ${total}` : `${items.length}`;
|
|
2859
|
+
return assemble(`# ${title} (${count})`, sections, state);
|
|
2860
|
+
}
|
|
2861
|
+
function renderJobs(response) {
|
|
2862
|
+
const jobs = Array.isArray(response) ? response : obj(response)?.jobs;
|
|
2863
|
+
if (!Array.isArray(jobs)) return void 0;
|
|
2864
|
+
if (jobs.length === 0) return "No ingestion jobs.";
|
|
2865
|
+
const state = { bounded: false };
|
|
2866
|
+
const sorted = jobs.map((raw) => obj(raw)).filter((job) => Boolean(job)).sort((a, b) => (num(b.created_at) ?? 0) - (num(a.created_at) ?? 0));
|
|
2867
|
+
const shown = sorted.slice(0, JOBS_RENDER_MAX);
|
|
2868
|
+
if (shown.length < sorted.length) state.bounded = true;
|
|
2869
|
+
const items = shown.map((job) => {
|
|
2870
|
+
const progress = obj(job.progress);
|
|
2871
|
+
const done = num(progress?.processed_chunks);
|
|
2872
|
+
const totalChunks = num(progress?.total_chunks);
|
|
2873
|
+
const bits = [
|
|
2874
|
+
str(job.status) || "?",
|
|
2875
|
+
done !== void 0 && totalChunks !== void 0 ? `${done}/${totalChunks} chunks` : void 0,
|
|
2876
|
+
num(progress?.nodes_created) !== void 0 ? `${num(progress?.nodes_created)} nodes` : void 0,
|
|
2877
|
+
num(job.queue_position) !== void 0 ? `queue #${num(job.queue_position)}` : void 0,
|
|
2878
|
+
str(job.error) ? `error: ${clip(job.error, 160, state)}` : void 0
|
|
2879
|
+
].filter(Boolean);
|
|
2880
|
+
return `- [${str(job.id) || "?"}] ${clip(job.title, 120, state) || "(untitled)"} \u2014 ${bits.join(", ")}`;
|
|
2881
|
+
});
|
|
2882
|
+
return assemble(
|
|
2883
|
+
`# Ingestion jobs (${shown.length}${shown.length < sorted.length ? ` of ${sorted.length}` : ""})`,
|
|
2884
|
+
[{ heading: "", items }],
|
|
2885
|
+
state
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
function renderSignals(response) {
|
|
2889
|
+
const payload = obj(response);
|
|
2890
|
+
if (!payload) return void 0;
|
|
2891
|
+
const state = { bounded: false };
|
|
2892
|
+
const sections = [];
|
|
2893
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
2894
|
+
if (!Array.isArray(value) || value.length === 0) continue;
|
|
2895
|
+
const items = value.map((raw) => obj(raw)).filter((item) => Boolean(item)).map((item) => {
|
|
2896
|
+
const fromLabel = str(item.from_label);
|
|
2897
|
+
const toLabel = str(item.to_label);
|
|
2898
|
+
const anyLabelKey = Object.keys(item).find(
|
|
2899
|
+
(k) => k.endsWith("_label") && str(item[k])
|
|
2900
|
+
);
|
|
2901
|
+
const label = str(item.label) ?? str(item.title) ?? str(item.name) ?? (fromLabel && toLabel ? `${fromLabel} \u2194 ${toLabel}` : void 0) ?? (anyLabelKey ? str(item[anyLabelKey]) : void 0) ?? str(item.uid) ?? str(item.target_uid) ?? "(item)";
|
|
2902
|
+
const uid = str(item.uid) ?? str(item.target_uid);
|
|
2903
|
+
const numbers = Object.entries(item).filter(([, v]) => typeof v === "number").slice(0, 4).map(([k, v]) => `${k} ${Math.round(v * 100) / 100}`);
|
|
2904
|
+
const lists = Object.entries(item).filter(([, v]) => Array.isArray(v) && v.length > 0).slice(0, 2).map(([k, v]) => `${k}: ${v.length}`);
|
|
2905
|
+
const meta = [...numbers, ...lists].join(", ");
|
|
2906
|
+
return `- ${clip(label, 160, state)}${uid && uid !== label ? ` [${uid}]` : ""}${meta ? ` (${meta})` : ""}`;
|
|
2907
|
+
});
|
|
2908
|
+
if (items.length > 0) {
|
|
2909
|
+
sections.push({ heading: `## ${key.replace(/_/g, " ")}`, items });
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
if (sections.length === 0) return void 0;
|
|
2913
|
+
return assemble("# Synthesis signals", sections, state);
|
|
2914
|
+
}
|
|
2915
|
+
var LABEL_MAX, SUMMARY_MAX, QUOTE_MAX, ARTICLE_MAX, CHUNK_MAX, RELATIONSHIP_MAX, RENDER_CHAR_BUDGET, CURATION_EDGE_TYPES, INFRA_NODE_TYPES, JOBS_RENDER_MAX;
|
|
2755
2916
|
var init_render = __esm({
|
|
2756
2917
|
"src/render.ts"() {
|
|
2757
2918
|
"use strict";
|
|
@@ -2764,6 +2925,7 @@ var init_render = __esm({
|
|
|
2764
2925
|
RENDER_CHAR_BUDGET = 24e3;
|
|
2765
2926
|
CURATION_EDGE_TYPES = /* @__PURE__ */ new Set(["POSSIBLE_DUPLICATE", "PossibleDuplicate"]);
|
|
2766
2927
|
INFRA_NODE_TYPES = /* @__PURE__ */ new Set(["Chunk", "Document", "Article"]);
|
|
2928
|
+
JOBS_RENDER_MAX = 20;
|
|
2767
2929
|
}
|
|
2768
2930
|
});
|
|
2769
2931
|
|
|
@@ -2776,9 +2938,14 @@ function toolsForProfile(profile = process.env.MINDGRAPH_PROFILE || "general") {
|
|
|
2776
2938
|
}
|
|
2777
2939
|
function ok3(data) {
|
|
2778
2940
|
return {
|
|
2779
|
-
content: [{ type: "text", text: JSON.stringify(data
|
|
2941
|
+
content: [{ type: "text", text: JSON.stringify(data) }]
|
|
2780
2942
|
};
|
|
2781
2943
|
}
|
|
2944
|
+
function renderedResult(format, raw, render) {
|
|
2945
|
+
if (format === "json") return ok3(raw);
|
|
2946
|
+
const text = render(raw);
|
|
2947
|
+
return text !== void 0 ? { content: [{ type: "text", text }] } : ok3(raw);
|
|
2948
|
+
}
|
|
2782
2949
|
function err3(message) {
|
|
2783
2950
|
return {
|
|
2784
2951
|
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
|
@@ -3390,15 +3557,11 @@ async function handleRetrieve(client2, args) {
|
|
|
3390
3557
|
max_cost,
|
|
3391
3558
|
agent_id
|
|
3392
3559
|
} = args;
|
|
3393
|
-
const
|
|
3394
|
-
if (format === "json") return ok3(raw);
|
|
3395
|
-
const text = render(raw);
|
|
3396
|
-
return text !== void 0 ? { content: [{ type: "text", text }] } : ok3(raw);
|
|
3397
|
-
};
|
|
3560
|
+
const rendered2 = (raw, render) => renderedResult(format, raw, render);
|
|
3398
3561
|
switch (action) {
|
|
3399
3562
|
case "context":
|
|
3400
3563
|
if (!query) return err3("query is required for context retrieval");
|
|
3401
|
-
return
|
|
3564
|
+
return rendered2(
|
|
3402
3565
|
await client2.retrieveContext({
|
|
3403
3566
|
query,
|
|
3404
3567
|
node_limit: limit,
|
|
@@ -3423,7 +3586,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3423
3586
|
);
|
|
3424
3587
|
case "text":
|
|
3425
3588
|
if (!query) return err3("query is required for text search");
|
|
3426
|
-
return
|
|
3589
|
+
return rendered2(
|
|
3427
3590
|
await client2.retrieve({
|
|
3428
3591
|
action: "text",
|
|
3429
3592
|
query,
|
|
@@ -3437,7 +3600,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3437
3600
|
);
|
|
3438
3601
|
case "semantic":
|
|
3439
3602
|
if (!query) return err3("query is required for semantic search");
|
|
3440
|
-
return
|
|
3603
|
+
return rendered2(
|
|
3441
3604
|
await client2.retrieve({
|
|
3442
3605
|
action: "semantic",
|
|
3443
3606
|
query,
|
|
@@ -3451,7 +3614,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3451
3614
|
);
|
|
3452
3615
|
case "hybrid":
|
|
3453
3616
|
if (!query) return err3("query is required for hybrid search");
|
|
3454
|
-
return
|
|
3617
|
+
return rendered2(
|
|
3455
3618
|
await client2.retrieve({
|
|
3456
3619
|
action: "hybrid",
|
|
3457
3620
|
query,
|
|
@@ -3473,7 +3636,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3473
3636
|
case "weak_claims":
|
|
3474
3637
|
case "pending_approvals":
|
|
3475
3638
|
case "unresolved_contradictions":
|
|
3476
|
-
return
|
|
3639
|
+
return rendered2(
|
|
3477
3640
|
await client2.retrieve({
|
|
3478
3641
|
action,
|
|
3479
3642
|
limit,
|
|
@@ -3483,7 +3646,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3483
3646
|
(raw) => renderNodeList(raw, action.replace(/_/g, " "), limit)
|
|
3484
3647
|
);
|
|
3485
3648
|
case "stale_derivations":
|
|
3486
|
-
return
|
|
3649
|
+
return rendered2(
|
|
3487
3650
|
await client2.retrieve({
|
|
3488
3651
|
action: "stale_derivations",
|
|
3489
3652
|
limit,
|
|
@@ -3492,7 +3655,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3492
3655
|
(raw) => renderNodeList(raw, "stale derivations", limit)
|
|
3493
3656
|
);
|
|
3494
3657
|
case "preferences":
|
|
3495
|
-
return
|
|
3658
|
+
return rendered2(
|
|
3496
3659
|
await client2.retrieve({
|
|
3497
3660
|
action: "preferences",
|
|
3498
3661
|
...query ? { query, k: limit } : {},
|
|
@@ -3503,7 +3666,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3503
3666
|
);
|
|
3504
3667
|
case "layer":
|
|
3505
3668
|
if (!layer) return err3("layer is required for layer retrieval");
|
|
3506
|
-
return
|
|
3669
|
+
return rendered2(
|
|
3507
3670
|
await client2.retrieve({
|
|
3508
3671
|
action: "layer",
|
|
3509
3672
|
layer,
|
|
@@ -3514,7 +3677,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3514
3677
|
(raw) => renderNodeList(raw, `Layer: ${layer}`, limit)
|
|
3515
3678
|
);
|
|
3516
3679
|
case "recent":
|
|
3517
|
-
return
|
|
3680
|
+
return rendered2(
|
|
3518
3681
|
await client2.retrieve({
|
|
3519
3682
|
action: "recent",
|
|
3520
3683
|
limit,
|
|
@@ -3529,7 +3692,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3529
3692
|
);
|
|
3530
3693
|
// Document inventory
|
|
3531
3694
|
case "document_index":
|
|
3532
|
-
return
|
|
3695
|
+
return rendered2(
|
|
3533
3696
|
await client2.getNodes({
|
|
3534
3697
|
node_type: "Document",
|
|
3535
3698
|
limit: limit ?? 100
|
|
@@ -3539,7 +3702,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3539
3702
|
// Graph traversal
|
|
3540
3703
|
case "chain":
|
|
3541
3704
|
if (!start_uid) return err3("start_uid is required for chain traversal");
|
|
3542
|
-
return
|
|
3705
|
+
return rendered2(
|
|
3543
3706
|
await client2.traverse({
|
|
3544
3707
|
action: "chain",
|
|
3545
3708
|
start_uid,
|
|
@@ -3552,7 +3715,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3552
3715
|
);
|
|
3553
3716
|
case "neighborhood":
|
|
3554
3717
|
if (!start_uid) return err3("start_uid is required for neighborhood traversal");
|
|
3555
|
-
return
|
|
3718
|
+
return rendered2(
|
|
3556
3719
|
await client2.traverse({
|
|
3557
3720
|
action: "neighborhood",
|
|
3558
3721
|
start_uid,
|
|
@@ -3568,7 +3731,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3568
3731
|
case "path":
|
|
3569
3732
|
if (!start_uid) return err3("start_uid is required for path traversal");
|
|
3570
3733
|
if (!end_uid) return err3("end_uid is required for path traversal");
|
|
3571
|
-
return
|
|
3734
|
+
return rendered2(
|
|
3572
3735
|
await client2.traverse({
|
|
3573
3736
|
action: "path",
|
|
3574
3737
|
start_uid,
|
|
@@ -3584,7 +3747,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3584
3747
|
);
|
|
3585
3748
|
case "subgraph":
|
|
3586
3749
|
if (!start_uid) return err3("start_uid is required for subgraph traversal");
|
|
3587
|
-
return
|
|
3750
|
+
return rendered2(
|
|
3588
3751
|
await client2.traverse({
|
|
3589
3752
|
action: "subgraph",
|
|
3590
3753
|
start_uid,
|
|
@@ -3600,7 +3763,7 @@ async function handleRetrieve(client2, args) {
|
|
|
3600
3763
|
case "top_k_paths":
|
|
3601
3764
|
if (!start_uid) return err3("start_uid is required for top_k_paths");
|
|
3602
3765
|
if (!end_uid) return err3("end_uid is required for top_k_paths");
|
|
3603
|
-
return
|
|
3766
|
+
return rendered2(
|
|
3604
3767
|
await client2.traverse({
|
|
3605
3768
|
action: "top_k_paths",
|
|
3606
3769
|
start_uid,
|
|
@@ -3637,6 +3800,7 @@ async function handleIngest(client2, args) {
|
|
|
3637
3800
|
chunk_size,
|
|
3638
3801
|
chunk_overlap,
|
|
3639
3802
|
job_id,
|
|
3803
|
+
format,
|
|
3640
3804
|
agent_id
|
|
3641
3805
|
} = args;
|
|
3642
3806
|
const src = source_uri ?? source;
|
|
@@ -3706,19 +3870,21 @@ async function handleIngest(client2, args) {
|
|
|
3706
3870
|
if (job_id) {
|
|
3707
3871
|
return ok3(await client2.getJob(job_id));
|
|
3708
3872
|
}
|
|
3709
|
-
return
|
|
3873
|
+
return renderedResult(format, await client2.listJobs(), renderJobs);
|
|
3710
3874
|
default:
|
|
3711
3875
|
return err3(`Unknown ingest action: ${action}`);
|
|
3712
3876
|
}
|
|
3713
3877
|
}
|
|
3714
3878
|
async function handleSynthesize(client2, args) {
|
|
3715
|
-
const { action, project_uid, signals, target_types, job_id } = args;
|
|
3879
|
+
const { action, project_uid, signals, target_types, job_id, format } = args;
|
|
3716
3880
|
switch (action) {
|
|
3717
3881
|
case "signals":
|
|
3718
3882
|
if (!project_uid)
|
|
3719
3883
|
return err3("project_uid is required for action='signals'");
|
|
3720
|
-
return
|
|
3721
|
-
|
|
3884
|
+
return renderedResult(
|
|
3885
|
+
format,
|
|
3886
|
+
await client2.signals(project_uid, { signals, target_types }),
|
|
3887
|
+
renderSignals
|
|
3722
3888
|
);
|
|
3723
3889
|
case "run":
|
|
3724
3890
|
if (!project_uid)
|
|
@@ -3752,6 +3918,7 @@ async function handleOntology(client2, args) {
|
|
|
3752
3918
|
relation_type,
|
|
3753
3919
|
fields,
|
|
3754
3920
|
source_uids,
|
|
3921
|
+
format,
|
|
3755
3922
|
agent_id
|
|
3756
3923
|
} = args;
|
|
3757
3924
|
switch (action) {
|
|
@@ -3767,7 +3934,8 @@ async function handleOntology(client2, args) {
|
|
|
3767
3934
|
"schema_id is required for action='query' (use action='schemas' to find the active schema)"
|
|
3768
3935
|
);
|
|
3769
3936
|
}
|
|
3770
|
-
return
|
|
3937
|
+
return renderedResult(
|
|
3938
|
+
format,
|
|
3771
3939
|
await client2.queryOntology({
|
|
3772
3940
|
query,
|
|
3773
3941
|
schema_id,
|
|
@@ -3776,29 +3944,42 @@ async function handleOntology(client2, args) {
|
|
|
3776
3944
|
include_sources: include_sources ?? true,
|
|
3777
3945
|
depth,
|
|
3778
3946
|
limit
|
|
3779
|
-
})
|
|
3947
|
+
}),
|
|
3948
|
+
renderOntologyAnswer
|
|
3780
3949
|
);
|
|
3781
3950
|
}
|
|
3782
3951
|
case "search":
|
|
3783
3952
|
if (!query) return err3("query is required for action='search'");
|
|
3784
|
-
return
|
|
3953
|
+
return renderedResult(
|
|
3954
|
+
format,
|
|
3785
3955
|
await client2.searchDomainObjects(query, {
|
|
3786
3956
|
schema_id,
|
|
3787
3957
|
object_types,
|
|
3788
3958
|
limit
|
|
3789
|
-
})
|
|
3959
|
+
}),
|
|
3960
|
+
(raw) => renderObjectList(raw, `Domain search: ${query}`)
|
|
3790
3961
|
);
|
|
3791
3962
|
case "objects":
|
|
3792
3963
|
if (!schema_id) return err3("schema_id is required for action='objects'");
|
|
3793
|
-
return
|
|
3794
|
-
|
|
3964
|
+
return renderedResult(
|
|
3965
|
+
format,
|
|
3966
|
+
await client2.listDomainObjects({ schema_id, object_type, limit }),
|
|
3967
|
+
(raw) => renderObjectList(raw, `Domain objects${object_type ? `: ${object_type}` : ""}`)
|
|
3795
3968
|
);
|
|
3796
3969
|
case "object":
|
|
3797
3970
|
if (!uid) return err3("uid is required for action='object'");
|
|
3798
|
-
return
|
|
3971
|
+
return renderedResult(
|
|
3972
|
+
format,
|
|
3973
|
+
await client2.getDomainObject(uid),
|
|
3974
|
+
(raw) => renderNodeList([raw], "Domain object")
|
|
3975
|
+
);
|
|
3799
3976
|
case "object_context":
|
|
3800
3977
|
if (!uid) return err3("uid is required for action='object_context'");
|
|
3801
|
-
return
|
|
3978
|
+
return renderedResult(
|
|
3979
|
+
format,
|
|
3980
|
+
await client2.getDomainObjectContext(uid, depth),
|
|
3981
|
+
renderOntologyAnswer
|
|
3982
|
+
);
|
|
3802
3983
|
case "proposals":
|
|
3803
3984
|
return ok3(
|
|
3804
3985
|
await client2.listOntologyProposals({
|
|
@@ -4665,6 +4846,11 @@ var init_tools = __esm({
|
|
|
4665
4846
|
type: "string",
|
|
4666
4847
|
description: "Job ID to check status (for job_status action)"
|
|
4667
4848
|
},
|
|
4849
|
+
format: {
|
|
4850
|
+
type: "string",
|
|
4851
|
+
enum: ["text", "json"],
|
|
4852
|
+
description: "job_status without job_id: 'text' (default) renders the 20 most recent jobs; 'json' returns the full raw list."
|
|
4853
|
+
},
|
|
4668
4854
|
agent_id: {
|
|
4669
4855
|
type: "string",
|
|
4670
4856
|
description: "Agent identity"
|
|
@@ -4700,6 +4886,11 @@ var init_tools = __esm({
|
|
|
4700
4886
|
type: "string",
|
|
4701
4887
|
description: "Job ID to poll (for action='job_status')"
|
|
4702
4888
|
},
|
|
4889
|
+
format: {
|
|
4890
|
+
type: "string",
|
|
4891
|
+
enum: ["text", "json"],
|
|
4892
|
+
description: "signals action: 'text' (default) renders signal sections; 'json' returns the raw payload."
|
|
4893
|
+
},
|
|
4703
4894
|
agent_id: {
|
|
4704
4895
|
type: "string",
|
|
4705
4896
|
description: "Agent identity"
|
|
@@ -4808,6 +4999,11 @@ var init_tools = __esm({
|
|
|
4808
4999
|
items: { type: "string" },
|
|
4809
5000
|
description: "Chunk/document UIDs to extract from (for action=extract)"
|
|
4810
5001
|
},
|
|
5002
|
+
format: {
|
|
5003
|
+
type: "string",
|
|
5004
|
+
enum: ["text", "json"],
|
|
5005
|
+
description: "Output format for the read actions query/search/objects/object/object_context (default 'text'): a compact rendered block. Pass 'json' for the raw server response."
|
|
5006
|
+
},
|
|
4811
5007
|
agent_id: {
|
|
4812
5008
|
type: "string",
|
|
4813
5009
|
description: "Agent identity"
|
|
@@ -4870,10 +5066,21 @@ async function getGeneratedTools(client2) {
|
|
|
4870
5066
|
);
|
|
4871
5067
|
}
|
|
4872
5068
|
byName.set(d.name, d);
|
|
5069
|
+
const inputSchema = d.maps_to === "structured_query" ? d.input_schema : {
|
|
5070
|
+
...d.input_schema,
|
|
5071
|
+
properties: {
|
|
5072
|
+
...d.input_schema.properties,
|
|
5073
|
+
format: {
|
|
5074
|
+
type: "string",
|
|
5075
|
+
enum: ["text", "json"],
|
|
5076
|
+
description: "Output format (default 'text': compact rendered block). Pass 'json' for the raw server response."
|
|
5077
|
+
}
|
|
5078
|
+
}
|
|
5079
|
+
};
|
|
4873
5080
|
tools.push({
|
|
4874
5081
|
name: d.name,
|
|
4875
5082
|
description: d.description,
|
|
4876
|
-
inputSchema
|
|
5083
|
+
inputSchema
|
|
4877
5084
|
});
|
|
4878
5085
|
}
|
|
4879
5086
|
cache = { tools, byName, fetchedAt: Date.now() };
|
|
@@ -4894,31 +5101,41 @@ async function handleGeneratedTool(client2, desc, args) {
|
|
|
4894
5101
|
if (!query) return err4(`query is required for ${desc.name}`);
|
|
4895
5102
|
const limit = typeof args.limit === "number" ? args.limit : void 0;
|
|
4896
5103
|
const filters = Array.isArray(args.filters) ? args.filters : void 0;
|
|
4897
|
-
return
|
|
5104
|
+
return rendered(
|
|
5105
|
+
args.format,
|
|
4898
5106
|
await ontologyClient.searchDomainObjects(query, {
|
|
4899
5107
|
schema_id: desc.schema_id,
|
|
4900
5108
|
object_types: [desc.object_type],
|
|
4901
5109
|
filters,
|
|
4902
5110
|
limit
|
|
4903
|
-
})
|
|
5111
|
+
}),
|
|
5112
|
+
(raw) => renderObjectList(raw, `${desc.object_type} search: ${query}`)
|
|
4904
5113
|
);
|
|
4905
5114
|
}
|
|
4906
5115
|
case "object": {
|
|
4907
5116
|
const uid = args.uid;
|
|
4908
5117
|
if (!uid) return err4(`uid is required for ${desc.name}`);
|
|
4909
|
-
return
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
5118
|
+
return rendered(
|
|
5119
|
+
args.format,
|
|
5120
|
+
await ontologyClient.getDomainObject(uid, {
|
|
5121
|
+
schema_id: desc.schema_id,
|
|
5122
|
+
object_type: desc.object_type
|
|
5123
|
+
}),
|
|
5124
|
+
(raw) => renderNodeList([raw], desc.object_type)
|
|
5125
|
+
);
|
|
4913
5126
|
}
|
|
4914
5127
|
case "object_context": {
|
|
4915
5128
|
const uid = args.uid;
|
|
4916
5129
|
if (!uid) return err4(`uid is required for ${desc.name}`);
|
|
4917
5130
|
const depth = typeof args.depth === "number" ? args.depth : void 0;
|
|
4918
|
-
return
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
5131
|
+
return rendered(
|
|
5132
|
+
args.format,
|
|
5133
|
+
await ontologyClient.getDomainObjectContext(uid, depth, {
|
|
5134
|
+
schema_id: desc.schema_id,
|
|
5135
|
+
object_type: desc.object_type
|
|
5136
|
+
}),
|
|
5137
|
+
renderOntologyAnswer
|
|
5138
|
+
);
|
|
4922
5139
|
}
|
|
4923
5140
|
case "related": {
|
|
4924
5141
|
const uid = args.uid;
|
|
@@ -4931,18 +5148,22 @@ async function handleGeneratedTool(client2, desc, args) {
|
|
|
4931
5148
|
"related ontology tools require a graph-aware version of the mindgraph SDK"
|
|
4932
5149
|
);
|
|
4933
5150
|
}
|
|
4934
|
-
return
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
5151
|
+
return rendered(
|
|
5152
|
+
args.format,
|
|
5153
|
+
await ontologyClient.queryRelatedDomainObjects({
|
|
5154
|
+
schema_id: desc.schema_id,
|
|
5155
|
+
entry_type: desc.object_type,
|
|
5156
|
+
uid,
|
|
5157
|
+
relation: desc.relation,
|
|
5158
|
+
entry_role: desc.entry_role,
|
|
5159
|
+
far_type: desc.far_type,
|
|
5160
|
+
where: Array.isArray(args.where) ? args.where : void 0,
|
|
5161
|
+
include_provenance: args.include_provenance === true,
|
|
5162
|
+
limit: typeof args.limit === "number" ? args.limit : void 0,
|
|
5163
|
+
offset: typeof args.offset === "number" ? args.offset : void 0
|
|
5164
|
+
}),
|
|
5165
|
+
(raw) => renderObjectList(raw, `${desc.far_type} related via ${desc.relation}`)
|
|
5166
|
+
);
|
|
4946
5167
|
}
|
|
4947
5168
|
case "structured_query": {
|
|
4948
5169
|
const select = args.select;
|
|
@@ -4968,13 +5189,20 @@ async function handleGeneratedTool(client2, desc, args) {
|
|
|
4968
5189
|
return err4(e instanceof Error ? e.message : String(e));
|
|
4969
5190
|
}
|
|
4970
5191
|
}
|
|
4971
|
-
var ok4, err4, CACHE_TTL_MS, FAILURE_COOLDOWN_MS, cache, retryNotBefore, EMPTY, DuplicateGeneratedToolError, STRUCTURED_QUERY_PASSTHROUGH;
|
|
5192
|
+
var ok4, rendered, err4, CACHE_TTL_MS, FAILURE_COOLDOWN_MS, cache, retryNotBefore, EMPTY, DuplicateGeneratedToolError, STRUCTURED_QUERY_PASSTHROUGH;
|
|
4972
5193
|
var init_generated_tools = __esm({
|
|
4973
5194
|
"src/generated-tools.ts"() {
|
|
4974
5195
|
"use strict";
|
|
5196
|
+
init_render();
|
|
4975
5197
|
ok4 = (data) => ({
|
|
4976
|
-
|
|
5198
|
+
// Compact on purpose — pretty-printing doubled the token cost.
|
|
5199
|
+
content: [{ type: "text", text: JSON.stringify(data) }]
|
|
4977
5200
|
});
|
|
5201
|
+
rendered = (format, raw, render) => {
|
|
5202
|
+
if (format === "json") return ok4(raw);
|
|
5203
|
+
const text = render(raw);
|
|
5204
|
+
return text !== void 0 ? { content: [{ type: "text", text }] } : ok4(raw);
|
|
5205
|
+
};
|
|
4978
5206
|
err4 = (message) => ({
|
|
4979
5207
|
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
|
4980
5208
|
isError: true
|
|
@@ -5245,7 +5473,7 @@ var init_governance = __esm({
|
|
|
5245
5473
|
// src/resources.ts
|
|
5246
5474
|
function json(uri, data) {
|
|
5247
5475
|
return {
|
|
5248
|
-
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(data
|
|
5476
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(data) }]
|
|
5249
5477
|
};
|
|
5250
5478
|
}
|
|
5251
5479
|
async function readResource(client2, uri) {
|
|
@@ -5359,7 +5587,7 @@ async function main() {
|
|
|
5359
5587
|
const transport = new import_stdio.StdioServerTransport();
|
|
5360
5588
|
await server.connect(transport);
|
|
5361
5589
|
console.error(
|
|
5362
|
-
`MindGraph MCP server v${"0.
|
|
5590
|
+
`MindGraph MCP server v${"0.17.0"} running on stdio (${BASE_URL})`
|
|
5363
5591
|
);
|
|
5364
5592
|
}
|
|
5365
5593
|
var import_server, import_stdio, import_types, API_KEY, BASE_URL, AGENT_ID, ORG_ID, PROFILE, HARNESS, client, INSTRUCTIONS, server, GOVERNANCE_CONFIG, PROMPTS;
|
|
@@ -5499,7 +5727,7 @@ Capture knowledge when the user shares something worth remembering:
|
|
|
5499
5727
|
server = new import_server.Server(
|
|
5500
5728
|
{
|
|
5501
5729
|
name: "mindgraph",
|
|
5502
|
-
version: "0.
|
|
5730
|
+
version: "0.17.0"
|
|
5503
5731
|
},
|
|
5504
5732
|
{
|
|
5505
5733
|
capabilities: {
|
|
@@ -6064,8 +6292,8 @@ ${knowledgeLines.join("\n")}`);
|
|
|
6064
6292
|
);
|
|
6065
6293
|
}
|
|
6066
6294
|
if (footer) lines.push(footer);
|
|
6067
|
-
const
|
|
6068
|
-
return
|
|
6295
|
+
const rendered2 = lines.join("\n");
|
|
6296
|
+
return rendered2.length <= BRIEF_CHAR_BUDGET ? rendered2 : `${rendered2.slice(0, BRIEF_CHAR_BUDGET - 40)}
|
|
6069
6297
|
\u2026[bounded work brief truncated]`;
|
|
6070
6298
|
}
|
|
6071
6299
|
async function repositoryScopeUids(input, client2, options, agentId) {
|