mcp-jvm-diagnostics 0.1.10 → 0.1.12
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 +1 -1
- package/build/index.js +4 -4
- package/build/parsers/gc-log.js +1 -0
- package/build/parsers/jfr-summary.js +4 -1
- package/package.json +1 -1
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.
|
|
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.
|
|
16
|
+
console.log(`mcp-jvm-diagnostics v0.1.12 — 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.
|
|
36
|
+
version: "0.1.12",
|
|
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.", {
|
|
@@ -349,11 +349,11 @@ server.tool("diagnose_jvm", "Unified JVM diagnosis combining thread dump and GC
|
|
|
349
349
|
thread_dump: z
|
|
350
350
|
.string()
|
|
351
351
|
.optional()
|
|
352
|
-
.describe("Thread dump text (from jstack, kill -3, or VisualVM). Capture
|
|
352
|
+
.describe("Thread dump text (from jstack, kill -3, or VisualVM). Capture during active symptoms for meaningful cross-correlation — a dump from a healthy period will not correlate with GC pressure visible in the log."),
|
|
353
353
|
gc_log: z
|
|
354
354
|
.string()
|
|
355
355
|
.optional()
|
|
356
|
-
.describe("GC log text (from -Xlog:gc* for Java 9+, or -verbose:gc for Java 8).
|
|
356
|
+
.describe("GC log text (from -Xlog:gc* for Java 9+, or -verbose:gc for Java 8). Provide the portion covering the time window when the thread dump was taken — trim the log to the symptom window if it is large. Logs from a different time period produce spurious correlations."),
|
|
357
357
|
}, async ({ thread_dump, gc_log }) => {
|
|
358
358
|
try {
|
|
359
359
|
if (!thread_dump && !gc_log) {
|
package/build/parsers/gc-log.js
CHANGED
|
@@ -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");
|
|
@@ -140,7 +142,8 @@ function analyzeJfrEvents(events, totalEvents, totalSize) {
|
|
|
140
142
|
.filter(Boolean)
|
|
141
143
|
.reduce((sum, e) => sum + e.count, 0);
|
|
142
144
|
if (ioCount > 5000) {
|
|
143
|
-
issues.push(`High I/O activity: ${ioCount.toLocaleString()} file/socket events
|
|
145
|
+
issues.push(`High I/O activity: ${ioCount.toLocaleString()} file/socket events recorded.`);
|
|
146
|
+
recommendations.push("Profile I/O call sites with async-profiler or VisualVM. Common causes: unbuffered writes, per-record DB queries, missing connection pooling. Consider batching writes and reads.");
|
|
144
147
|
}
|
|
145
148
|
// Check for compilation events
|
|
146
149
|
const compilation = byName.get("jdk.Compilation");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-jvm-diagnostics",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
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",
|