mcp-jvm-diagnostics 0.1.9 → 0.1.11

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 CHANGED
@@ -31,7 +31,7 @@ It analyzes **offline** artifacts (thread dumps, GC logs, heap histograms) rathe
31
31
  - Priority support
32
32
 
33
33
  <!-- TODO: replace placeholder Stripe Payment Link once STRIPE_SECRET_KEY is configured -->
34
- **$9.99/month** — [Get Pro License](https://buy.stripe.com/PLACEHOLDER)
34
+ **$9.00/month** — [Get Pro License](https://buy.stripe.com/PLACEHOLDER)
35
35
 
36
36
  Pro license key activates the `generate_report` MCP tool in mcp-jvm-diagnostics.
37
37
 
package/build/index.js CHANGED
@@ -13,7 +13,7 @@ import { parseJfrSummary } from "./parsers/jfr-summary.js";
13
13
  import { generateReportFromThreadDump, analyzeThreadDumpMarkdown, } from "./reporting.js";
14
14
  // Handle --help
15
15
  if (process.argv.includes("--help") || process.argv.includes("-h")) {
16
- console.log(`mcp-jvm-diagnostics v0.1.9 — MCP server for JVM diagnostics
16
+ console.log(`mcp-jvm-diagnostics v0.1.11 — MCP server for JVM diagnostics
17
17
 
18
18
  Usage:
19
19
  mcp-jvm-diagnostics [options]
@@ -33,7 +33,7 @@ Tools provided:
33
33
  }
34
34
  const server = new McpServer({
35
35
  name: "mcp-jvm-diagnostics",
36
- version: "0.1.9",
36
+ version: "0.1.11",
37
37
  });
38
38
  // --- Tool: analyze_thread_dump ---
39
39
  server.tool("analyze_thread_dump", "Parse a JVM thread dump (jstack output) and analyze thread states, detect deadlocks, identify lock contention hotspots, and find thread starvation patterns. Handles both platform threads and virtual threads (Java 21+). Note: deadlock detection covers synchronized monitor locks only — java.util.concurrent.locks.ReentrantLock and other j.u.c lock types do not expose their waiters in thread dump lock info and will not be detected.", {
@@ -345,15 +345,15 @@ server.tool("analyze_jfr", "Parse JDK Flight Recorder summary output and analyze
345
345
  }
346
346
  });
347
347
  // --- Tool: diagnose_jvm ---
348
- server.tool("diagnose_jvm", "Unified JVM diagnosis combining thread dump and GC log analysis. Provide one or both inputs for comprehensive root cause analysis.", {
348
+ server.tool("diagnose_jvm", "Unified JVM diagnosis combining thread dump and GC log analysis with cross-correlation. Detects deadlocks, lock contention, GC pressure, and GC-induced cascading thread blocks. When both inputs are provided from the same time window, cross-correlates high GC overhead with contention and flags long GC pauses causing thread starvation. Either input can be omitted for single-source analysis.", {
349
349
  thread_dump: z
350
350
  .string()
351
351
  .optional()
352
- .describe("Thread dump text (from jstack)"),
352
+ .describe("Thread dump text (from jstack, kill -3, or VisualVM). Capture at the same time as the GC log for accurate cross-correlation."),
353
353
  gc_log: z
354
354
  .string()
355
355
  .optional()
356
- .describe("GC log text (from -Xlog:gc*)"),
356
+ .describe("GC log text (from -Xlog:gc* for Java 9+, or -verbose:gc for Java 8). Capture at the same time as the thread dump for accurate cross-correlation."),
357
357
  }, async ({ thread_dump, gc_log }) => {
358
358
  try {
359
359
  if (!thread_dump && !gc_log) {
@@ -119,6 +119,7 @@ function analyzeJfrEvents(events, totalEvents, totalSize) {
119
119
  const threadStart = byName.get("jdk.ThreadStart");
120
120
  if (threadStart && threadStart.count > 200) {
121
121
  issues.push(`${threadStart.count.toLocaleString()} threads started — possible thread churn. Consider thread pooling.`);
122
+ recommendations.push("Replace ad-hoc thread creation with a fixed-size thread pool (Executors.newFixedThreadPool) or virtual threads (Java 21+) to eliminate thread creation overhead.");
122
123
  }
123
124
  // Check for exception events
124
125
  const exceptions = byName.get("jdk.JavaExceptionThrow");
@@ -130,6 +131,7 @@ function analyzeJfrEvents(events, totalEvents, totalSize) {
130
131
  const classLoad = byName.get("jdk.ClassLoad");
131
132
  if (classLoad && classLoad.count > 1000) {
132
133
  issues.push(`${classLoad.count.toLocaleString()} class loads — excessive class loading may indicate classloader leak or dynamic proxy overuse.`);
134
+ recommendations.push("Use `analyze_heap_histo` to check java.lang.Class instance count. If growing, look for frameworks that generate proxies or bytecode at runtime (Hibernate, Spring AOP, reflection-heavy libraries).");
133
135
  }
134
136
  // Check for file/socket I/O
135
137
  const fileRead = byName.get("jdk.FileRead");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-jvm-diagnostics",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "MCP server for JVM diagnostics — analyze thread dumps, detect deadlocks, parse GC logs, and get JVM tuning recommendations",
5
5
  "mcpName": "io.github.dmitriusan/mcp-jvm-diagnostics",
6
6
  "author": "Dmytro Lisnichenko",