mindgraph-mcp 0.14.0 → 0.14.2

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.
Files changed (3) hide show
  1. package/dist/cli.js +101 -38
  2. package/dist/index.js +25 -19
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -710,6 +710,22 @@ var init_codegraph = __esm({
710
710
  }
711
711
  });
712
712
 
713
+ // src/error-detail.ts
714
+ function errorDetail(e) {
715
+ if (e instanceof import_mindgraph.MindGraphError && e.body !== void 0) {
716
+ const detail = typeof e.body === "string" ? e.body : JSON.stringify(e.body);
717
+ return `${e.message} \u2014 ${detail}`;
718
+ }
719
+ return e instanceof Error ? e.message : String(e);
720
+ }
721
+ var import_mindgraph;
722
+ var init_error_detail = __esm({
723
+ "src/error-detail.ts"() {
724
+ "use strict";
725
+ import_mindgraph = require("mindgraph");
726
+ }
727
+ });
728
+
713
729
  // src/code-tool.ts
714
730
  async function handleCodeTool(client2, args, adapter = new CodegraphAdapter()) {
715
731
  const codeClient = client2;
@@ -893,10 +909,7 @@ async function handleCodeTool(client2, args, adapter = new CodegraphAdapter()) {
893
909
  return err("unknown_action", `unknown mindgraph_code action: ${action}`);
894
910
  }
895
911
  } catch (cause) {
896
- return err(
897
- "code_tool_failed",
898
- cause instanceof Error ? cause.message : String(cause)
899
- );
912
+ return err("code_tool_failed", errorDetail(cause));
900
913
  }
901
914
  }
902
915
  async function attachCodeRefsToToolResult(client2, result, args, adapter) {
@@ -1136,6 +1149,7 @@ var ok, err, CODE_TOOL;
1136
1149
  var init_code_tool = __esm({
1137
1150
  "src/code-tool.ts"() {
1138
1151
  "use strict";
1152
+ init_error_detail();
1139
1153
  init_codegraph();
1140
1154
  ok = (data) => ({
1141
1155
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
@@ -1304,10 +1318,7 @@ async function handleSyncTool(client2, args) {
1304
1318
  }
1305
1319
  return ok2(await remote.memorySync(request));
1306
1320
  } catch (error) {
1307
- return err2(
1308
- "sync_failed",
1309
- error instanceof Error ? error.message : String(error)
1310
- );
1321
+ return err2("sync_failed", errorDetail(error));
1311
1322
  }
1312
1323
  }
1313
1324
  async function scanRepository(remote, repository, requested, provider, agentId) {
@@ -1351,6 +1362,7 @@ var init_sync_tool = __esm({
1351
1362
  import_node_fs5 = __toESM(require("fs"));
1352
1363
  import_node_path5 = __toESM(require("path"));
1353
1364
  init_codegraph();
1365
+ init_error_detail();
1354
1366
  ok2 = (data) => ({
1355
1367
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
1356
1368
  });
@@ -1495,12 +1507,7 @@ async function handleTool(client2, name, args) {
1495
1507
  ].includes(action);
1496
1508
  return attach ? await attachCodeRefsToToolResult(client2, result, args) : result;
1497
1509
  } catch (e) {
1498
- if (e instanceof import_mindgraph.MindGraphError && e.body !== void 0) {
1499
- const detail = typeof e.body === "string" ? e.body : JSON.stringify(e.body);
1500
- return err3(`${e.message} \u2014 ${detail}`);
1501
- }
1502
- const message = e instanceof Error ? e.message : String(e);
1503
- return err3(message);
1510
+ return err3(errorDetail(e));
1504
1511
  }
1505
1512
  }
1506
1513
  async function handleCapture(client2, args) {
@@ -1638,13 +1645,23 @@ async function handleReason(client2, args) {
1638
1645
  agent_id
1639
1646
  } = args;
1640
1647
  if (action === "claim") {
1641
- const claimObj = claim || (label ? { label, confidence } : null);
1648
+ const claimObj = claim ? {
1649
+ label: claim.label,
1650
+ confidence: claim.confidence,
1651
+ ...claim.content ? { props: { content: claim.content } } : {}
1652
+ } : label ? { label, confidence } : null;
1642
1653
  if (!claimObj) return err3("claim object or label is required for action=claim");
1643
1654
  return ok3(
1644
1655
  await client2.argue({
1645
1656
  claim: claimObj,
1646
- evidence,
1647
- warrant,
1657
+ evidence: evidence?.map((e) => ({
1658
+ label: e.label,
1659
+ ...e.description ? { props: { description: e.description } } : {}
1660
+ })),
1661
+ warrant: warrant ? {
1662
+ label: warrant.label,
1663
+ ...warrant.content ? { props: { content: warrant.content } } : {}
1664
+ } : void 0,
1648
1665
  argument,
1649
1666
  agent_id
1650
1667
  })
@@ -2384,11 +2401,11 @@ async function handleOntology(client2, args) {
2384
2401
  return err3(`Unknown ontology action: ${action}`);
2385
2402
  }
2386
2403
  }
2387
- var import_mindgraph, TOOLS, INVOCATION_CONTEXT_SCHEMA;
2404
+ var TOOLS, INVOCATION_CONTEXT_SCHEMA;
2388
2405
  var init_tools = __esm({
2389
2406
  "src/tools.ts"() {
2390
2407
  "use strict";
2391
- import_mindgraph = require("mindgraph");
2408
+ init_error_detail();
2392
2409
  init_code_tool();
2393
2410
  init_sync_tool();
2394
2411
  TOOLS = [
@@ -3988,7 +4005,7 @@ Capture knowledge when the user shares something worth remembering:
3988
4005
  server = new import_server.Server(
3989
4006
  {
3990
4007
  name: "mindgraph",
3991
- version: "0.14.0"
4008
+ version: "0.14.2"
3992
4009
  },
3993
4010
  {
3994
4011
  capabilities: {
@@ -4300,6 +4317,17 @@ function parseArgs(argv) {
4300
4317
  }
4301
4318
  return { command, apiKey, baseUrl, scope, projectDir, harness, hooks };
4302
4319
  }
4320
+ function mcpAddFailureOutput(e) {
4321
+ const err5 = e;
4322
+ return `${err5.stdout ?? ""}${err5.stderr ?? ""}`.trim();
4323
+ }
4324
+ function classifyMcpAddFailure(e) {
4325
+ if (e?.code === "ENOENT") return "missing-cli";
4326
+ if (mcpAddFailureOutput(e).toLowerCase().includes("already exists")) {
4327
+ return "already-exists";
4328
+ }
4329
+ return "other";
4330
+ }
4303
4331
 
4304
4332
  // src/claude-hooks.ts
4305
4333
  var import_node_crypto2 = __toESM(require("crypto"));
@@ -4738,7 +4766,20 @@ var import_node_os4 = __toESM(require("os"));
4738
4766
  var import_node_path4 = __toESM(require("path"));
4739
4767
  var import_node_crypto3 = __toESM(require("crypto"));
4740
4768
  var OWNER_MARKER = "--owner mindgraph";
4741
- var COMMAND = "npx -y mindgraph-mcp@latest hook --harness claude-code --owner mindgraph";
4769
+ var RUNNER_RELATIVE = ".mindgraph/bin/mindgraph-hook.cjs";
4770
+ var COMMAND = `node "$HOME/${RUNNER_RELATIVE}" hook --harness claude-code --owner mindgraph`;
4771
+ function installHookRunner(sourceFile, homeDir) {
4772
+ const target = import_node_path4.default.join(homeDir || import_node_os4.default.homedir(), RUNNER_RELATIVE);
4773
+ import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(target), { recursive: true });
4774
+ import_node_fs4.default.copyFileSync(sourceFile, target);
4775
+ return target;
4776
+ }
4777
+ function uninstallHookRunner(homeDir) {
4778
+ try {
4779
+ import_node_fs4.default.rmSync(import_node_path4.default.join(homeDir || import_node_os4.default.homedir(), RUNNER_RELATIVE));
4780
+ } catch {
4781
+ }
4782
+ }
4742
4783
  function settingsPath(scope, projectDir = process.cwd()) {
4743
4784
  return scope === "user" ? import_node_path4.default.join(import_node_os4.default.homedir(), ".claude", "settings.json") : import_node_path4.default.join(projectDir, ".claude", "settings.json");
4744
4785
  }
@@ -4759,7 +4800,7 @@ function desiredEntries() {
4759
4800
  SessionStart: [
4760
4801
  {
4761
4802
  matcher: "startup|resume|clear|compact|fork",
4762
- hooks: [ownedHook(8)]
4803
+ hooks: [ownedHook(20)]
4763
4804
  }
4764
4805
  ],
4765
4806
  PreToolUse: [
@@ -4799,19 +4840,21 @@ function installClaudeHooks(scope, projectDir = process.cwd()) {
4799
4840
  const settings = readSettings(file);
4800
4841
  const hooks = settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? settings.hooks : {};
4801
4842
  let added = 0;
4843
+ let updated = 0;
4802
4844
  for (const [event, wanted] of Object.entries(desiredEntries())) {
4803
4845
  const current = Array.isArray(hooks[event]) ? [...hooks[event]] : [];
4846
+ const kept = current.filter((entry) => !entryHasOwnedHook(entry));
4847
+ const hadOwned = kept.length !== current.length;
4804
4848
  for (const entry of wanted) {
4805
- if (!current.some(entryHasOwnedHook)) {
4806
- current.push(entry);
4807
- added += 1;
4808
- }
4849
+ kept.push(entry);
4850
+ if (hadOwned) updated += 1;
4851
+ else added += 1;
4809
4852
  }
4810
- hooks[event] = current;
4853
+ hooks[event] = kept;
4811
4854
  }
4812
4855
  settings.hooks = hooks;
4813
4856
  writeSettings(file, settings);
4814
- return { path: file, added };
4857
+ return { path: file, added, updated };
4815
4858
  }
4816
4859
  function uninstallClaudeHooks(scope, projectDir = process.cwd()) {
4817
4860
  const file = settingsPath(scope, projectDir);
@@ -4932,7 +4975,7 @@ function installClaudeCode(apiKey, baseUrl) {
4932
4975
  envArgs.push("--env", `MINDGRAPH_BASE_URL=${baseUrl}`);
4933
4976
  }
4934
4977
  try {
4935
- (0, import_child_process.execFileSync)(
4978
+ const out = (0, import_child_process.execFileSync)(
4936
4979
  "claude",
4937
4980
  [
4938
4981
  "mcp",
@@ -4944,15 +4987,30 @@ function installClaudeCode(apiKey, baseUrl) {
4944
4987
  "-y",
4945
4988
  "mindgraph-mcp@latest"
4946
4989
  ],
4947
- { stdio: "inherit" }
4990
+ { stdio: ["inherit", "pipe", "pipe"] }
4948
4991
  );
4992
+ if (out?.length) process.stdout.write(out);
4949
4993
  console.log("Added MindGraph MCP server to Claude Code.");
4950
- } catch {
4951
- console.error(
4952
- "Failed to run 'claude mcp add'. Is Claude Code CLI installed?"
4953
- );
4954
- console.error("Install it from: https://claude.ai/code");
4955
- process.exit(1);
4994
+ } catch (e) {
4995
+ switch (classifyMcpAddFailure(e)) {
4996
+ case "already-exists":
4997
+ console.log(
4998
+ "MindGraph MCP server already registered in Claude Code \u2014 leaving it in place."
4999
+ );
5000
+ break;
5001
+ case "missing-cli":
5002
+ console.error(
5003
+ "Failed to run 'claude mcp add'. Is Claude Code CLI installed?"
5004
+ );
5005
+ console.error("Install it from: https://claude.ai/code");
5006
+ process.exit(1);
5007
+ break;
5008
+ default: {
5009
+ const detail = mcpAddFailureOutput(e);
5010
+ console.error(detail || "'claude mcp add' failed.");
5011
+ process.exit(1);
5012
+ }
5013
+ }
4956
5014
  }
4957
5015
  }
4958
5016
  function uninstallClaudeDesktop() {
@@ -5007,9 +5065,11 @@ function withHooksFlag() {
5007
5065
  }
5008
5066
  function finishCodeInstall(apiKey, baseUrl, withHooks) {
5009
5067
  if (withHooks) {
5068
+ const runner = installHookRunner(__filename);
5069
+ console.log(`Installed pinned hook runner at ${runner}`);
5010
5070
  const result = installClaudeHooks("user");
5011
5071
  console.log(
5012
- `Installed ${result.added} MindGraph Claude Code hook entries in ${result.path}`
5072
+ `Installed ${result.added} and refreshed ${result.updated} MindGraph Claude Code hook entries in ${result.path}`
5013
5073
  );
5014
5074
  const envPath = saveHookEnv({ apiKey, baseUrl });
5015
5075
  console.log(`Saved hook connection settings to ${envPath} (mode 600)`);
@@ -5215,9 +5275,11 @@ async function main2() {
5215
5275
  if ((harness || "claude-code") !== "claude-code") {
5216
5276
  throw new Error("only --harness claude-code is available in this release");
5217
5277
  }
5278
+ const runner = installHookRunner(__filename);
5279
+ console.log(`Installed pinned hook runner at ${runner}`);
5218
5280
  const result = installClaudeHooks(scope, projectDir);
5219
5281
  console.log(
5220
- `Installed ${result.added} MindGraph Claude Code hook entries in ${result.path}`
5282
+ `Installed ${result.added} and refreshed ${result.updated} MindGraph Claude Code hook entries in ${result.path}`
5221
5283
  );
5222
5284
  if (apiKey || baseUrl) {
5223
5285
  const envPath = saveHookEnv({ apiKey, baseUrl });
@@ -5233,6 +5295,7 @@ async function main2() {
5233
5295
  if ((harness || "claude-code") !== "claude-code") {
5234
5296
  throw new Error("only --harness claude-code is available in this release");
5235
5297
  }
5298
+ uninstallHookRunner();
5236
5299
  const result = uninstallClaudeHooks(scope, projectDir);
5237
5300
  console.log(
5238
5301
  `Removed ${result.removed} MindGraph Claude Code hooks from ${result.path}`
package/dist/index.js CHANGED
@@ -28,8 +28,15 @@ 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/tools.ts
31
+ // src/error-detail.ts
32
32
  var import_mindgraph = require("mindgraph");
33
+ function errorDetail(e) {
34
+ if (e instanceof import_mindgraph.MindGraphError && e.body !== void 0) {
35
+ const detail = typeof e.body === "string" ? e.body : JSON.stringify(e.body);
36
+ return `${e.message} \u2014 ${detail}`;
37
+ }
38
+ return e instanceof Error ? e.message : String(e);
39
+ }
33
40
 
34
41
  // src/codegraph.ts
35
42
  var import_node_child_process = require("child_process");
@@ -964,10 +971,7 @@ async function handleCodeTool(client2, args, adapter = new CodegraphAdapter()) {
964
971
  return err("unknown_action", `unknown mindgraph_code action: ${action}`);
965
972
  }
966
973
  } catch (cause) {
967
- return err(
968
- "code_tool_failed",
969
- cause instanceof Error ? cause.message : String(cause)
970
- );
974
+ return err("code_tool_failed", errorDetail(cause));
971
975
  }
972
976
  }
973
977
  async function attachCodeRefsToToolResult(client2, result, args, adapter) {
@@ -1374,10 +1378,7 @@ async function handleSyncTool(client2, args) {
1374
1378
  }
1375
1379
  return ok2(await remote.memorySync(request));
1376
1380
  } catch (error) {
1377
- return err2(
1378
- "sync_failed",
1379
- error instanceof Error ? error.message : String(error)
1380
- );
1381
+ return err2("sync_failed", errorDetail(error));
1381
1382
  }
1382
1383
  }
1383
1384
  async function scanRepository(remote, repository, requested, provider, agentId) {
@@ -2426,12 +2427,7 @@ async function handleTool(client2, name, args) {
2426
2427
  ].includes(action);
2427
2428
  return attach ? await attachCodeRefsToToolResult(client2, result, args) : result;
2428
2429
  } catch (e) {
2429
- if (e instanceof import_mindgraph.MindGraphError && e.body !== void 0) {
2430
- const detail = typeof e.body === "string" ? e.body : JSON.stringify(e.body);
2431
- return err3(`${e.message} \u2014 ${detail}`);
2432
- }
2433
- const message = e instanceof Error ? e.message : String(e);
2434
- return err3(message);
2430
+ return err3(errorDetail(e));
2435
2431
  }
2436
2432
  }
2437
2433
  async function handleCapture(client2, args) {
@@ -2569,13 +2565,23 @@ async function handleReason(client2, args) {
2569
2565
  agent_id
2570
2566
  } = args;
2571
2567
  if (action === "claim") {
2572
- const claimObj = claim || (label ? { label, confidence } : null);
2568
+ const claimObj = claim ? {
2569
+ label: claim.label,
2570
+ confidence: claim.confidence,
2571
+ ...claim.content ? { props: { content: claim.content } } : {}
2572
+ } : label ? { label, confidence } : null;
2573
2573
  if (!claimObj) return err3("claim object or label is required for action=claim");
2574
2574
  return ok3(
2575
2575
  await client2.argue({
2576
2576
  claim: claimObj,
2577
- evidence,
2578
- warrant,
2577
+ evidence: evidence?.map((e) => ({
2578
+ label: e.label,
2579
+ ...e.description ? { props: { description: e.description } } : {}
2580
+ })),
2581
+ warrant: warrant ? {
2582
+ label: warrant.label,
2583
+ ...warrant.content ? { props: { content: warrant.content } } : {}
2584
+ } : void 0,
2579
2585
  argument,
2580
2586
  agent_id
2581
2587
  })
@@ -3925,7 +3931,7 @@ if (PROFILE === "coding") {
3925
3931
  var server = new import_server.Server(
3926
3932
  {
3927
3933
  name: "mindgraph",
3928
- version: "0.14.0"
3934
+ version: "0.14.2"
3929
3935
  },
3930
3936
  {
3931
3937
  capabilities: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph-mcp",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
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",