| name | jmeter-hitl-editing |
| description | AI-assisted Human-in-the-Loop JMeter script analysis, component addition, editing, and headless smoke testing. Use when the user wants to analyze, edit, add components to, import, or modify a JMeter JMX script, or run a local JMeter smoke test. |
JMeter HITL (Human-in-the-Loop) Editing
When to Use This Skill
- User wants to analyze the structure of a JMeter JMX script
- User wants to add components (extractors, assertions, timers, etc.) to a JMX script
- User wants to edit existing components (rename, set properties, replace values)
- User wants to import an external JMX script into the artifacts folder
- User wants to run a headless JMeter smoke test to validate a script
Reference
This section provides context for humans and capable models. For the step-by-step
execution instructions, skip to the Execution section below.
How HITL Editing Works
The HITL tools work on any valid JMX script, regardless of how it was created:
- JMeter GUI, BlazeMeter export, third-party tool, CI/CD pipeline
- Generated by mcp-perf-suite (Playwright, HAR, or Swagger workflows)
The workflow is interactive and user-directed, not a fixed linear pipeline. The user
tells the agent what to analyze, add, or edit. The agent executes using the HITL MCP tools.
Script Sources
A JMX script can arrive in the artifacts folder from any of these sources:
- External / Pre-existing JMX — User provides a path to an existing JMX file.
Copy it into
artifacts/{test_run_id}/jmeter/ with an imported_ prefix.
- Playwright browser automation — Follow the skill at
.cursor/skills/playwright-browser-automation/SKILL.md.
- HAR file conversion — Follow the skill at
.cursor/skills/jmeter-har-conversion/SKILL.md.
- Swagger/OpenAPI conversion — Follow the skill at
.cursor/skills/jmeter-swagger-conversion/SKILL.md.
Tool Reference
| Tool | Purpose | Key Parameters |
|---|
analyze_jmeter_script | Get script structure and node IDs. Exports versioned structure files to disk. | test_run_id, jmx_filename, detail_level, export_structure, output_format |
list_jmeter_component_types | Discover available component types | category (optional filter) |
add_jmeter_component | Add a new component to the script | test_run_id, component_type, parent_node_id, component_config, position, dry_run |
edit_jmeter_component | Edit an existing component | test_run_id, target_node_id, operations, dry_run |
list_jmeter_scripts | List JMX scripts for a test run | test_run_id |
start_jmeter_test | Run a headless JMeter test | test_run_id, jmx_path |
stop_jmeter_test | Stop a JMeter test | test_run_id |
get_jmeter_run_status | Poll running test for metrics | test_run_id, pid |
generate_aggregate_report | Generate aggregate CSV report | test_run_id |
analyze_jmeter_log | Analyze a JMeter log for test execution errors | test_run_id, log_source (e.g. "jmeter"/"blazemeter") |
Edit Operations
The edit_jmeter_component tool supports these operations:
{"op": "rename", "value": "New Name"} — Rename a component
{"op": "set_prop", "name": "property_name", "value": "new_value"} — Set a property
{"op": "replace_in_body", "old": "find_this", "new": "replace_with"} — Replace text in body
{"op": "toggle_enabled"} — Enable or disable a component
Common HITL Patterns
Add assertions to all samplers:
- Analyze script to get all HTTPSamplerProxy node_ids
- For each sampler, add a
response_assertion checking for status 200
Parameterize hardcoded values:
- Analyze with
detail_level="full" to see element properties
- Check
variables.undefined for missing variable definitions
- Use
edit_jmeter_component with replace_in_body to swap hardcoded values
- Add a
csv_dataset or user_defined_variables component to define new variables
Add think time between steps:
- Analyze to get controller node_ids
- Add
constant_timer or flow_control_action as last child of each controller
Related Rules
prerequisites.mdc — test_run_id and artifact structure validation
skill-execution-rules.mdc — Follow steps in order, collect inputs first
mcp-error-handling.mdc — MCP tool error handling (retry policy, reporting)
jmeter-script-guardrails.mdc — Smoke test = 1/1/1, dry run first, analyze before edit
Execution Output Files
After headless execution, these files are written to artifacts/{test_run_id}/jmeter/:
| File | Purpose |
|---|
test-results.csv | Raw sample data (JTL) |
{test_run_id}_aggregate_report.csv | Per-label aggregate stats |
results_tree.csv | Detailed sample data (JMeter built-in) |
aggregate_report.csv | Aggregate data (JMeter built-in) |
{test_run_id}.log | JMeter execution log |
Execution
This is an interactive workflow. The user directs what to analyze, add, or edit.
Follow the phases below, but Steps 3-4 repeat as many times as the user needs.
Collect Inputs
Ask the user for the following values. Do not proceed until all required values are collected.
REQUIRED:
test_run_id = [ask user]
CONDITIONAL:
jmx_source = [one of: "external", "already exists", "generate from HAR/Swagger/Playwright"]
jmx_path = [required if jmx_source is "external" — full path to the JMX file]
Step 1 — Import External JMX (if needed)
When: Only if the user is importing an external JMX file not already in the artifacts folder.
Input: test_run_id, jmx_path
Action:
- Create directory
artifacts/{test_run_id}/jmeter/ if it does not exist
- Copy (do NOT move) the JMX file to
artifacts/{test_run_id}/jmeter/imported_{filename}.jmx
Save: jmx_filename = imported_{filename}.jmx
Skip this step if the JMX already exists in the artifacts folder.
Step 2 — Analyze the Script
Input: test_run_id, jmx_filename (optional — auto-discovers if not provided)
Action: Call MCP tool analyze_jmeter_script
analyze_jmeter_script(
test_run_id = {test_run_id},
jmx_filename = {jmx_filename},
detail_level = "detailed"
)
Expected MCP response (summary only):
{
"status": "OK",
"test_run_id": "{test_run_id}",
"jmx_path": "artifacts/{test_run_id}/jmeter/...",
"jmx_filename": "...",
"summary": { "total_elements": 142, "by_type": { "..." } },
"outline": "- [ThreadGroup] TC01_Thread_Group (id: a1b2c3d4e5)\n ...",
"exported_files": {
"json": "artifacts/{test_run_id}/jmeter/analysis/jmx_structure_<timestamp>.json",
"markdown": "artifacts/{test_run_id}/jmeter/analysis/jmx_structure_<timestamp>.md"
}
}
Important: The MCP response does NOT include the full hierarchy, node_index,
or variables. These are in the exported JSON file on disk.
Save from the MCP response: exported_files, outline, summary.
Read the exported JSON file at exported_files.json to obtain:
node_index — all components with their node_id values (needed for add/edit)
hierarchy — the nested script structure
variables — defined, used, and undefined variables
On error: If status is "ERROR", stop. Report the error to the user.
Present the outline and key findings to the user. Ask what they want to add or edit.
Step 3 — Add or Edit Components (user-directed, repeatable)
This step repeats as many times as the user needs. Each cycle follows the same pattern.
To Add a Component:
Input: test_run_id, parent_node_id (from Step 2), user's request
Action: First, preview with dry run:
add_jmeter_component(
test_run_id = {test_run_id},
component_type = {type from user request or list_jmeter_component_types},
parent_node_id = {parent_node_id},
component_config = {config based on user request},
position = "last",
dry_run = true
)
Review the dry run output with the user. If approved, apply:
add_jmeter_component(
...same parameters...,
dry_run = false
)
To Edit a Component:
Input: test_run_id, target_node_id (from Step 2), user's request
Action: First, preview with dry run:
edit_jmeter_component(
test_run_id = {test_run_id},
target_node_id = {target_node_id},
operations = [ {"op": "...", ...} ],
dry_run = true
)
Review the dry run output with the user. If approved, apply:
edit_jmeter_component(
...same parameters...,
dry_run = false
)
After every applied change: Go to Step 4 to re-analyze.
Step 4 — Re-Analyze After Edits
Input: test_run_id
Action: Call MCP tool analyze_jmeter_script to refresh the persisted structure
files with the latest node_ids after edits.
analyze_jmeter_script(
test_run_id = {test_run_id},
detail_level = "detailed"
)
Verify the script structure is correct after the edit using the outline and
summary from the response.
Save: exported_files (refreshed structure files). Read the new exported JSON
file at exported_files.json to get the updated node_index — node IDs may have
changed after edits.
Ask the user: "Do you want to make more changes?" — If yes, go back to Step 3.
Step 5 — Headless Smoke Test (optional)
When: Only if the user wants to run the script locally to validate it.
Critical: Smoke tests MUST use 1 thread, 1 second ramp-up, 1 loop. If the
Thread Group has higher values, override to 1/1/1 before running.
5a. List Scripts
list_jmeter_scripts(
test_run_id = {test_run_id}
)
Save: jmx_path from the scripts list.
5b. Start Test
start_jmeter_test(
test_run_id = {test_run_id},
jmx_path = {jmx_path}
)
Save: pid from the response.
5c. Monitor Until Complete
Poll get_jmeter_run_status every few seconds until the test finishes:
get_jmeter_run_status(
test_run_id = {test_run_id},
pid = {pid}
)
5d. Generate Report
generate_aggregate_report(
test_run_id = {test_run_id}
)
Present the results to the user. If errors are found and the user wants to debug,
follow the debugging skill at .cursor/skills/jmeter-debugging/SKILL.md.
Step 6 — Downstream Analysis (optional)
When: Only if the user wants to analyze test results with PerfAnalysis.
analyze_test_results(
test_run_id = {test_run_id}
)
The PerfAnalysis MCP will find test-results.csv in the jmeter/ folder.
Error Handling
These rules apply to every step:
- Always analyze the script before any add/edit operation.
- Always use
dry_run=true first, then dry_run=false to apply.
- If any MCP tool returns an error status, stop and report to the user.
- Do NOT write code to fix MCP tool issues.
- Advise the user to close JMeter GUI during HITL edits to prevent file conflicts.