agentleFS
canyonlabzcanyonlabz/perfpilot-hub/.cursor/skills/jmeter-hitl-editing/SKILL.md

jmeter-hitl-editing

Skill5 starsChanged 6 months agoMITView on GitHub

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.

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 9 are distinctive, and 10 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 10

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Check variables.undefined for missing variable definitions

    line 77
  2. Very specific:

    Use edit_jmeter_component with replace_in_body to swap hardcoded values

    line 78
  3. Very specific:

    Add a csv_dataset or user_defined_variables component to define new variables

    line 79
  4. Very specific:

    Add constant_timer or flow_control_action as last child of each controller

    line 83
  5. Very specific:

    After headless execution, these files are written to artifacts/{test_run_id}/jmeter/:

    line 94
  6. Distinctive:

    Follow the phases below, but Steps 3-4 repeat as many times as the user needs.

    line 109
  7. Distinctive:

    Ask the user for the following values.

    line 115
  8. Distinctive:

    When: Only if the user is importing an external JMX file not already in the artifacts folder.

    line 130
  9. Very specific:

    Create directory artifacts/{test_run_id}/jmeter/ if it does not exist

    line 135
  10. Distinctive:

    Skip this step: if the JMX already exists in the artifacts folder.

    line 140
  11. Very specific:

    Action: Call MCP tool analyze_jmeter_script

    line 148
  12. Very specific:

    On error: If status is "ERROR", stop.

    line 185
  13. Very specific:

    Action: Call MCP tool analyze_jmeter_script to refresh the persisted structure files with the latest node_ids after edits.

    line 253
  14. Distinctive:

    When: Only if the user wants to run the script locally to validate it.

    line 276
  15. Distinctive:

    When: Only if the user wants to analyze test results with PerfAnalysis.

    line 328
  16. Distinctive:

    Always analyze the script before any add/edit operation.

    line 344
  17. Very specific:

    Always use dry_run=true first, then dry_run=false to apply.

    line 345
  18. Distinctive:

    If any MCP tool returns an error status, stop and report to the user.

    line 346
  19. Distinctive:

    Do NOT write code to fix MCP tool issues.

    line 347

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

ToolPurposeKey Parameters
analyze_jmeter_scriptGet 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_typesDiscover available component typescategory (optional filter)
add_jmeter_componentAdd a new component to the scripttest_run_id, component_type, parent_node_id, component_config, position, dry_run
edit_jmeter_componentEdit an existing componenttest_run_id, target_node_id, operations, dry_run
list_jmeter_scriptsList JMX scripts for a test runtest_run_id
start_jmeter_testRun a headless JMeter testtest_run_id, jmx_path
stop_jmeter_testStop a JMeter testtest_run_id
get_jmeter_run_statusPoll running test for metricstest_run_id, pid
generate_aggregate_reportGenerate aggregate CSV reporttest_run_id
analyze_jmeter_logAnalyze a JMeter log for test execution errorstest_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:

  1. Analyze script to get all HTTPSamplerProxy node_ids
  2. For each sampler, add a response_assertion checking for status 200

Parameterize hardcoded values:

  1. Analyze with detail_level="full" to see element properties
  2. Check variables.undefined for missing variable definitions
  3. Use edit_jmeter_component with replace_in_body to swap hardcoded values
  4. Add a csv_dataset or user_defined_variables component to define new variables

Add think time between steps:

  1. Analyze to get controller node_ids
  2. 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/:

FilePurpose
test-results.csvRaw sample data (JTL)
{test_run_id}_aggregate_report.csvPer-label aggregate stats
results_tree.csvDetailed sample data (JMeter built-in)
aggregate_report.csvAggregate data (JMeter built-in)
{test_run_id}.logJMeter 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:

  1. Create directory artifacts/{test_run_id}/jmeter/ if it does not exist
  2. 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.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.