.cursor/skills/performance-testing-workflow/SKILL.md
End-to-end performance testing pipeline orchestrating BlazeMeter, Datadog, PerfAnalysis, PerfReport, and Confluence MCP workflows sequentially. Use when the user mentions performance testing workflow, E2E pipeline, BlazeMeter results, test run analysis, performance report generation, or end-to-end test processing.
npx skillsauth add canyonlabz/mcp-perf-suite performance-testing-workflowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This section provides context for humans and capable models. For the step-by-step execution instructions, skip to the Execution section below.
Orchestrates the complete performance testing pipeline from retrieving BlazeMeter/JMeter test results through publishing reports to Confluence. It coordinates multiple MCP workflows sequentially, ensuring data flows correctly between each step.
The pipeline executes in this order:
Each workflow can also be run independently if needed (e.g., running Datadog workflow days after test completion).
Variables that must be passed between workflows:
| Variable | Source | Destination |
|----------|--------|-------------|
| run_id | User input | All workflows |
| start_time | BlazeMeter get_run_results | Datadog workflow |
| end_time | BlazeMeter get_run_results | Datadog workflow |
| environment | User input | Datadog, PerfAnalysis, PerfReport |
| sessionsId | BlazeMeter get_run_results | BlazeMeter process_session_artifacts |
| space_ref | Confluence list_spaces | Confluence create_page |
| parent_id | Confluence get_page_by_id / list_pages | Confluence create_page |
| page_ref | Confluence create_page | Confluence attach_images, update_page |
| Tool | Purpose | Key Parameters |
|------|---------|---------------|
| get_run_results | Get test run results, extract start/end times and sessionsId | test_run_id |
| get_artifacts_path | Get local artifact storage path | run_id |
| process_session_artifacts | Download, extract, and process session artifacts | run_id, sessions_id_list |
| get_public_report | Get public BlazeMeter report URL | test_run_id |
| get_aggregate_report | Get aggregate performance report CSV | test_run_id |
| Tool | Purpose | Key Parameters |
|------|---------|---------------|
| load_environment | Load environment config (host-based or k8s-based) | env_name |
| get_host_metrics | Get CPU/Memory metrics for host-based environments | run_id, env_name, start_time, end_time |
| get_kubernetes_metrics | Get CPU/Memory metrics for k8s-based environments | run_id, env_name, start_time, end_time |
| get_logs | Get logs from Datadog | run_id, env_name, query_type, start_time, end_time |
| get_apm_traces | Get APM traces from Datadog | run_id, env_name, query_type, start_time, end_time |
| get_kpi_timeseries | Get custom KPI metrics (optional) | env_name, query_names (list), start_time, end_time, run_id, scope (optional) |
| Tool | Purpose | Key Parameters |
|------|---------|---------------|
| analyze_test_results | Analyze BlazeMeter test results | test_run_id |
| analyze_environment_metrics | Analyze Datadog infrastructure metrics | test_run_id, environment |
| correlate_test_results | Cross-correlate BlazeMeter and Datadog data | test_run_id |
| analyze_logs | Analyze JMeter/BlazeMeter and Datadog logs | test_run_id |
| identify_bottlenecks | Bottleneck analysis and concurrency threshold detection | test_run_id |
| Tool | Purpose | Key Parameters |
|------|---------|---------------|
| create_performance_test_report | Generate performance report (MD/PDF/DOCX) | run_id, template (optional), format |
| list_chart_types | List available chart options and chart_id values | — |
| create_chart | Create a chart image (PNG) | run_id, chart_id, env_name (for infra charts) |
| Tool | Purpose | Key Parameters |
|------|---------|---------------|
| list_spaces | List Confluence spaces | mode |
| get_space_details | Get space metadata | space_ref, mode |
| get_page_by_id | Look up page by ID | page_id, mode |
| list_pages | List pages in a space (search by name) | space_ref, mode |
| get_available_reports | List available reports for a test run | test_run_id |
| create_page | Create Confluence page from Markdown report | space_ref, test_run_id, filename, mode, parent_id, report_type |
| attach_images | Attach chart PNGs to a page | page_ref, test_run_id, mode, report_type |
| update_page | Replace chart placeholders with embedded images | page_ref, test_run_id, mode, report_type |
| Tool | Purpose | Key Parameters |
|------|---------|---------------|
| analyze_jmeter_log | Analyze JMeter log for errors and issues | test_run_id, log_source |
The report_type parameter determines artifact paths for Confluence publishing:
"single_run" — Individual test run reports (this workflow)
artifacts/{test_run_id}/reports/artifacts/{test_run_id}/charts/"comparison" — Comparison reports (see .cursor/skills/comparison-report-workflow/SKILL.md)
artifacts/comparisons/{comparison_id}/artifacts/comparisons/{comparison_id}/charts/prerequisites.mdc — test_run_id and artifact structure validationskill-execution-rules.mdc — Follow steps in order, collect inputs first, do not skipmcp-error-handling.mdc — MCP tool error handling (retry policy, reporting format)After completing this workflow, the user can proceed to:
.cursor/skills/report-revision-workflow/SKILL.md
Iterative AI-assisted revision of report sections (executive summary, key observations,
issues table) with version tracking..cursor/skills/comparison-report-workflow/SKILL.md
Multi-run comparison report with comparison charts and Confluence publishing.
Requires the E2E workflow to have completed for each individual test run first.Follow these steps exactly, in order. Each step has one or more actions.
Ask the user for the following values. Do not proceed until all required values are collected.
REQUIRED:
test_mode = [single test run or multiple test runs]
run_id = [for each test run — e.g., "7654321"]
env_name = [environment name — e.g., "QA", "UAT"]
OPTIONAL:
test_name = [informational label for the test run]
env_type = [for validation — "Hosts-based" or "Kubernetes-based"]
CONDITIONAL (only if publishing to Confluence):
confluence_mode = ["cloud" or "onprem"]
confluence_space = [space name — e.g., "Quality Engineering"]
parent_page_name = [e.g., "AI Generated Test Reports"]
parent_page_id = [optional — e.g., "123456789"]
If the user provides Confluence information, assume they want to publish results.
Input: run_id(s), workflow list
Action: For each test run, create granular task items to monitor progress:
Update task status as each step completes. This allows resuming if context is lost.
Prerequisites: run_id collected from user.
For each test run, process sequentially (Run 1 complete -> Run 2).
get_run_results(
test_run_id = {run_id}
)
Save:
start_time = extracted from the test run resultsend_time = extracted from the test run resultssessionsId = list of session IDs from the responseIf start/end times cannot be extracted, fall back to extracting from the aggregate report in step 2e.
get_artifacts_path(
run_id = {run_id}
)
Save: artifacts_path from the response.
process_session_artifacts(
run_id = {run_id},
sessions_id_list = {sessionsId}
)
This single tool handles downloading, extracting, and processing all session artifacts:
test-results.csv and jmeter.logtest-results.csv and jmeter-1.log through jmeter-N.log"partial" or "error", re-run with the same parameters.
It skips completed sessions and retries only failed ones.get_public_report(
test_run_id = {run_id}
)
Save: public_url from the response.
Action: Save the returned URL to artifacts/{run_id}/blazemeter/public_report.json:
{"run_id": "{run_id}", "public_url": "{url}", "public_token": "{token}"}
This enables PerfReport to include a direct link to the BlazeMeter report.
get_aggregate_report(
test_run_id = {run_id}
)
When: Only if the JMeter MCP server is available.
analyze_jmeter_log(
test_run_id = {run_id},
log_source = "blazemeter"
)
Discovers all .log files in artifacts/{run_id}/blazemeter/ automatically.
Output files are used downstream by PerfAnalysis and PerfReport.
If the JMeter MCP server is not available, skip this step.
Verify these files exist before proceeding:
artifacts/{run_id}/blazemeter/aggregate_performance_report.csvartifacts/{run_id}/blazemeter/test-results.csvartifacts/{run_id}/blazemeter/jmeter.log (single-session) OR artifacts/{run_id}/blazemeter/jmeter-*.log (multi-session)artifacts/{run_id}/blazemeter/sessions/session_manifest.jsonOn error: If API calls fail, retry up to 3 times. If retries fail, stop and report. Do not proceed to the next workflow if BlazeMeter fails.
Save forward:
run_id -> all downstream workflowsstart_time -> Datadog workflowend_time -> Datadog workflowUpdate task tracking: Mark all BlazeMeter steps as completed.
Prerequisites:
env_name provided by the userrun_id from BlazeMeter workflowstart_time and end_time from BlazeMeter workflowDo not proceed until all prerequisites are met.
load_environment(
env_name = {env_name}
)
This automatically loads the complete environment configuration, identifies the environment type (host-based or k8s-based), and loads all resources with CPU/Memory specs.
Save: env_type = host-based or k8s-based from the response.
Decision gate — choose based on env_type:
If host-based:
get_host_metrics(
run_id = {run_id},
env_name = {env_name},
start_time = {start_time},
end_time = {end_time}
)
If k8s-based:
get_kubernetes_metrics(
run_id = {run_id},
env_name = {env_name},
start_time = {start_time},
end_time = {end_time}
)
Metrics pulled should be CPU and Memory only.
get_logs(
run_id = {run_id},
env_name = {env_name},
query_type = {query_type},
start_time = {start_time},
end_time = {end_time}
)
Log query types: "warnings", "all_errors", "api_errors", "service_errors",
"host_errors", "kubernetes_errors", or "custom".
Custom log queries are defined in datadog-mcp/custom_queries.json using "Keys" for query_type.
get_apm_traces(
run_id = {run_id},
env_name = {env_name},
query_type = {query_type},
start_time = {start_time},
end_time = {end_time}
)
APM query types: "all_errors", "service_errors", "http_500_errors", "http_errors",
"slow_requests", or "custom".
Custom APM queries are defined in datadog-mcp/custom_queries.json using "Keys" for query_type.
When: Only if the user provides a list of custom KPI query names.
get_kpi_timeseries(
env_name = {env_name},
query_names = {list of query group keys},
start_time = {start_time},
end_time = {end_time},
run_id = {run_id},
scope = {scope}
)
query_names is a list of query group keys from the "kpi_queries" section in
datadog-mcp/custom_queries.json (e.g., ["cpu_usage", "memory_pressure"]).scope is optional ("host" or "k8s"). If omitted, it is auto-detected from the
loaded environment configuration.{{service_name}}, {{env_tag}})
or hard-coded.Verify these files exist before proceeding:
artifacts/{run_id}/datadog/host_metrics_*.csv OR artifacts/{run_id}/datadog/k8s_metrics_*.csvartifacts/{run_id}/datadog/logs_*.csv (optional)artifacts/{run_id}/datadog/kpi_metrics_*.csv (optional)On error: If API calls fail, retry up to 3 times. If retries fail, stop and report. Do not proceed to the next workflow if Datadog fails.
Save forward:
run_id -> all downstream workflowsenv_name -> PerfAnalysis and PerfReport workflowsUpdate task tracking: Mark all Datadog steps as completed.
Prerequisites:
test_run_id = same as BlazeMeter run_idenvironment = same as Datadog env_nameartifacts/{test_run_id}/blazemeter/aggregate_performance_report.csv)artifacts/{test_run_id}/datadog/host_metrics_*.csv or k8s_metrics_*.csv)Do not proceed until both BlazeMeter and Datadog workflows have completed successfully.
analyze_test_results(
test_run_id = {test_run_id}
)
This must run BEFORE steps 4b and 4c.
Requires: artifacts/{test_run_id}/blazemeter/aggregate_performance_report.csv
analyze_environment_metrics(
test_run_id = {test_run_id},
environment = {environment}
)
Requires: artifacts/{test_run_id}/datadog/host_metrics_*.csv or k8s_metrics_*.csv
correlate_test_results(
test_run_id = {test_run_id}
)
Requires: Outputs from steps 4a and 4b must be completed first.
analyze_logs(
test_run_id = {test_run_id}
)
Requires:
artifacts/{test_run_id}/blazemeter/jmeter.log (single-session) OR jmeter-*.log (multi-session)artifacts/{test_run_id}/datadog/logs_*.csvidentify_bottlenecks(
test_run_id = {test_run_id}
)
Performs bottleneck analysis and identifies the concurrency threshold where degradation begins.
Requires: artifacts/{test_run_id}/blazemeter/test-results.csv
Optional: artifacts/{test_run_id}/datadog/k8s_metrics_*.csv, host_metrics_*.csv, or kpi_metrics_*.csv
Verify these files exist before proceeding:
artifacts/{run_id}/analysis/performance_analysis.jsonartifacts/{run_id}/analysis/infrastructure_analysis.jsonartifacts/{run_id}/analysis/correlation_analysis.jsonartifacts/{run_id}/analysis/log_analysis.jsonartifacts/{run_id}/analysis/blazemeter_log_analysis.jsonartifacts/{run_id}/analysis/bottleneck_analysis.jsonartifacts/{run_id}/analysis/kpi_analysis.jsonOn error: These are Python code executions (not API calls). Do NOT retry. Report the error with: error message, missing file paths, expected vs. actual structure. Do NOT attempt to fix code or modify files. Stop and report to user.
Save forward:
run_id -> PerfReport workflowenv_name -> PerfReport workflowUpdate task tracking: Mark all PerfAnalysis steps as completed.
Prerequisites:
run_id = same as PerfAnalysis test_run_idenv_name = same as used in Datadog and PerfAnalysis (required for infrastructure charts)artifacts/{run_id}/analysis/performance_analysis.json,
infrastructure_analysis.json, correlation_analysis.json)Do not proceed until PerfAnalysis has completed successfully.
create_performance_test_report(
run_id = {run_id},
template = {template},
format = "md"
)
"md"), but can also generate PDF ("pdf") or Word ("docx").artifacts/{run_id}/reports/report_metadata_{run_id}.json
for the template_used field and pass that value as template to maintain consistency.default_report_template.md.list_chart_types()
This identifies the correct chart_id values for chart creation.
create_chart(
run_id = {run_id},
chart_id = "CPU_CORES_LINE",
env_name = {env_name}
)
create_chart(
run_id = {run_id},
chart_id = "MEMORY_USAGE_LINE",
env_name = {env_name}
)
These line charts show CPU and Memory utilization for all hosts/services.
Output: CPU_CORES_LINE-{resource-name}.png, MEMORY_USAGE_LINE-{resource-name}.png
create_chart(
run_id = {run_id},
chart_id = "RESP_TIME_P90_VUSERS_DUALAXIS"
)
This dual-axis chart shows correlation between P90 response time and virtual users over time.
Output: RESP_TIME_P90_VUSERS_DUALAXIS.png
Verify these files exist before proceeding:
artifacts/{run_id}/reports/performance_report_{run_id}.mdartifacts/{run_id}/charts/*.png (at least CPU, Memory, and P90 charts)On error: These are Python code executions (not API calls). Do NOT retry. Report the error with: error message, missing file paths, expected vs. actual structure. Do NOT attempt to fix code or modify files. Stop and report to user.
Save forward:
run_id -> Confluence workflow (if applicable)Update task tracking: Mark all PerfReport steps as completed.
When: Only execute if Confluence details were provided in Collect Inputs.
Prerequisites:
test_run_id = same as PerfReport run_idconfluence_mode = "cloud" or "onprem"confluence_space = space name from userparent_page_name or parent_page_id from userartifacts/{test_run_id}/reports/*.md)Do not proceed until all prerequisites are met and PerfReport has completed.
list_spaces(
mode = {confluence_mode}
)
Search for the space matching confluence_space. Extract space_ref (space_id for cloud,
space_key for onprem).
get_space_details(
space_ref = {space_ref},
mode = {confluence_mode}
)
Decision gate:
If parent_page_id is provided:
get_page_by_id(
page_id = {parent_page_id},
mode = {confluence_mode}
)
If parent_page_name is provided:
list_pages(
space_ref = {space_ref},
mode = {confluence_mode}
)
Search results for the page matching parent_page_name.
Save: parent_id = the parent page ID for use in step 6e.
get_available_reports(
test_run_id = {test_run_id}
)
Select the report filename to publish (typically performance_report_{test_run_id}.md).
Save: report_filename from the selected report.
create_page(
space_ref = {space_ref},
test_run_id = {test_run_id},
filename = {report_filename},
mode = {confluence_mode},
parent_id = {parent_id},
report_type = "single_run",
title = {optional custom title}
)
The tool converts Markdown to Confluence XHTML and creates the page nested under the parent. If no title is provided, the title is extracted from the Markdown H1 heading.
Save: page_ref = returned page ID for use in steps 6f and 6g.
attach_images(
page_ref = {page_ref},
test_run_id = {test_run_id},
mode = {confluence_mode},
report_type = "single_run"
)
Uploads ALL PNG chart images from artifacts/{test_run_id}/charts/ to the page.
Check response for attached/failed counts. Continue even if some fail.
update_page(
page_ref = {page_ref},
test_run_id = {test_run_id},
mode = {confluence_mode},
report_type = "single_run"
)
Replaces {{CHART_PLACEHOLDER: ID}} markers with embedded <ac:image> markup.
Check response for placeholders_replaced and placeholders_remaining.
Note on report_type:
report_type: "single_run" for individual test run reports.report_type: "comparison" with comparison_id as the
test_run_id. See .cursor/skills/comparison-report-workflow/SKILL.md for the
comparison Confluence flow.Verify:
page_ref and URL in create_page response)attach_images status: "success" or "partial")update_page placeholders_replaced list)On error: If API calls fail, retry up to 3 times. If retries fail, report error but continue (do not block other runs).
Update task tracking: Mark all Confluence steps as completed.
Input: All data collected throughout the workflow.
Action: After all test runs are processed, generate a comprehensive summary.
For each test run, list all generated artifacts:
artifacts/{run_id}/blazemeter/artifacts/{run_id}/datadog/artifacts/{run_id}/analysis/artifacts/{run_id}/reports/artifacts/{run_id}/charts/For each test run, provide aggregate metrics in a table:
BlazeMeter Metrics:
Datadog Infrastructure Metrics:
Do not include per-API breakdowns, only aggregate metrics.
If multiple test runs were processed, provide a side-by-side comparison table:
Action: Display final task tracking status:
Ask the user:
.cursor/skills/report-revision-workflow/SKILL.md..cursor/skills/comparison-report-workflow/SKILL.md.These rules apply to every step:
API-based workflows (BlazeMeter, Datadog, Confluence):
Code-based workflows (PerfAnalysis, PerfReport):
Sequential execution: Do not proceed to the next workflow if the current one fails.
Multiple test runs: Process sequentially. Complete Run 1 fully before starting Run 2.
Do NOT write code to fix MCP tool issues.
Ask the user for next steps on any unrecoverable failure.
testing
Orchestrates BlazeMeter and Datadog data extraction using dedicated subagents. Use when the user mentions subagent workflow, subagent orchestrator, or wants to run the BlazeMeter and Datadog extraction phases via subagents. This skill handles the extraction and handoff phases only — it does NOT run PerfAnalysis, PerfReport, or Confluence. After this skill completes, the user can continue with the performance-testing-workflow skill starting from Step 4 (PerfAnalysis).
testing
AI-assisted HITL revision of performance test reports with iterative refinement, version tracking, and optional Confluence publishing. Use when the user mentions report revision, AI-enhanced report, revise executive summary, revise key observations, revise issues table, or improve a performance report.
tools
Run Playwright browser automation to capture network traffic and generate a JMeter JMX script. Use when the user mentions browser automation, Playwright recording, test spec execution, browser-based network capture, or generating a JMeter script from a live browser session.
development
Manage the PerfMemory lessons-learned layer — search for past fixes before debugging, store debug sessions and attempts during debugging, and ingest existing knowledge from debug manifests or lessons-learned documents. Use when the user mentions perfmemory, lessons learned, debug memory, ingesting debug manifests, or searching for past fixes.