mindgraph-mcp 0.14.8 → 0.15.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/dist/index.js CHANGED
@@ -28,6 +28,38 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
28
28
  var import_types = require("@modelcontextprotocol/sdk/types.js");
29
29
  var import_mindgraph2 = require("mindgraph");
30
30
 
31
+ // src/hook-env.ts
32
+ var import_node_crypto = __toESM(require("crypto"));
33
+ var import_node_fs = __toESM(require("fs"));
34
+ var import_node_os = __toESM(require("os"));
35
+ var import_node_path = __toESM(require("path"));
36
+ function stableAgentId() {
37
+ let user = "user";
38
+ try {
39
+ user = import_node_os.default.userInfo().username || "user";
40
+ } catch {
41
+ }
42
+ const digest = import_node_crypto.default.createHash("sha256").update(`${user}@${import_node_os.default.hostname()}`).digest("hex").slice(0, 12);
43
+ return `u-${digest}`;
44
+ }
45
+ function hookEnvPath(dir) {
46
+ return import_node_path.default.join(dir || import_node_path.default.join(import_node_os.default.homedir(), ".mindgraph"), "hooks.json");
47
+ }
48
+ function loadHookEnv(dir) {
49
+ try {
50
+ const raw = import_node_fs.default.readFileSync(hookEnvPath(dir), "utf8");
51
+ const parsed = JSON.parse(raw);
52
+ return {
53
+ baseUrl: typeof parsed.baseUrl === "string" ? parsed.baseUrl : void 0,
54
+ apiKey: typeof parsed.apiKey === "string" ? parsed.apiKey : void 0,
55
+ agentId: typeof parsed.agentId === "string" ? parsed.agentId : void 0,
56
+ orgId: typeof parsed.orgId === "string" ? parsed.orgId : void 0
57
+ };
58
+ } catch {
59
+ return {};
60
+ }
61
+ }
62
+
31
63
  // src/error-detail.ts
32
64
  var import_mindgraph = require("mindgraph");
33
65
  function errorDetail(e) {
@@ -37,14 +69,31 @@ function errorDetail(e) {
37
69
  }
38
70
  return e instanceof Error ? e.message : String(e);
39
71
  }
72
+ var CONFLICT_STATE_KEYS = [
73
+ "current_version",
74
+ "current_epoch",
75
+ "lease_expires_at",
76
+ "lease_owner_agent_id"
77
+ ];
78
+ function conflictState(e) {
79
+ if (!(e instanceof import_mindgraph.MindGraphError) || !e.body || typeof e.body !== "object") {
80
+ return {};
81
+ }
82
+ const body = e.body;
83
+ const lifted = {};
84
+ for (const key of CONFLICT_STATE_KEYS) {
85
+ if (body[key] !== void 0) lifted[key] = body[key];
86
+ }
87
+ return lifted;
88
+ }
40
89
 
41
90
  // src/codegraph.ts
42
91
  var import_node_child_process = require("child_process");
43
- var import_node_fs = require("fs");
92
+ var import_node_fs2 = require("fs");
44
93
  var import_promises = require("fs/promises");
45
- var import_node_os = require("os");
46
- var import_node_path = require("path");
47
- var import_node_crypto = require("crypto");
94
+ var import_node_os2 = require("os");
95
+ var import_node_path2 = require("path");
96
+ var import_node_crypto2 = require("crypto");
48
97
  function unavailabilityCaveats(reason, message) {
49
98
  const caveats = [message || "codegraph status failed"];
50
99
  if (reason === "absent") {
@@ -57,14 +106,14 @@ function unavailabilityCaveats(reason, message) {
57
106
  var DEFAULT_TIMEOUT_MS = 5e3;
58
107
  var DEFAULT_STATUS_TTL_MS = 6e4;
59
108
  var MAX_OUTPUT_BYTES = 5 * 1024 * 1024;
60
- function normalizePath(path2) {
61
- return path2.replaceAll("\\", "/").replace(/^\.\//, "");
109
+ function normalizePath(path3) {
110
+ return path3.replaceAll("\\", "/").replace(/^\.\//, "");
62
111
  }
63
112
  function normalizeSignature(signature) {
64
113
  return signature.replace(/\s+/g, " ").trim();
65
114
  }
66
- function languageFromPath(path2) {
67
- const extension = (0, import_node_path.extname)(path2).toLowerCase();
115
+ function languageFromPath(path3) {
116
+ const extension = (0, import_node_path2.extname)(path3).toLowerCase();
68
117
  return {
69
118
  ".c": "c",
70
119
  ".cc": "cpp",
@@ -113,30 +162,30 @@ function normalizeRemote(remote) {
113
162
  }
114
163
  }
115
164
  function pathContains(root, candidate) {
116
- const child = (0, import_node_path.relative)(root, candidate);
117
- return child === "" || child !== ".." && !child.startsWith(`..${import_node_path.sep}`) && !(0, import_node_path.isAbsolute)(child);
165
+ const child = (0, import_node_path2.relative)(root, candidate);
166
+ return child === "" || child !== ".." && !child.startsWith(`..${import_node_path2.sep}`) && !(0, import_node_path2.isAbsolute)(child);
118
167
  }
119
168
  function nearestExistingDirectory(candidate) {
120
- let current = (0, import_node_path.resolve)(candidate);
169
+ let current = (0, import_node_path2.resolve)(candidate);
121
170
  for (; ; ) {
122
- if ((0, import_node_fs.existsSync)(current)) {
171
+ if ((0, import_node_fs2.existsSync)(current)) {
123
172
  try {
124
- return (0, import_node_fs.statSync)(current).isDirectory() ? current : (0, import_node_path.dirname)(current);
173
+ return (0, import_node_fs2.statSync)(current).isDirectory() ? current : (0, import_node_path2.dirname)(current);
125
174
  } catch {
126
175
  }
127
176
  }
128
- const parent = (0, import_node_path.dirname)(current);
177
+ const parent = (0, import_node_path2.dirname)(current);
129
178
  if (parent === current) return current;
130
179
  current = parent;
131
180
  }
132
181
  }
133
182
  function findWorkspaceFile(start, explicit) {
134
- if (explicit) return (0, import_node_path.resolve)(start, explicit);
135
- let current = (0, import_node_path.resolve)(start);
183
+ if (explicit) return (0, import_node_path2.resolve)(start, explicit);
184
+ let current = (0, import_node_path2.resolve)(start);
136
185
  for (; ; ) {
137
- const candidate = (0, import_node_path.join)(current, ".mindgraph", "workspace.json");
138
- if ((0, import_node_fs.existsSync)(candidate)) return candidate;
139
- const parent = (0, import_node_path.dirname)(current);
186
+ const candidate = (0, import_node_path2.join)(current, ".mindgraph", "workspace.json");
187
+ if ((0, import_node_fs2.existsSync)(candidate)) return candidate;
188
+ const parent = (0, import_node_path2.dirname)(current);
140
189
  if (parent === current) return void 0;
141
190
  current = parent;
142
191
  }
@@ -223,7 +272,7 @@ var CodegraphAdapter = class {
223
272
  async resolveRepository(repo, fallbackSpaceUid) {
224
273
  const configured = await this.resolveRepositories(fallbackSpaceUid);
225
274
  const selected = repo && configured.find((candidate) => candidate.repoId === repo) || repo && configured.find(
226
- (candidate) => candidate.repoRoot === repo || (0, import_node_path.basename)(candidate.repoRoot) === repo
275
+ (candidate) => candidate.repoRoot === repo || (0, import_node_path2.basename)(candidate.repoRoot) === repo
227
276
  ) || (!repo ? [...configured].sort((a, b) => b.repoRoot.length - a.repoRoot.length).find((candidate) => pathContains(candidate.repoRoot, this.cwd)) : void 0) || (!repo && configured.length === 1 ? configured[0] : void 0);
228
277
  if (selected) {
229
278
  return !repo && this.env.MINDGRAPH_REPO_ID ? this.resolveRepositoryIdentity(
@@ -233,8 +282,8 @@ var CodegraphAdapter = class {
233
282
  ) : selected;
234
283
  }
235
284
  const requestedRoot = repo || this.env.MINDGRAPH_REPO_ROOT || this.cwd;
236
- const requestedPath = await (0, import_promises.realpath)((0, import_node_path.resolve)(this.cwd, requestedRoot)).catch(
237
- () => (0, import_node_path.resolve)(this.cwd, requestedRoot)
285
+ const requestedPath = await (0, import_promises.realpath)((0, import_node_path2.resolve)(this.cwd, requestedRoot)).catch(
286
+ () => (0, import_node_path2.resolve)(this.cwd, requestedRoot)
238
287
  );
239
288
  const repoRoot = await this.gitRoot(requestedPath) ?? requestedPath;
240
289
  return this.resolveRepositoryIdentity(
@@ -255,7 +304,7 @@ var CodegraphAdapter = class {
255
304
  );
256
305
  }
257
306
  async resolveRepositoryIdentity(root, explicitRepoId, spaceUid) {
258
- const repoRoot = await (0, import_promises.realpath)(root).catch(() => (0, import_node_path.resolve)(root));
307
+ const repoRoot = await (0, import_promises.realpath)(root).catch(() => (0, import_node_path2.resolve)(root));
259
308
  const cacheKey = `${repoRoot}\0${explicitRepoId ?? ""}\0${spaceUid ?? ""}`;
260
309
  const cached = this.identityCache.get(cacheKey);
261
310
  if (cached) return cached;
@@ -285,20 +334,20 @@ var CodegraphAdapter = class {
285
334
  this.env
286
335
  ).catch(() => "");
287
336
  if (!rawCommonDir.trim()) {
288
- return `local:${(0, import_node_path.basename)(repoRoot)}`;
337
+ return `local:${(0, import_node_path2.basename)(repoRoot)}`;
289
338
  }
290
- const commonDir = (0, import_node_path.resolve)(repoRoot, rawCommonDir.trim());
291
- const identityDir = (0, import_node_path.join)(commonDir, "mindgraph");
292
- const identityFile = (0, import_node_path.join)(identityDir, "repository-id");
339
+ const commonDir = (0, import_node_path2.resolve)(repoRoot, rawCommonDir.trim());
340
+ const identityDir = (0, import_node_path2.join)(commonDir, "mindgraph");
341
+ const identityFile = (0, import_node_path2.join)(identityDir, "repository-id");
293
342
  try {
294
- const existing = (0, import_node_fs.readFileSync)(identityFile, "utf8").trim();
343
+ const existing = (0, import_node_fs2.readFileSync)(identityFile, "utf8").trim();
295
344
  if (existing) return existing;
296
345
  } catch {
297
346
  }
298
- (0, import_node_fs.mkdirSync)(identityDir, { recursive: true, mode: 448 });
299
- const generated = (0, import_node_crypto.randomUUID)();
347
+ (0, import_node_fs2.mkdirSync)(identityDir, { recursive: true, mode: 448 });
348
+ const generated = (0, import_node_crypto2.randomUUID)();
300
349
  try {
301
- (0, import_node_fs.writeFileSync)(identityFile, `${generated}
350
+ (0, import_node_fs2.writeFileSync)(identityFile, `${generated}
302
351
  `, {
303
352
  encoding: "utf8",
304
353
  flag: "wx",
@@ -307,7 +356,7 @@ var CodegraphAdapter = class {
307
356
  return generated;
308
357
  } catch (cause) {
309
358
  if (cause.code !== "EEXIST") throw cause;
310
- const winner = (0, import_node_fs.readFileSync)(identityFile, "utf8").trim();
359
+ const winner = (0, import_node_fs2.readFileSync)(identityFile, "utf8").trim();
311
360
  if (!winner) throw new Error(`empty repository identity file: ${identityFile}`);
312
361
  return winner;
313
362
  }
@@ -320,7 +369,7 @@ var CodegraphAdapter = class {
320
369
  Math.min(this.timeoutMs, 2e3),
321
370
  this.env
322
371
  ).catch(() => "");
323
- return raw.trim() ? (0, import_node_path.resolve)(start, raw.trim()) : void 0;
372
+ return raw.trim() ? (0, import_node_path2.resolve)(start, raw.trim()) : void 0;
324
373
  }
325
374
  async availability(repository) {
326
375
  const cached = this.statusCache.get(repository.repoRoot);
@@ -437,7 +486,7 @@ var CodegraphAdapter = class {
437
486
  return this.resolveRepository(ref.repo || defaultRepo, fallbackSpaceUid);
438
487
  }
439
488
  if (ref.path) {
440
- const requested = (0, import_node_path.isAbsolute)(ref.path) ? (0, import_node_path.resolve)(ref.path) : (0, import_node_path.resolve)(this.cwd, ref.path);
489
+ const requested = (0, import_node_path2.isAbsolute)(ref.path) ? (0, import_node_path2.resolve)(ref.path) : (0, import_node_path2.resolve)(this.cwd, ref.path);
441
490
  const absolute = await (0, import_promises.realpath)(requested).catch(() => requested);
442
491
  const configured = await this.resolveRepositories(fallbackSpaceUid);
443
492
  const defining = [...configured].sort((a, b) => b.repoRoot.length - a.repoRoot.length).find((candidate) => pathContains(candidate.repoRoot, absolute));
@@ -514,19 +563,19 @@ var CodegraphAdapter = class {
514
563
  }
515
564
  configuredRepositories() {
516
565
  const configured = [];
517
- if (this.workspaceFile && (0, import_node_fs.existsSync)(this.workspaceFile)) {
566
+ if (this.workspaceFile && (0, import_node_fs2.existsSync)(this.workspaceFile)) {
518
567
  try {
519
568
  const parsed = JSON.parse(
520
- (0, import_node_fs.readFileSync)(this.workspaceFile, "utf8")
569
+ (0, import_node_fs2.readFileSync)(this.workspaceFile, "utf8")
521
570
  );
522
571
  if (parsed.v === 1 && Array.isArray(parsed.repositories)) {
523
- const configDirectory = (0, import_node_path.dirname)(this.workspaceFile);
524
- const base = (0, import_node_path.basename)(configDirectory) === ".mindgraph" ? (0, import_node_path.dirname)(configDirectory) : configDirectory;
572
+ const configDirectory = (0, import_node_path2.dirname)(this.workspaceFile);
573
+ const base = (0, import_node_path2.basename)(configDirectory) === ".mindgraph" ? (0, import_node_path2.dirname)(configDirectory) : configDirectory;
525
574
  for (const repository of parsed.repositories) {
526
575
  if (!repository || typeof repository.root !== "string") continue;
527
576
  configured.push({
528
577
  repoId: typeof repository.repo_id === "string" ? repository.repo_id : void 0,
529
- repoRoot: (0, import_node_path.resolve)(base, repository.root),
578
+ repoRoot: (0, import_node_path2.resolve)(base, repository.root),
530
579
  spaceUid: typeof repository.space_uid === "string" ? repository.space_uid : void 0
531
580
  });
532
581
  }
@@ -541,7 +590,7 @@ var CodegraphAdapter = class {
541
590
  for (const [repoId, config] of Object.entries(parsed)) {
542
591
  configured.push({
543
592
  repoId,
544
- repoRoot: (0, import_node_path.resolve)(
593
+ repoRoot: (0, import_node_path2.resolve)(
545
594
  this.cwd,
546
595
  typeof config === "string" ? config : config.root
547
596
  ),
@@ -569,9 +618,9 @@ var CodegraphAdapter = class {
569
618
  const hits = await this.runJson(args);
570
619
  let candidates = hits.map(asNode).map(toCandidate).filter((item) => item !== null);
571
620
  if (ref.path) {
572
- const absolutePath = (0, import_node_path.isAbsolute)(ref.path) ? await (0, import_promises.realpath)(ref.path).catch(() => ref.path) : void 0;
621
+ const absolutePath = (0, import_node_path2.isAbsolute)(ref.path) ? await (0, import_promises.realpath)(ref.path).catch(() => ref.path) : void 0;
573
622
  const wanted = normalizePath(
574
- absolutePath ? (0, import_node_path.relative)(repository.repoRoot, absolutePath) : ref.path
623
+ absolutePath ? (0, import_node_path2.relative)(repository.repoRoot, absolutePath) : ref.path
575
624
  );
576
625
  candidates = candidates.filter((candidate) => candidate.path === wanted);
577
626
  }
@@ -672,7 +721,7 @@ var CodegraphAdapter = class {
672
721
  const candidates = [
673
722
  this.env.MINDGRAPH_CODEGRAPH_BIN,
674
723
  "codegraph",
675
- (0, import_node_path.resolve)((0, import_node_os.homedir)(), ".local", "bin", "codegraph")
724
+ (0, import_node_path2.resolve)((0, import_node_os2.homedir)(), ".local", "bin", "codegraph")
676
725
  ].filter((candidate, index, all) => {
677
726
  return Boolean(candidate) && all.indexOf(candidate) === index;
678
727
  });
@@ -1219,9 +1268,9 @@ function primaryUids(value) {
1219
1268
  }
1220
1269
 
1221
1270
  // src/sync-tool.ts
1222
- var import_node_crypto2 = __toESM(require("crypto"));
1223
- var import_node_fs2 = __toESM(require("fs"));
1224
- var import_node_path2 = __toESM(require("path"));
1271
+ var import_node_crypto3 = __toESM(require("crypto"));
1272
+ var import_node_fs3 = __toESM(require("fs"));
1273
+ var import_node_path3 = __toESM(require("path"));
1225
1274
  var ok2 = (data) => ({
1226
1275
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
1227
1276
  });
@@ -1298,25 +1347,25 @@ var SYNC_TOOL = {
1298
1347
  }
1299
1348
  };
1300
1349
  function safePath(root, candidate) {
1301
- const absolute = import_node_path2.default.resolve(root, candidate);
1302
- const relative2 = import_node_path2.default.relative(root, absolute);
1303
- if (relative2.startsWith("..") || import_node_path2.default.isAbsolute(relative2)) {
1350
+ const absolute = import_node_path3.default.resolve(root, candidate);
1351
+ const relative2 = import_node_path3.default.relative(root, absolute);
1352
+ if (relative2.startsWith("..") || import_node_path3.default.isAbsolute(relative2)) {
1304
1353
  throw new Error(`path escapes repository root: ${candidate}`);
1305
1354
  }
1306
1355
  return absolute;
1307
1356
  }
1308
1357
  function markdownFiles(target) {
1309
- if (!import_node_fs2.default.existsSync(target)) return [];
1310
- const stat = import_node_fs2.default.statSync(target);
1358
+ if (!import_node_fs3.default.existsSync(target)) return [];
1359
+ const stat = import_node_fs3.default.statSync(target);
1311
1360
  if (stat.isFile()) return target.endsWith(".md") ? [target] : [];
1312
1361
  if (!stat.isDirectory()) return [];
1313
- return import_node_fs2.default.readdirSync(target, { withFileTypes: true }).flatMap((entry) => markdownFiles(import_node_path2.default.join(target, entry.name)));
1362
+ return import_node_fs3.default.readdirSync(target, { withFileTypes: true }).flatMap((entry) => markdownFiles(import_node_path3.default.join(target, entry.name)));
1314
1363
  }
1315
1364
  function fileDescriptor(root, absolute) {
1316
- const content = import_node_fs2.default.readFileSync(absolute, "utf8");
1365
+ const content = import_node_fs3.default.readFileSync(absolute, "utf8");
1317
1366
  return {
1318
- logical_path: import_node_path2.default.relative(root, absolute).split(import_node_path2.default.sep).join("/"),
1319
- content_hash: import_node_crypto2.default.createHash("sha256").update(content).digest("hex"),
1367
+ logical_path: import_node_path3.default.relative(root, absolute).split(import_node_path3.default.sep).join("/"),
1368
+ content_hash: import_node_crypto3.default.createHash("sha256").update(content).digest("hex"),
1320
1369
  bytes: Buffer.byteLength(content),
1321
1370
  content
1322
1371
  };
@@ -1381,7 +1430,7 @@ async function handleSyncTool(client2, args) {
1381
1430
  }
1382
1431
  if (action === "status" && request.logical_path && request.file_present !== false) {
1383
1432
  const absolute = safePath(root, String(request.logical_path));
1384
- request.file_present = import_node_fs2.default.existsSync(absolute);
1433
+ request.file_present = import_node_fs3.default.existsSync(absolute);
1385
1434
  if (request.file_present && !request.content_hash) {
1386
1435
  request.content_hash = fileDescriptor(root, absolute).content_hash;
1387
1436
  }
@@ -1889,7 +1938,7 @@ var TOOLS = [
1889
1938
  scope_uids: {
1890
1939
  type: "array",
1891
1940
  items: { type: "string" },
1892
- description: "Ordinary target UIDs that bound deterministic resume selection"
1941
+ description: "Required target UIDs for create_task and ordinary target UIDs that bound deterministic resume selection"
1893
1942
  },
1894
1943
  limit: {
1895
1944
  type: "number",
@@ -2441,6 +2490,18 @@ async function handleTool(client2, name, args) {
2441
2490
  ].includes(action);
2442
2491
  return attach ? await attachCodeRefsToToolResult(client2, result, args) : result;
2443
2492
  } catch (e) {
2493
+ const lifted = conflictState(e);
2494
+ if (Object.keys(lifted).length > 0) {
2495
+ return {
2496
+ content: [
2497
+ {
2498
+ type: "text",
2499
+ text: JSON.stringify({ error: errorDetail(e), ...lifted })
2500
+ }
2501
+ ],
2502
+ isError: true
2503
+ };
2504
+ }
2444
2505
  return err3(errorDetail(e));
2445
2506
  }
2446
2507
  }
@@ -2687,6 +2748,38 @@ async function handleCommit(client2, args) {
2687
2748
  return err3(`Unknown commit action: ${action}`);
2688
2749
  }
2689
2750
  }
2751
+ async function repositoryScopeUidsForTask(client2, options) {
2752
+ const scopeUids = [...new Set(options.scopeUids ?? [])];
2753
+ const cwd = options.invocationContext?.cwd;
2754
+ const repoId = options.invocationContext?.repoId;
2755
+ if (!options.repo && !cwd && !repoId) {
2756
+ return options.scopeUids;
2757
+ }
2758
+ const agentId = options.agentId ?? process.env.MINDGRAPH_AGENT_ID ?? "mcp";
2759
+ const fallbackSpaceUid = options.repoSpaceUid ?? `space:agent:${agentId}`;
2760
+ const env = { ...process.env };
2761
+ if (!options.repo && repoId) {
2762
+ env.MINDGRAPH_REPO_ID = repoId;
2763
+ }
2764
+ const adapter = new CodegraphAdapter({
2765
+ cwd: cwd ?? process.cwd(),
2766
+ env
2767
+ });
2768
+ const repository = await adapter.resolveRepository(options.repo, fallbackSpaceUid);
2769
+ const anchored = await anchorRepository(
2770
+ client2,
2771
+ repository,
2772
+ repository.spaceUid ?? fallbackSpaceUid,
2773
+ agentId
2774
+ );
2775
+ if (!anchored.uid) {
2776
+ throw new Error(
2777
+ `repository scope ${repository.repoId} could not be materialized (${anchored.status ?? "missing uid"})`
2778
+ );
2779
+ }
2780
+ scopeUids.push(anchored.uid);
2781
+ return [...new Set(scopeUids)];
2782
+ }
2690
2783
  async function handlePlan(client2, args) {
2691
2784
  const {
2692
2785
  action,
@@ -2717,6 +2810,9 @@ async function handlePlan(client2, args) {
2717
2810
  release_lease,
2718
2811
  override_reason,
2719
2812
  scope_uids,
2813
+ repo,
2814
+ repo_space_uid,
2815
+ invocation_context,
2720
2816
  limit,
2721
2817
  confidence,
2722
2818
  salience,
@@ -2746,7 +2842,14 @@ async function handlePlan(client2, args) {
2746
2842
  case "checkpoint_iteration":
2747
2843
  case "block_task":
2748
2844
  case "complete_task":
2749
- case "abandon_iteration":
2845
+ case "abandon_iteration": {
2846
+ const resolvedScopeUids = action === "create_task" ? await repositoryScopeUidsForTask(client2, {
2847
+ scopeUids: scope_uids,
2848
+ repo,
2849
+ repoSpaceUid: repo_space_uid,
2850
+ invocationContext: invocation_context,
2851
+ agentId: agent_id
2852
+ }) : scope_uids;
2750
2853
  return ok3(
2751
2854
  await client2.plan({
2752
2855
  action,
@@ -2774,7 +2877,7 @@ async function handlePlan(client2, args) {
2774
2877
  allow_takeover,
2775
2878
  release_lease,
2776
2879
  override_reason,
2777
- scope_uids,
2880
+ scope_uids: resolvedScopeUids,
2778
2881
  limit,
2779
2882
  input_snapshot,
2780
2883
  output_snapshot,
@@ -2789,6 +2892,7 @@ async function handlePlan(client2, args) {
2789
2892
  agent_id
2790
2893
  })
2791
2894
  );
2895
+ }
2792
2896
  // Execution tracking
2793
2897
  case "start_execution":
2794
2898
  return ok3(
@@ -3833,7 +3937,7 @@ async function readGovernedResource(client2, uri, governanceConfig) {
3833
3937
  // src/index.ts
3834
3938
  var API_KEY = process.env.MINDGRAPH_API_KEY;
3835
3939
  var BASE_URL = process.env.MINDGRAPH_BASE_URL || "https://api.mindgraph.cloud";
3836
- var AGENT_ID = process.env.MINDGRAPH_AGENT_ID || "mcp";
3940
+ var AGENT_ID = process.env.MINDGRAPH_AGENT_ID || loadHookEnv().agentId || stableAgentId();
3837
3941
  var ORG_ID = process.env.MINDGRAPH_ORG_ID;
3838
3942
  var PROFILE = process.env.MINDGRAPH_PROFILE || "general";
3839
3943
  var HARNESS = process.env.MINDGRAPH_HARNESS || "generic";
@@ -3955,7 +4059,7 @@ if (PROFILE === "coding") {
3955
4059
  var server = new import_server.Server(
3956
4060
  {
3957
4061
  name: "mindgraph",
3958
- version: "0.14.8"
4062
+ version: "0.15.0"
3959
4063
  },
3960
4064
  {
3961
4065
  capabilities: {
@@ -4169,7 +4273,7 @@ async function main() {
4169
4273
  const transport = new import_stdio.StdioServerTransport();
4170
4274
  await server.connect(transport);
4171
4275
  console.error(
4172
- `MindGraph MCP server v0.7.1 running on stdio (${BASE_URL})`
4276
+ `MindGraph MCP server v${"0.15.0"} running on stdio (${BASE_URL})`
4173
4277
  );
4174
4278
  }
4175
4279
  main().catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph-mcp",
3
- "version": "0.14.8",
3
+ "version": "0.15.0",
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",