Heap Seance

by SegfaultSorcerer

312 downloads
Not rated
GitHub

About

Java memory leak diagnostics via MCP. Channels jcmd, jmap, jstat, JFR, Eclipse MAT, and async-profiler into a structured investigation workflow with confidence-based verdicts. Two slash commands: /leak-scan (conservative) and /leak-deep (full forensics). Designed for Claude Code.

Details

Author
SegfaultSorcerer
Downloads
312
Categories
Other

- Two‑stage escalation: /leak-scan (conservative) then /leak-deep (full forensics)
- Eight MCP tools: process listing, class histograms, GC snapshots, JFR recording, heap dumps, MAT leak suspects, and async-profiler allocation profiles
- Unified confidence ladder: none → low → medium → high based on independent signals
- Conservative by default: no deep forensics unless evidence demands it
- Automatic artifact saving for team review
- CLI mode available without Claude Code

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Heap Seance
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Clone the repository, add a .mcp.json configuration to your Java project pointing to the Heap Seance directory, and copy the .claude/commands/ folder into the project. Then invoke the /leak-scan or /leak-deep slash commands from Claude Code, or use the CLI directly via uv run heap-seance --mode scan --match <name> or --mode deep --pid <pid>. The tools require Python 3.10+, JDK 17+, and uv. Deep mode additionally requires Eclipse MAT CLI.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "heap seance": {
            "heap-seance": {
                "command": "uv",
                "args": [
                    "run",
                    "--directory",
                    "/path/to/heap-seance",
                    "python",
                    "-m",
                    "heap_seance_mcp.server"
                ],
                "env": {
                    "JAVA_HOME": "/path/to/jdk-17",
                    "MAT_BIN": "/path/to/ParseHeapDump.sh",
                    "ASYNC_PROFILER_BIN": "/path/to/asprof"
                }
            }
        }
    }
}

McpServers

{
    "heap-seance": {
        "command": "uv",
        "args": [
            "run",
            "--directory",
            "/path/to/heap-seance",
            "python",
            "-m",
            "heap_seance_mcp.server"
        ],
        "env": {
            "JAVA_HOME": "/path/to/jdk-17",
            "MAT_BIN": "/path/to/ParseHeapDump.sh",
            "ASYNC_PROFILER_BIN": "/path/to/asprof"
        }
    }
}

<p align="center">
Heap Seance
</p>

<h1 align="center">Heap Seance</h1>

<p align="center">
<em>Summoning retained objects from the heap — so you can interrogate what refuses to die.</em>
</p>

<p align="center">
<a href="LICENSE-MIT">MIT</a>
<a href="LICENSE-APACHE">Apache 2.0</a>
Python 3.10+
JDK 17+
MCP Server
Claude Code Plugin
</p>

<p align="center">
An MCP server + CLI toolkit that channels the spirits of <code>jcmd</code>, <code>jmap</code>, <code>jstat</code>, <code>jfr</code>, Eclipse MAT, and async-profiler into a structured leak investigation workflow — designed to run inside <a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code</a>.
</p>

<p align="center">
2 slash commands. 8 MCP tools. Conservative by default.
</p>

---

<p align="center">
<a href="#how-it-works">How It Works</a> &bull;
<a href="#quick-start">Quick Start</a> &bull;
<a href="#mcp-tools">MCP Tools</a> &bull;
<a href="#investigation-workflow">Workflow</a> &bull;
<a href="#prerequisites">Prerequisites</a> &bull;
<a href="#contributing">Contributing</a>
</p>

---

How It Works

Heap Seance follows a two-stage escalation model. No deep forensics unless the evidence demands it.

 /leak-scan                          /leak-deep
     |                                   |
     v                                   v
  3x class histogram               (all of scan, plus)
  + GC pressure snapshot            JFR recording
     |                              heap dump
     v                              MAT leak suspects
  monotonic growth?                 async-profiler alloc profile
  old-gen pressure?                     |
     |                                  v
     +--- both true? -----> auto-escalate to deep
     |
     +--- otherwise ------> verdict + next steps

Confidence is earned, not assumed. high requires at least two independent strong signals. A single growing class is watch. Growth plus GC pressure is suspicious. Add a MAT dominator or JFR correlation and you get probable_memory_leak.

Quick Start

Requires uv, Python 3.10+, and a JDK 17+ for tooling (the target app can run any Java version).

1. Clone

git clone https://github.com/your-org/heap-seance.git

2. Add .mcp.json to your Java project

In the project you want to investigate, create a .mcp.json:

{
  "mcpServers": {
    "heap-seance": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/heap-seance", "python", "-m", "heap_seance_mcp.server"],
      "env": {
        "JAVA_HOME": "/path/to/jdk-17",
        "MAT_BIN": "/path/to/ParseHeapDump.sh",
        "ASYNC_PROFILER_BIN": "/path/to/asprof"
      }
    }
  }
}

--directory points to where you cloned Heap Seance. uv run handles the virtual environment and dependencies automatically. ASYNC_PROFILER_BIN is optional — if missing, deep mode continues with JFR + MAT.

3. Copy the Claude Code commands

Copy the .claude/commands/ folder into your Java project so the /leak-scan and /leak-deep slash commands are available:

cp -r /path/to/heap-seance/.claude/commands/ .claude/commands/

4. Run

/leak-scan my-service        # conservative scan
/leak-deep 12345             # full forensics by PID

Heap Seance resolves the target process, collects evidence, and returns a structured verdict.

MCP Tools

| Tool | What it does |
|------|-------------|
| java_list_processes() | Discover running JVMs via jcmd -l |
| java_class_histogram(pid) | Snapshot live object counts per class |
| java_gc_snapshot(pid) | Sample jstat -gcutil over time |
| java_jfr_start(pid) | Capture a JFR recording |
| java_jfr_summary(jfr_file) | Summarize JFR event types and counts |
| java_heap_dump(pid) | Full heap dump (.hprof) |
| java_mat_suspects(heap_dump) | Run MAT leak suspects analysis |
| java_async_alloc_profile(pid) | Allocation flame graph via async-profiler |

Every tool returns the same unified schema:

{
  "status": "ok | warn | error",
  "evidence": ["..."],
  "metrics": {},
  "confidence": "none | low | medium | high",
  "next_recommended_action": "...",
  "raw_artifact_path": "..."
}

Investigation Workflow

1. Start your app and let it initialize fully.
2. /leak-scan <name-or-pid> — takes the first histogram snapshot.
3. Exercise the suspect behavior — the scan prompts you between each of the 3 histogram samples to perform the action you suspect is leaking (open/close views, send requests, repeat workflows). This is critical — without load between samples, leaks stay invisible.
4. Read the verdict. Focus on Confidence, Key Evidence, Suspect Types.
5. /leak-deep <name-or-pid> if the scan flags growth, or if you want full forensics regardless.
6. Fix and re-scan. Bounded caches, weak refs, listener cleanup — then /leak-scan again to confirm the signal drops.
7. Keep artifacts. .jfr, .hprof, and MAT reports are saved for team review.

What you get back

/leak-scan returns: Verdict, Confidence, Key Evidence, Suspect Types, Artifacts, Next Steps.

/leak-deep goes further: Verdict, Confidence, Root Holder Hypothesis (who retains the growing objects and via which field/chain), Supporting Evidence, Artifacts, Remediation Hypotheses (concrete fix suggestions), Verification Plan.

Confidence ladder

| Confidence | What it means | Signals required |
|------------|--------------|-----------------|
| none | No leak evidence | — |
| low | Weak growth, no GC pressure | histogram only |
| medium | Growth + GC is losing | histogram + GC pressure |
| high | Probable leak, corroborated | histogram + GC + MAT/JFR |

Prerequisites

Tooling JDK (required):
- JDK 17+ for jcmd, jmap, jstat — set via JAVA_HOME in .mcp.json
- The target application can run any Java version (including Java 8)

Deep forensics (for /leak-deep):
- Eclipse MAT CLI (ParseHeapDump.sh / .bat) — required for deep mode
- async-profiler — optional tie-breaker

Optional tools:
- jfr CLI — used for JFR summary if available, falls back to jcmd JFR.view otherwise. JFR is skipped entirely for Java 8 targets (incompatible format).

Check your setup:

./scripts/check_prereqs.sh          # macOS / Linux
scripts\check_prereqs.bat           # Windows

Environment overrides

Set these in your .mcp.json env block (recommended) or as shell variables:

| Variable | Required | Description |
|----------|----------|-------------|
| JAVA_HOME | recommended | JDK 17+ installation path — $JAVA_HOME/bin is searched first for jcmd, jmap, jstat, jfr. Also used to launch MAT with the correct Java version. |
| MAT_BIN | for deep mode | Path to ParseHeapDump.sh (macOS/Linux) or .bat (Windows) |
| ASYNC_PROFILER_BIN | optional | Path to async-profiler binary — tie-breaker evidence, deep mode works without it |
| HEAP_SEANCE_ARTIFACT_DIR | optional | Where .jfr, .hprof, and reports are saved (default: system temp dir) |

See .mcp.json.example for a full config template.

Compatibility notes

- Java 8 targets: histogram + GC + MAT work fully. JFR is skipped (v0.9 format incompatible with modern tools).
- Windows: MAT works via ParseHeapDump.bat. async-profiler is optional — if missing, deep mode continues with JFR + MAT. Locale-specific decimal separators (comma vs dot) in jstat output are handled automatically.
- MAT + JAVA_HOME: MAT is launched with the JDK from JAVA_HOME, so it works even if the system default Java is too old for MAT.

CLI Usage (without Claude Code)

uv run heap-seance --mode scan --match your-app
uv run heap-seance --mode deep --pid 12345 --output json

<details>
<summary><strong>Installing uv</strong></summary>

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

Windows (PowerShell)

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

</details>

<details>
<summary><strong>Manual setup (without uv)</strong></summary>

python3 -m venv .venv
source .venv/bin/activate       # Windows: .\.venv\Scripts\Activate.ps1
pip install -e .

heap-seance --mode scan --match your-app

</details>

Tests

python3 -m unittest discover -s tests -p "test_*.py"

Example Java scenarios for validation live in examples/java-scenarios/ — a real leak, a bounded cache (no leak), and a burst allocator (no leak).

Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines on adding tools, signals, and skills.

License

This project is dual-licensed under either of

- Apache License, Version 2.0
- MIT License

at your option.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.