Skip to main content
Glama
perfsage

perfsage-jmeter-mcp

by perfsage
README.md
<p align="center">
  <a href="./assets/readme/hero.svg">
    <img src="./assets/readme/hero.gif" width="100%" alt="PerfSage JMeter MCP β€” your LLM becomes a performance engineer: heal, script, discover, verdict">
  </a>
</p>

<p align="center">
  <strong>Self-healing JMeter for LLM agents.</strong><br/>
  Heal the runtime Β· auto-correlate scripts Β· discover capacity Β· ship a <code>p95</code>/<code>p99</code> verdict.
</p>

<p align="center">
  <a href="#-60-second-setup">πŸš€ Setup</a> Β·
  <a href="#-why-teams-reach-for-this">✨ Why</a> ·
  <a href="#-how-it-works">πŸ” Flow</a> Β·
  <a href="#-tools">🧰 Tools</a> ·
  <a href="#-example-session">πŸ’¬ Demo</a> Β·
  <a href="https://perfsage.com">🌐 PerfSage</a>
</p>

---

## 🎯 What you get

Stop wrestling with Java paths, broken plugins, and hand-written extractors.

Point Cursor / Claude at this MCP server and ask for a performance test. It will:

1. **Heal** Java + Apache JMeter **5.6.3** + plugins under `~/.perfsage` (Docker fallback if needed)
2. **Import** HAR / OpenAPI / Postman traffic
3. **Auto-correlate** tokens, cookies, and IDs into JMeter variables
4. **Discover** the throughput knee when you don’t know the workload
5. **Report** a PASS / WARN / FAIL led by **p95 + p99** (never averages alone)

> Analysis, not dashboards. Every run ends in a decision.

---

## ⚑ 60-second setup

Requires **Python 3.10+**. Prefer [uv](https://docs.astral.sh/uv/) (macOS system `python3` is often 3.9; uv-managed Pythons also block bare `pip` via PEP 668).

```bash
# try it (no install)
uvx perfsage-jmeter-mcp --version
uvx perfsage-jmeter-mcp
```

```bash
# install as a user tool (recommended)
uv tool install perfsage-jmeter-mcp
perfsage-jmeter-mcp --version
```

```bash
# or inside a project venv
uv venv --python 3.12
source .venv/bin/activate   # Windows: .venv\Scripts\activate
uv pip install perfsage-jmeter-mcp
```

> **Do not** run `python3.12 -m pip install …` against a uv-managed interpreter β€” you’ll get `externally-managed-environment`. Use `uv tool install` / `uv pip install` / a venv instead. Apple’s `/usr/bin/python3` (3.9) cannot see this package at all (`requires-python >=3.10`).

### πŸ”Œ Connect Cursor / Claude Desktop

Drop this into your MCP config (`examples/cursor-mcp.json`):

```json
{
  "mcpServers": {
    "perfsage-jmeter": {
      "command": "uvx",
      "args": ["perfsage-jmeter-mcp"]
    }
  }
}
```

Then say:

> **β€œSet up the performance environment, then import `login_flow.har` and give me a capacity recommendation.”**

That’s the whole onboarding.

> **Fixture note:** `tests/recorder/fixtures/login_flow.har` targets `shop.perfsage.test`, which is **offline**. Use it to demo **correlation / JMX generation** only β€” not live `run_test` smoke. For runnable demos, import a HAR against a real host (for example JSONPlaceholder or your own staging URL).

---

## ✨ Why teams reach for this

| Pain today | With PerfSage JMeter MCP |
|---|---|
| ❌ β€œWrong Java / missing JMeter / plugin chaos” | βœ… `ensure_environment` self-heals under `~/.perfsage` β€” **no sudo**, no shell-profile edits |
| ❌ Manual regex correlation for every token | βœ… `correlate_flow` detects CSRF / JWT / session IDs and wires extractors |
| ❌ Guessing thread counts | βœ… `discover_workload` finds the knee, recommends **80%** sustained load |
| ❌ Average latency gates that lie | βœ… Reports always include **p95 + p99** + SLO verdict |
| ❌ Client metrics disconnected from K8s | βœ… Optional [SignalPilot](https://github.com/perfsage/signalpilot) RCA + [Reveal](https://github.com/perfsage/reveal) charts |

---

## πŸ” How it works

<p align="center">
  <img src="./assets/readme/workflow.svg" width="100%" alt="Workflow: Heal β†’ Import β†’ Correlate β†’ Discover β†’ Verdict">
</p>

| Step | Tool | Outcome |
|:----:|---|---|
| 1️⃣ | `ensure_environment` | Ready runtime (native or Docker) |
| 2️⃣ | `import_traffic` | Clean application Flow (static noise filtered) |
| 3️⃣ | `correlate_flow` + `generate_jmx` | Replayable JMeter 5.6.3 plan |
| 4️⃣ | `edit_jmx` (optional) | Workload / structure tweaks (burst, loops, JSR223, …) |
| 5️⃣ | `run_test` / `discover_workload` | Guarded execution + capacity profile |
| 6️⃣ | `compile_report` | Markdown + HTML + JSON, verdict first |

---

## πŸ’¬ Example session

```text
You:  Set up the performance environment.
Agent: ensure_environment β†’ ready=true, Java 21 + JMeter 5.6.3 under ~/.perfsage

You:  Import tests/recorder/fixtures/login_flow.har (correlation demo; host is offline) and correlate it.
Agent: import_traffic β†’ 4 app requests
       correlate_flow β†’ csrf_token, token, cart_id, SESSION (cookie-managed)

You:  Generate a fixed plan at 20 threads / 120s, then run a 5-minute burst inside 20 minutes.
Agent: generate_jmx β†’ ${__P(perfsage.threads,20)} / ${__P(perfsage.duration,120)}
       edit_jmx β†’ set_workload burst (Ultimate Thread Group)
       run_test / discover_workload β†’ guarded execution + capacity

You:  Compile the report with examples/slo.properties.
Agent: compile_report β†’ PASS/WARN/FAIL leading with p95 + p99
       artifacts β†’ ~/.perfsage/runs/<id>/report/
```

---

## 🧰 Tools

| Tool | What it does |
|---|---|
| 🩺 `ensure_environment` | Diagnose + heal Java / JMeter / plugins / Docker |
| πŸ” `diagnose_environment` | Read-only readiness report |
| πŸ“₯ `import_traffic` | HAR / OpenAPI / Postman β†’ Flow |
| πŸ”— `correlate_flow` | Dynamic values β†’ variables + extractors |
| πŸ“ `generate_jmx` | Correlated Flow β†’ JMeter 5.6.3 plan |
| ✏️ `edit_jmx` | Structured ops on an existing plan (new file by default) |
| πŸš€ `run_test` | Execute with always-on guardrails |
| πŸ“ˆ `discover_workload` | Adaptive knee-point discovery |
| πŸ“Š `analyze_results` | JTL β†’ metrics, bottlenecks, p95/p99 |
| βœ… `evaluate_slo` | Gate against `slo.properties` |
| ☸️ `correlate_with_signalpilot` | Merge Kubernetes RCA for the test window |
| πŸ“¦ `compile_report` | Unified Markdown + HTML + JSON |

Full schemas & sample payloads: [`docs/TOOLS.md`](./docs/TOOLS.md)

---

## πŸ›‘οΈ Environment gate (runs first)

Every JMeter-touching tool calls `ensure_environment` first:

| Condition | Action |
|---|---|
| Java missing / outside 17–21 | Download Temurin JDK **21** into `~/.perfsage/jdk/` |
| JMeter missing / &lt; 5.6.3 | Download Apache JMeter **5.6.3** + verify ASF SHA-512 |
| Plugins missing | Install `jpgc-casutg`, `jpgc-tst`, `jpgc-json`, `jpgc-dummy`, `perfsage-slo-reporter` |
| Host can’t be provisioned | Fall back to Docker (`justb4/jmeter`) and **say so** |
| Neither works | Structured failure: attempted Β· failed Β· values |

πŸ”’ Nothing writes outside `~/.perfsage` (or your working directory). No `JAVA_HOME` mutations. No package-manager side effects.

---

## 🧩 Ecosystem

| Project | Role |
|---|---|
| [Reveal](https://github.com/perfsage/reveal) | JTL analysis + chart pack |
| [SLO Reporter](https://github.com/perfsage/perfsage-slo-reporter) | SLO gate format + Backend Listener |
| [SignalPilot](https://github.com/perfsage/signalpilot) | Kubernetes RCA for the test window |
| [perfsage.com](https://perfsage.com) | Brand home Β· Field Notes Β· tools |

---

## πŸ› οΈ Development

```bash
uv run --python 3.12 --extra dev pytest
uv run --python 3.12 --extra dev ruff check .
uv run --python 3.12 --extra dev mypy perfsage_jmeter_mcp
```

Real JMeter e2e: `tests/test_end_to_end.py` (`e2e` marker).  
Architecture notes: [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md)

---

## πŸ“„ License

MIT

Apache JMeter is a trademark of the Apache Software Foundation. This project is an independent tool and is not affiliated with or endorsed by the ASF.

---

<p align="center">
  <strong>Ready when your agent is.</strong><br/>
  <code>uvx perfsage-jmeter-mcp</code> Β· then ask it to <code>ensure_environment</code>
</p>

TDQS

A4.1/5.0

Scored across 12 tools

Disambiguation4/5

Most tools map to distinct pipeline stages (import, correlate, generate, run, analyze, report), but diagnose_environment/ensure_environment and correlate_flow/correlate_with_signalpilot have overlapping names and related purposes. Descriptions clarify the boundaries, so an agent can usually select correctly.

Naming Consistency4/5

All tool names are snake_case and verb-first, following a predictable pattern like diagnose_environment, generate_jmx, and evaluate_slo. correlate_with_signalpilot is a minor deviation from the simple verb_noun shape but still fits the overall style.

Tool Count5/5

Twelve tools are well-scoped for a JMeter performance-testing workflow. Each tool covers a meaningful stage from environment readiness to traffic import, JMX generation, execution, analysis, SLO evaluation, and reporting, with no obvious bloat.

Completeness5/5

The tool surface covers the full load-test lifecycle: environment provisioning, test creation, execution, workload discovery, results analysis, SLO gating, and report compilation. There are no obvious dead ends or missing core operations for the stated domain.

Maintenance

ActivitySlowing
ResponsivenessNo issues