jmeter-mcp
by Realtyka
README.md
# jmeter-mcp
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that integrates [Apache JMeter](https://jmeter.apache.org/) with AI assistants like Claude Code. Run load tests, parse results, inspect test plans, and compare performance — all through natural language.
## Prerequisites
- **Node.js** >= 18
- **Apache JMeter** installed locally ([download](https://jmeter.apache.org/download_jmeter.cgi))
## Installation
```bash
git clone https://github.com/chung-ta1/jmeter-mcp.git
cd jmeter-mcp
npm install
npm run build
```
## Configuration
Set the `JMETER_HOME` environment variable to your JMeter installation path:
```bash
export JMETER_HOME=/usr/local/opt/jmeter
```
Or create a `.env` file in the project root (see `.env.example`):
```
JMETER_HOME=/usr/local/opt/jmeter
```
## Usage
### Adding to Claude Code
There are three ways to register this MCP server with Claude Code:
#### Option 1: CLI command (recommended)
```bash
claude mcp add jmeter -e JMETER_HOME=/usr/local/opt/jmeter -- node /absolute/path/to/jmeter-mcp/dist/index.js
```
This adds the server to your project-level config (`.claude/mcp.json`). To add it globally (available in all projects):
```bash
claude mcp add --scope user jmeter -e JMETER_HOME=/usr/local/opt/jmeter -- node /absolute/path/to/jmeter-mcp/dist/index.js
```
#### Option 2: Edit settings file manually
Add to `~/.claude.json` (global) or `.claude/mcp.json` (project-level):
```json
{
"mcpServers": {
"jmeter": {
"command": "node",
"args": ["/absolute/path/to/jmeter-mcp/dist/index.js"],
"env": {
"JMETER_HOME": "/usr/local/opt/jmeter"
}
}
}
}
```
#### Option 3: From within Claude Code
Run the `/mcp` slash command inside a Claude Code session, then follow the prompts to add a new stdio server.
#### Verify it works
After adding, restart Claude Code and run:
```bash
claude mcp list
```
You should see `jmeter` listed with status `connected`. Then ask Claude things like:
- *"Run the load test at ~/tests/api-test.jmx with 50 threads"*
- *"Show me the results from /tmp/jmeter-results.jtl"*
- *"Compare the baseline and current test results"*
- *"List all test plans in my project"*
- *"Inspect the structure of my test plan"*
### Standalone
```bash
JMETER_HOME=/usr/local/opt/jmeter node dist/index.js
```
The server communicates over stdio using the MCP protocol.
## MCP Tools
| Tool | Description |
|------|-------------|
| `run_test_plan` | Execute a `.jmx` test plan in non-GUI mode and return a results summary |
| `get_test_results` | Parse and summarize a `.jtl` or `.csv` results file |
| `list_test_plans` | Find all `.jmx` files in a directory (optionally recursive) |
| `inspect_test_plan` | Parse a `.jmx` file and return its structure (thread groups, samplers, assertions) |
| `compare_results` | Compare two result files and show performance metric differences |
### Tool Examples
**Run a test plan with custom parameters:**
```json
{
"tool": "run_test_plan",
"arguments": {
"testPlanPath": "/home/user/tests/api-load-test.jmx",
"threads": 100,
"duration": 60,
"rampUp": 10,
"properties": {
"server": "api.example.com",
"port": "8080"
}
}
}
```
**Get detailed test results:**
```json
{
"tool": "get_test_results",
"arguments": {
"resultsPath": "/tmp/jmeter-results-1234567890.jtl",
"detailed": true
}
}
```
**Compare two test runs:**
```json
{
"tool": "compare_results",
"arguments": {
"baselinePath": "/tmp/baseline-results.jtl",
"currentPath": "/tmp/current-results.jtl"
}
}
```
## Tech Stack
| Library | Version | Purpose |
|---------|---------|---------|
| [TypeScript](https://www.typescriptlang.org/) | ^5.7 | Language — strict mode, ES2022 target, ESM modules |
| [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) | ^1.12 | MCP server SDK — `McpServer` high-level API with stdio transport |
| [Zod](https://zod.dev/) | ^3.24 | Schema validation for MCP tool parameters |
| [csv-parse](https://csv.js.org/parse/) | ^5.6 | Parse JMeter `.jtl` / `.csv` result files |
| [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | ^4.5 | Parse JMeter `.jmx` test plan XML files |
| [dotenv](https://github.com/motdotla/dotenv) | ^17.3 | Load environment variables from `.env` files |
| [Vitest](https://vitest.dev/) | ^4.0 | Test framework (dev dependency) |
## Development
```bash
npm run dev # Watch mode — recompiles on changes
npm run build # One-time TypeScript compilation
npm test # Run all tests
npx vitest run src/test/services/JMeterService.test.ts # Run a single test file
```
## Project Structure
```
src/
├── index.ts # Entry point: config → server → stdio transport
├── server.ts # McpServer creation + tool registration wiring
├── config.ts # Environment config loader (JMETER_HOME)
├── types/index.ts # Shared interfaces (JtlRecord, OverallStats, AppConfig)
├── tools/
│ ├── testPlan.ts # run_test_plan, list_test_plans, inspect_test_plan
│ └── results.ts # get_test_results, compare_results
├── services/
│ └── JMeterService.ts # Business logic: CLI execution, JTL/XML parsing
├── utils/
│ └── stats.ts # percentile(), diffPercent() helpers
└── test/
├── config.test.ts
└── services/
└── JMeterService.test.ts
```
## License
MIT