@memlab/mcp-server 2.0.2 → 2.1.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.
Files changed (134) hide show
  1. package/README.md +23 -13
  2. package/bin/memlab-mcp.js +9 -0
  3. package/dist/heap-state.d.ts +12 -1
  4. package/dist/heap-state.d.ts.map +1 -1
  5. package/dist/heap-state.js +10 -4
  6. package/dist/heap-state.js.map +1 -1
  7. package/dist/index.js +29 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/tools/aggregate-nodes.d.ts.map +1 -1
  10. package/dist/tools/aggregate-nodes.js +2 -2
  11. package/dist/tools/aggregate-nodes.js.map +1 -1
  12. package/dist/tools/auto-investigate.d.ts +12 -0
  13. package/dist/tools/auto-investigate.d.ts.map +1 -0
  14. package/dist/tools/auto-investigate.js +683 -0
  15. package/dist/tools/auto-investigate.js.map +1 -0
  16. package/dist/tools/cache-analysis.d.ts +12 -0
  17. package/dist/tools/cache-analysis.d.ts.map +1 -0
  18. package/dist/tools/cache-analysis.js +341 -0
  19. package/dist/tools/cache-analysis.js.map +1 -0
  20. package/dist/tools/check-health.d.ts +12 -0
  21. package/dist/tools/check-health.d.ts.map +1 -0
  22. package/dist/tools/check-health.js +289 -0
  23. package/dist/tools/check-health.js.map +1 -0
  24. package/dist/tools/class-histogram.d.ts.map +1 -1
  25. package/dist/tools/class-histogram.js +70 -14
  26. package/dist/tools/class-histogram.js.map +1 -1
  27. package/dist/tools/closure-inspection.d.ts.map +1 -1
  28. package/dist/tools/closure-inspection.js +5 -5
  29. package/dist/tools/closure-inspection.js.map +1 -1
  30. package/dist/tools/detached-dom.d.ts.map +1 -1
  31. package/dist/tools/detached-dom.js +151 -5
  32. package/dist/tools/detached-dom.js.map +1 -1
  33. package/dist/tools/diff-snapshots.d.ts +12 -0
  34. package/dist/tools/diff-snapshots.d.ts.map +1 -0
  35. package/dist/tools/diff-snapshots.js +224 -0
  36. package/dist/tools/diff-snapshots.js.map +1 -0
  37. package/dist/tools/dominator-subtree.d.ts.map +1 -1
  38. package/dist/tools/dominator-subtree.js +29 -4
  39. package/dist/tools/dominator-subtree.js.map +1 -1
  40. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  41. package/dist/tools/duplicated-strings.js +62 -9
  42. package/dist/tools/duplicated-strings.js.map +1 -1
  43. package/dist/tools/eval.d.ts.map +1 -1
  44. package/dist/tools/eval.js +111 -7
  45. package/dist/tools/eval.js.map +1 -1
  46. package/dist/tools/event-listener-leaks.d.ts +12 -0
  47. package/dist/tools/event-listener-leaks.d.ts.map +1 -0
  48. package/dist/tools/event-listener-leaks.js +266 -0
  49. package/dist/tools/event-listener-leaks.js.map +1 -0
  50. package/dist/tools/find-by-property.d.ts.map +1 -1
  51. package/dist/tools/find-by-property.js +38 -4
  52. package/dist/tools/find-by-property.js.map +1 -1
  53. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  54. package/dist/tools/find-nodes-by-class.js +4 -4
  55. package/dist/tools/find-nodes-by-class.js.map +1 -1
  56. package/dist/tools/for-each.d.ts.map +1 -1
  57. package/dist/tools/for-each.js +2 -2
  58. package/dist/tools/for-each.js.map +1 -1
  59. package/dist/tools/get-node.d.ts.map +1 -1
  60. package/dist/tools/get-node.js +2 -2
  61. package/dist/tools/get-node.js.map +1 -1
  62. package/dist/tools/get-property.d.ts.map +1 -1
  63. package/dist/tools/get-property.js +4 -4
  64. package/dist/tools/get-property.js.map +1 -1
  65. package/dist/tools/get-references.d.ts.map +1 -1
  66. package/dist/tools/get-references.js +11 -5
  67. package/dist/tools/get-references.js.map +1 -1
  68. package/dist/tools/get-referrers.d.ts.map +1 -1
  69. package/dist/tools/get-referrers.js +11 -5
  70. package/dist/tools/get-referrers.js.map +1 -1
  71. package/dist/tools/global-variables.d.ts.map +1 -1
  72. package/dist/tools/global-variables.js +10 -6
  73. package/dist/tools/global-variables.js.map +1 -1
  74. package/dist/tools/largest-objects.d.ts.map +1 -1
  75. package/dist/tools/largest-objects.js +78 -8
  76. package/dist/tools/largest-objects.js.map +1 -1
  77. package/dist/tools/load-snapshot.d.ts.map +1 -1
  78. package/dist/tools/load-snapshot.js +118 -4
  79. package/dist/tools/load-snapshot.js.map +1 -1
  80. package/dist/tools/object-shape.d.ts.map +1 -1
  81. package/dist/tools/object-shape.js +66 -47
  82. package/dist/tools/object-shape.js.map +1 -1
  83. package/dist/tools/pinch-points.d.ts +12 -0
  84. package/dist/tools/pinch-points.d.ts.map +1 -0
  85. package/dist/tools/pinch-points.js +124 -0
  86. package/dist/tools/pinch-points.js.map +1 -0
  87. package/dist/tools/quick-diagnosis.d.ts +12 -0
  88. package/dist/tools/quick-diagnosis.d.ts.map +1 -0
  89. package/dist/tools/quick-diagnosis.js +213 -0
  90. package/dist/tools/quick-diagnosis.js.map +1 -0
  91. package/dist/tools/referrer-summary.d.ts +12 -0
  92. package/dist/tools/referrer-summary.d.ts.map +1 -0
  93. package/dist/tools/referrer-summary.js +119 -0
  94. package/dist/tools/referrer-summary.js.map +1 -0
  95. package/dist/tools/reports.d.ts.map +1 -1
  96. package/dist/tools/reports.js +5 -5
  97. package/dist/tools/reports.js.map +1 -1
  98. package/dist/tools/retainer-summary.d.ts +12 -0
  99. package/dist/tools/retainer-summary.d.ts.map +1 -0
  100. package/dist/tools/retainer-summary.js +307 -0
  101. package/dist/tools/retainer-summary.js.map +1 -0
  102. package/dist/tools/retainer-trace.d.ts.map +1 -1
  103. package/dist/tools/retainer-trace.js +88 -14
  104. package/dist/tools/retainer-trace.js.map +1 -1
  105. package/dist/tools/search-nodes.d.ts.map +1 -1
  106. package/dist/tools/search-nodes.js +2 -2
  107. package/dist/tools/search-nodes.js.map +1 -1
  108. package/dist/tools/shape-histogram.d.ts +12 -0
  109. package/dist/tools/shape-histogram.d.ts.map +1 -0
  110. package/dist/tools/shape-histogram.js +119 -0
  111. package/dist/tools/shape-histogram.js.map +1 -0
  112. package/dist/tools/sliced-strings.d.ts +12 -0
  113. package/dist/tools/sliced-strings.d.ts.map +1 -0
  114. package/dist/tools/sliced-strings.js +126 -0
  115. package/dist/tools/sliced-strings.js.map +1 -0
  116. package/dist/tools/snapshot-summary.d.ts.map +1 -1
  117. package/dist/tools/snapshot-summary.js +42 -3
  118. package/dist/tools/snapshot-summary.js.map +1 -1
  119. package/dist/tools/stale-collections.d.ts.map +1 -1
  120. package/dist/tools/stale-collections.js +30 -6
  121. package/dist/tools/stale-collections.js.map +1 -1
  122. package/dist/tools/string-patterns.d.ts +12 -0
  123. package/dist/tools/string-patterns.d.ts.map +1 -0
  124. package/dist/tools/string-patterns.js +115 -0
  125. package/dist/tools/string-patterns.js.map +1 -0
  126. package/dist/tools/trace-dominators.d.ts +12 -0
  127. package/dist/tools/trace-dominators.d.ts.map +1 -0
  128. package/dist/tools/trace-dominators.js +237 -0
  129. package/dist/tools/trace-dominators.js.map +1 -0
  130. package/dist/utils.d.ts +9 -1
  131. package/dist/utils.d.ts.map +1 -1
  132. package/dist/utils.js +67 -5
  133. package/dist/utils.js.map +1 -1
  134. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"largest-objects.js","sourceRoot":"","sources":["../../src/tools/largest-objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,yGAAyG,EACzG;QACE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,kDAAkD,CAAC;KAChE,EACD,KAAK,EAAE,EAAC,KAAK,EAAC,EAAE,EAAE;QAChB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,oBAAoB,CAChC,QAAQ,EACR,qBAAqB,EACrB,KAAK,CACN,CAAC;YACF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClD,OAAO,UAAU,CACf,OAAO,SAAS,CAAC,MAAM,gCAAgC,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAC3F,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"largest-objects.js","sourceRoot":"","sources":["../../src/tools/largest-objects.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"load-snapshot.d.ts","sourceRoot":"","sources":["../../src/tools/load-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AASvE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmC5D"}
1
+ {"version":3,"file":"load-snapshot.d.ts","sourceRoot":"","sources":["../../src/tools/load-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoIvE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgE5D"}
@@ -13,9 +13,98 @@ import { z } from 'zod';
13
13
  import memlabHeapAnalysis from '@memlab/heap-analysis';
14
14
  const { getFullHeapFromFile } = memlabHeapAnalysis;
15
15
  import { setSnapshot } from '../heap-state.js';
16
- import { formatBytes, formatNumber, errorResult, textResult } from '../utils.js';
16
+ import { formatBytes, formatNumber, truncateNodeName, errorResult, textResult, } from '../utils.js';
17
+ function findLargestObject(snapshot) {
18
+ let best = null;
19
+ snapshot.nodes.forEach(node => {
20
+ if (node.id <= 3)
21
+ return;
22
+ if (node.type === 'object' ||
23
+ node.type === 'closure' ||
24
+ node.type === 'regexp') {
25
+ if (!best || node.retainedSize > best.size) {
26
+ best = {
27
+ id: node.id,
28
+ name: node.name,
29
+ size: node.retainedSize,
30
+ type: node.type,
31
+ };
32
+ }
33
+ }
34
+ });
35
+ return best;
36
+ }
37
+ function detectEnv(snapshot) {
38
+ let hasWindow = false;
39
+ let hasModule = false;
40
+ snapshot.nodes.forEach(node => {
41
+ if (hasWindow)
42
+ return;
43
+ if (node.name.startsWith('Window ') && node.type === 'object') {
44
+ hasWindow = true;
45
+ }
46
+ if (node.name === 'Module' &&
47
+ node.type === 'object' &&
48
+ !hasWindow &&
49
+ !hasModule) {
50
+ hasModule = true;
51
+ }
52
+ });
53
+ if (hasWindow)
54
+ return 'browser';
55
+ if (hasModule)
56
+ return 'node';
57
+ return 'unknown';
58
+ }
59
+ function quickDiagnosis(snapshot, totalSelfSize) {
60
+ const warnings = [];
61
+ const largeStrings = [];
62
+ const stringCounts = new Map();
63
+ const classCounts = new Map();
64
+ snapshot.nodes.forEach(node => {
65
+ if (node.id <= 3)
66
+ return;
67
+ if (node.type === 'string' && node.self_size >= 1024 * 1024) {
68
+ largeStrings.push({ id: node.id, name: node.name, size: node.self_size });
69
+ }
70
+ if (node.type === 'string' && node.name !== 'system / SlicedString') {
71
+ const key = node.name.length > 100 ? node.name.slice(0, 100) : node.name;
72
+ stringCounts.set(key, (stringCounts.get(key) ?? 0) + 1);
73
+ }
74
+ if (node.type !== 'hidden' && node.type !== 'array') {
75
+ classCounts.set(node.name, (classCounts.get(node.name) ?? 0) + 1);
76
+ }
77
+ });
78
+ if (largeStrings.length > 0) {
79
+ const totalSize = largeStrings.reduce((s, n) => s + n.size, 0);
80
+ warnings.push(`⚠ ${largeStrings.length} string(s) > 1 MB (${formatBytes(totalSize)} total) — possible unbounded data retention`);
81
+ }
82
+ const highDups = [...stringCounts.entries()]
83
+ .filter(([, count]) => count >= 1000)
84
+ .sort((a, b) => b[1] - a[1])
85
+ .slice(0, 3);
86
+ for (const [val, count] of highDups) {
87
+ const display = val.length > 40 ? val.slice(0, 40) + '…' : val;
88
+ warnings.push(`⚠ "${display}" duplicated ${formatNumber(count)} times`);
89
+ }
90
+ const largest = findLargestObject(snapshot);
91
+ if (largest && totalSelfSize > 0) {
92
+ const pct = ((largest.size / totalSelfSize) * 100).toFixed(0);
93
+ if (largest.size >= totalSelfSize * 0.3) {
94
+ warnings.push(`⚠ @${largest.id} ${truncateNodeName(largest.name, largest.type, largest.size, 40)} (${largest.type}) retains ${formatBytes(largest.size)} (${pct}% of heap)`);
95
+ }
96
+ }
97
+ const anomalous = [...classCounts.entries()]
98
+ .filter(([, count]) => count >= 10000)
99
+ .sort((a, b) => b[1] - a[1])
100
+ .slice(0, 3);
101
+ for (const [name, count] of anomalous) {
102
+ warnings.push(`⚠ ${formatNumber(count)}× \`${name}\` instances`);
103
+ }
104
+ return warnings;
105
+ }
17
106
  export function registerLoadSnapshot(server) {
18
- server.tool('memlab_load_snapshot', 'Load and parse a .heapsnapshot file. This builds indexes, computes the dominator tree, and calculates retained sizes. Only one snapshot can be loaded at a time.', {
107
+ server.tool('memlab_load_snapshot', 'Load and parse a .heapsnapshot file. This builds indexes, computes the dominator tree, and calculates retained sizes. Returns a quick diagnosis highlighting potential issues. Only one snapshot can be loaded at a time.', {
19
108
  file_path: z.string().describe('Absolute path to a .heapsnapshot file'),
20
109
  }, async ({ file_path }) => {
21
110
  try {
@@ -23,8 +112,12 @@ export function registerLoadSnapshot(server) {
23
112
  if (!fs.existsSync(resolved)) {
24
113
  return errorResult(new Error(`File not found: ${resolved}`));
25
114
  }
115
+ const fileStat = fs.statSync(resolved);
116
+ const fileSizeMB = fileStat.size / (1024 * 1024);
117
+ if (fileSizeMB > 200) {
118
+ process.stderr.write(`Loading ${formatBytes(fileStat.size)} snapshot — this may take a while (parsing, computing dominators, building indexes)...\n`);
119
+ }
26
120
  const snapshot = await getFullHeapFromFile(resolved);
27
- setSnapshot(snapshot, file_path);
28
121
  let nodeCount = 0;
29
122
  let edgeCount = 0;
30
123
  let totalSize = 0;
@@ -35,7 +128,28 @@ export function registerLoadSnapshot(server) {
35
128
  snapshot.edges.forEach(() => {
36
129
  edgeCount++;
37
130
  });
38
- return textResult(`Loaded ${file_path}: ${formatNumber(nodeCount)} nodes, ${formatNumber(edgeCount)} edges, ${formatBytes(totalSize)}`);
131
+ const env = detectEnv(snapshot);
132
+ const fileName = path.basename(file_path);
133
+ setSnapshot(snapshot, file_path, {
134
+ fileName,
135
+ nodeCount,
136
+ edgeCount,
137
+ totalSize,
138
+ env,
139
+ });
140
+ const envLabel = env === 'browser'
141
+ ? 'Browser'
142
+ : env === 'node'
143
+ ? 'Node.js'
144
+ : 'Unknown';
145
+ const lines = [
146
+ `Loaded ${file_path} (${formatBytes(fileStat.size)} on disk): ${formatNumber(nodeCount)} nodes, ${formatNumber(edgeCount)} edges, ${formatBytes(totalSize)} heap size (${envLabel} snapshot)`,
147
+ ];
148
+ const warnings = quickDiagnosis(snapshot, totalSize);
149
+ if (warnings.length > 0) {
150
+ lines.push('', ...warnings);
151
+ }
152
+ return textResult(lines.join('\n'));
39
153
  }
40
154
  catch (err) {
41
155
  return errorResult(err);
@@ -1 +1 @@
1
- {"version":3,"file":"load-snapshot.js","sourceRoot":"","sources":["../../src/tools/load-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,MAAM,EAAC,mBAAmB,EAAC,GAAG,kBAAkB,CAAC;AACjD,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAC,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AAE/E,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,kKAAkK,EAClK;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;KACxE,EACD,KAAK,EAAE,EAAC,SAAS,EAAC,EAAE,EAAE;QACpB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO,WAAW,CAAC,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACrD,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAEjC,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC5B,SAAS,EAAE,CAAC;gBACZ,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;YAC9B,CAAC,CAAC,CAAC;YACH,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC1B,SAAS,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,OAAO,UAAU,CACf,UAAU,SAAS,KAAK,YAAY,CAAC,SAAS,CAAC,WAAW,YAAY,CAAC,SAAS,CAAC,WAAW,WAAW,CAAC,SAAS,CAAC,EAAE,CACrH,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"load-snapshot.js","sourceRoot":"","sources":["../../src/tools/load-snapshot.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"object-shape.d.ts","sourceRoot":"","sources":["../../src/tools/object-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAYvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkF3D"}
1
+ {"version":3,"file":"object-shape.d.ts","sourceRoot":"","sources":["../../src/tools/object-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAavE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+G3D"}
@@ -9,10 +9,17 @@
9
9
  */
10
10
  import { z } from 'zod';
11
11
  import { getSnapshot } from '../heap-state.js';
12
- import { formatBytes, formatNumber, formatNodeInline, markdownTable, errorResult, textResult, } from '../utils.js';
12
+ import { formatBytes, formatNumber, formatNodeInline, markdownTable, errorResult, toolResult, } from '../utils.js';
13
13
  export function registerObjectShape(server) {
14
- server.tool('memlab_object_shape', 'Show the shape/structure of a heap object: all its named properties with target node types and sizes. Filters out internal/hidden edges to show only user-visible properties. Use this to understand what an object contains at a glance.', {
15
- node_id: z.number().describe('The numeric ID of the heap node'),
14
+ server.tool('memlab_object_shape', 'Show the shape/structure of one or more heap objects: all named properties with target node types and sizes. Filters out internal/hidden edges to show only user-visible properties. Supports batch inspection via node_ids to compare multiple objects side-by-side in a single call.', {
15
+ node_id: z
16
+ .number()
17
+ .optional()
18
+ .describe('The numeric ID of a single heap node. Use node_ids for batch inspection.'),
19
+ node_ids: z
20
+ .array(z.number())
21
+ .optional()
22
+ .describe('Array of node IDs to inspect in a single call (batch mode). Returns shape for each node.'),
16
23
  include_internal: z
17
24
  .boolean()
18
25
  .optional()
@@ -22,13 +29,16 @@ export function registerObjectShape(server) {
22
29
  .number()
23
30
  .optional()
24
31
  .default(50)
25
- .describe('Maximum number of properties to return (default 50)'),
26
- }, async ({ node_id, include_internal, limit }) => {
32
+ .describe('Maximum number of properties to return per node (default 50)'),
33
+ }, async ({ node_id, node_ids, include_internal, limit }) => {
27
34
  try {
28
35
  const snapshot = getSnapshot();
29
- const node = snapshot.getNodeById(node_id);
30
- if (!node) {
31
- return errorResult(`Node with id ${node_id} not found`);
36
+ const ids = node_ids ?? (node_id != null ? [node_id] : []);
37
+ if (ids.length === 0) {
38
+ return errorResult('Provide either node_id or node_ids to inspect.');
39
+ }
40
+ if (ids.length > 20) {
41
+ return errorResult('Maximum 20 nodes per batch. Reduce node_ids count.');
32
42
  }
33
43
  const userEdgeTypes = new Set([
34
44
  'property',
@@ -36,47 +46,56 @@ export function registerObjectShape(server) {
36
46
  'context',
37
47
  'shortcut',
38
48
  ]);
39
- const filteredEdges = node.references
40
- .filter(edge => include_internal || userEdgeTypes.has(edge.type))
41
- .sort((a, b) => b.toNode.retainedSize - a.toNode.retainedSize)
42
- .slice(0, limit);
43
- const totalEdges = node.references.length;
44
- const hiddenCount = include_internal
45
- ? 0
46
- : totalEdges -
47
- node.references.filter(e => userEdgeTypes.has(e.type)).length;
48
- const lines = [
49
- `**${formatNodeInline(node.id, node.name, node.type)}** — ${formatNumber(totalEdges)} edges total${hiddenCount > 0 ? `, ${formatNumber(hiddenCount)} internal hidden` : ''}`,
50
- '',
51
- ];
52
- const headers = [
53
- 'Name',
54
- 'Edge Type',
55
- 'Target',
56
- 'Target Type',
57
- 'Retained',
58
- ];
59
- const rightCols = new Set([4]);
60
- const rows = filteredEdges.map(edge => {
61
- const target = edge.toNode;
62
- let targetLabel = `@${target.id} ${target.name}`;
63
- if (target.isString) {
64
- const strNode = target.toStringNode();
65
- if (strNode) {
66
- const val = strNode.stringValue;
67
- targetLabel = `@${target.id} "${val.length > 60 ? val.slice(0, 60) + '...' : val}"`;
68
- }
49
+ const sections = [];
50
+ for (const id of ids) {
51
+ const node = snapshot.getNodeById(id);
52
+ if (!node) {
53
+ sections.push(`**@${id}** not found\n`);
54
+ continue;
69
55
  }
70
- return [
71
- String(edge.name_or_index),
72
- edge.type,
73
- targetLabel,
74
- target.type,
75
- formatBytes(target.retainedSize),
56
+ const filteredEdges = node.references
57
+ .filter(edge => include_internal || userEdgeTypes.has(edge.type))
58
+ .sort((a, b) => b.toNode.retainedSize - a.toNode.retainedSize)
59
+ .slice(0, limit);
60
+ const totalEdges = node.references.length;
61
+ const hiddenCount = include_internal
62
+ ? 0
63
+ : totalEdges -
64
+ node.references.filter(e => userEdgeTypes.has(e.type)).length;
65
+ const lines = [
66
+ `**${formatNodeInline(node.id, node.name, node.type, node.self_size)}** — ${formatNumber(totalEdges)} edges total${hiddenCount > 0 ? `, ${formatNumber(hiddenCount)} internal hidden` : ''}`,
67
+ '',
68
+ ];
69
+ const headers = [
70
+ 'Name',
71
+ 'Edge Type',
72
+ 'Target',
73
+ 'Target Type',
74
+ 'Retained',
76
75
  ];
77
- });
78
- lines.push(markdownTable(headers, rows, rightCols));
79
- return textResult(lines.join('\n'));
76
+ const rightCols = new Set([4]);
77
+ const rows = filteredEdges.map(edge => {
78
+ const target = edge.toNode;
79
+ let targetLabel = `@${target.id} ${target.name}`;
80
+ if (target.isString) {
81
+ const strNode = target.toStringNode();
82
+ if (strNode) {
83
+ const val = strNode.stringValue;
84
+ targetLabel = `@${target.id} "${val.length > 60 ? val.slice(0, 60) + '...' : val}"`;
85
+ }
86
+ }
87
+ return [
88
+ String(edge.name_or_index),
89
+ edge.type,
90
+ targetLabel,
91
+ target.type,
92
+ formatBytes(target.retainedSize),
93
+ ];
94
+ });
95
+ lines.push(markdownTable(headers, rows, rightCols));
96
+ sections.push(lines.join('\n'));
97
+ }
98
+ return toolResult(sections.join('\n\n---\n\n'));
80
99
  }
81
100
  catch (err) {
82
101
  return errorResult(err);
@@ -1 +1 @@
1
- {"version":3,"file":"object-shape.js","sourceRoot":"","sources":["../../src/tools/object-shape.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"object-shape.js","sourceRoot":"","sources":["../../src/tools/object-shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ export declare function registerPinchPoints(server: McpServer): void;
12
+ //# sourceMappingURL=pinch-points.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinch-points.d.ts","sourceRoot":"","sources":["../../src/tools/pinch-points.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAuBvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiI3D"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import { z } from 'zod';
11
+ import { getSnapshot, getSnapshotMetadata } from '../heap-state.js';
12
+ import { isNodeWorthInspecting, formatBytes, formatNumber, markdownTable, truncateNodeName, errorResult, toolResult, } from '../utils.js';
13
+ export function registerPinchPoints(server) {
14
+ server.tool('memlab_pinch_points', 'Find "pinch points" — small objects that retain disproportionately large subtrees in the dominator tree. These are the most impactful objects to free: a single cache, map, or closure whose removal would reclaim the most memory. Returns objects ranked by retained_size/self_size ratio, filtered to actionable user-code objects (excludes V8 internals).', {
15
+ limit: z
16
+ .number()
17
+ .optional()
18
+ .default(15)
19
+ .describe('Maximum number of pinch points to return (default 15)'),
20
+ min_retained_size: z
21
+ .number()
22
+ .optional()
23
+ .default(1048576)
24
+ .describe('Minimum retained size in bytes to consider (default 1 MB). Increase for large snapshots.'),
25
+ min_ratio: z
26
+ .number()
27
+ .optional()
28
+ .default(100)
29
+ .describe('Minimum retained_size/self_size ratio (default 100). Higher values find more extreme pinch points.'),
30
+ }, async ({ limit, min_retained_size, min_ratio }) => {
31
+ try {
32
+ const snapshot = getSnapshot();
33
+ const meta = getSnapshotMetadata();
34
+ const totalSize = meta?.totalSize ?? 0;
35
+ const candidates = [];
36
+ snapshot.nodes.forEach(node => {
37
+ if (!isNodeWorthInspecting(node))
38
+ return;
39
+ if (node.self_size === 0)
40
+ return;
41
+ if (node.retainedSize < min_retained_size)
42
+ return;
43
+ const ratio = node.retainedSize / node.self_size;
44
+ if (ratio < min_ratio)
45
+ return;
46
+ const entry = {
47
+ nodeId: node.id,
48
+ name: node.name,
49
+ type: node.type,
50
+ selfSize: node.self_size,
51
+ retainedSize: node.retainedSize,
52
+ ratio,
53
+ dominatedCount: 0,
54
+ };
55
+ let inserted = false;
56
+ for (let i = 0; i < candidates.length; i++) {
57
+ if (entry.retainedSize > candidates[i].retainedSize) {
58
+ candidates.splice(i, 0, entry);
59
+ inserted = true;
60
+ break;
61
+ }
62
+ }
63
+ if (!inserted)
64
+ candidates.push(entry);
65
+ if (candidates.length > limit)
66
+ candidates.length = limit;
67
+ });
68
+ const candidateIds = new Set(candidates.map(c => c.nodeId));
69
+ snapshot.nodes.forEach(node => {
70
+ const domId = node.dominatorNode?.id;
71
+ if (domId != null && candidateIds.has(domId)) {
72
+ const entry = candidates.find(c => c.nodeId === domId);
73
+ if (entry)
74
+ entry.dominatedCount++;
75
+ }
76
+ });
77
+ if (candidates.length === 0) {
78
+ return toolResult(`No pinch points found with retained_size >= ${formatBytes(min_retained_size)} and ratio >= ${min_ratio}:1. Try lowering the thresholds.`);
79
+ }
80
+ const headers = [
81
+ 'ID',
82
+ 'Name',
83
+ 'Type',
84
+ 'Self Size',
85
+ 'Retained Size',
86
+ 'Ratio',
87
+ '% Heap',
88
+ 'Dominated',
89
+ ];
90
+ const rightCols = new Set([3, 4, 5, 6, 7]);
91
+ const rows = candidates.map(c => {
92
+ const pct = totalSize > 0
93
+ ? ((c.retainedSize / totalSize) * 100).toFixed(1) + '%'
94
+ : '-';
95
+ return [
96
+ `@${c.nodeId}`,
97
+ truncateNodeName(c.name, c.type, c.selfSize, 50),
98
+ c.type,
99
+ formatBytes(c.selfSize),
100
+ formatBytes(c.retainedSize),
101
+ `${formatNumber(Math.round(c.ratio))}:1`,
102
+ pct,
103
+ formatNumber(c.dominatedCount),
104
+ ];
105
+ });
106
+ const lines = [
107
+ `Pinch points: ${candidates.length} objects with high retained/self ratio`,
108
+ '',
109
+ markdownTable(headers, rows, rightCols),
110
+ '',
111
+ '**Interpretation:** Each row is a small object retaining a large subtree. Freeing it (e.g., clearing a cache, removing an event listener) would reclaim the retained size.',
112
+ '',
113
+ '**Suggested next steps:**',
114
+ ];
115
+ const top = candidates[0];
116
+ lines.push(`- Inspect top pinch point: \`memlab_get_node(${top.nodeId})\` → \`memlab_object_shape(${top.nodeId})\``, `- See what it retains: \`memlab_dominator_subtree(${top.nodeId})\``, `- Trace how it's kept alive: \`memlab_retainer_trace(${top.nodeId})\``);
117
+ return toolResult(lines.join('\n'));
118
+ }
119
+ catch (err) {
120
+ return errorResult(err);
121
+ }
122
+ });
123
+ }
124
+ //# sourceMappingURL=pinch-points.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinch-points.js","sourceRoot":"","sources":["../../src/tools/pinch-points.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ export declare function registerQuickDiagnosis(server: McpServer): void;
12
+ //# sourceMappingURL=quick-diagnosis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quick-diagnosis.d.ts","sourceRoot":"","sources":["../../src/tools/quick-diagnosis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoDvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4O9D"}