This file enumerates every item deferred to v0.2 (or later) during the v0.1.0 pre-public review. Open each as a GitHub issue immediately after the repo flips public so they aren't lost.
Each block below is in gh issue create shape — copy-paste-ready once the repo URL is live.
Body:
deny.tomlignores three advisories, each justified in ADR 0011. Re-evaluate each release:
- RUSTSEC-2026-0002 (
lruIterMutStacked-Borrows unsoundness) — transitive viaratatui 0.29(lru ^0.12), only under the optionaltuifeature. Drop the ignore + bump onceratatuiships on patchedlru(≥0.13).- RUSTSEC-2025-0052 (
async-stddiscontinued) — dev-only viahttpmock. Drop whenhttpmockreleases withoutasync-std(or swap the mock).- RUSTSEC-2024-0436 (
pasteunmaintained) — transitive proc-macro. Drop when the dep tree moves offpaste(e.g.pastey). Action:cargo deny checkaftercargo update; if any becomes an actual vulnerability orlrureaches the default build, fix immediately rather than re-ignoring.
Labels: security, dependencies, chore
Body:
Currently the redirect policy is hardened to
Policy::none()per ADR 0007, but an operator pointing the load tester at a malicious URL can still hit any internal endpoint resolvable from the machine running the test. v0.2 should add an operator-facing allowlist (TOML config:server.allowed_hosts = ["app.example.com"]) and rejectconnect_async/reqwest::sendcalls when the resolved host isn't matched. See CHANGELOG[Unreleased]Notes.
Labels: security, enhancement, v0.2
Body:
Pre-publish Phase 1 audit found scenarios still deep-clone
Valueonce per worker spawn (the&Valuechange in commitc8dee52cut per-call clones, not per-worker setup). WrappingSustained.args/Pattern.argsetc. inArc<Value>lets concurrent workers share the JSON tree by reference. TouchesSession::call_toolsignature → breaking v0.2 API change.
Labels: performance, breaking, v0.2
Body:
extract_idparses the entire JSON twice (once for id-probe, once for full body after match). Usesimd-jsonor a streaming id-extractor (parse only the first"id":Nkey). Matters at >100K iter/s — not a v0.1 blocker.
Labels: performance, v0.2
Body:
stdio.rs::requestdoesself.line_buf.trim_end().to_string(). In-place truncate plus returning&strwould save one alloc per call. Small win at high call rates.
Labels: performance, v0.2
Body:
ColdStartis intentionally a placeholder in v0.1.0; the integration test pins the inert-placeholder contract. v0.2: implement real cold-start sampling (Session::reinitializeloop + per-iteration histogram) and replace the placeholder assertion with a measured-latency assertion.
Labels: test, feature, v0.2
Body:
DESIGN.md §16 lists 10 mock fixtures; v0.1 ships 6 (normal/slow/broken/crash/http/sse). The 4 missing fixtures gate richer scenario coverage:
mock-leak.py— RSS grows over time → exercisessoak::detect_leakmock-error.py— returns JSON-RPC errors deterministically → exercises error-classification scenariosmock-slow-init.py— slow initialize handshake → exercisescold_start(post-real-impl)mock-malformed.py— emits malformed JSON → exercises fuzzer's defensive parse paths Each is < 50 lines of stdlib-only Python following_common.py.
Labels: test, v0.2
Body:
Phase 1 added
benches/{record,histogram,session_loopback,hang_detect}.rs. v0.2: capture baseline numbers inbench-baseline.jsonand add acargo bench-checkCI step that flags regressions > 10% vs baseline (same threshold ascomparesubcommand).
Labels: test, ci, v0.2
Files where production code (excluding #[cfg(test)] mod tests) exceeds the 300-line convention. The bracketed numbers are production LoC / total LoC.
All 11 originally-flagged files now have production code under 300 lines. Splits landed across four commits in the pre-publish review:
- Wave 1:
scenario/soak.rs(358→196 viasoak/leak_detect.rs),report/html.rs(336→212 viahtml/{css,chart}.rs),scenario/spike.rs(331→217 viaspike/phase.rs). - Wave 2:
cmd_compare.rs(503→100 viacmd_compare/{types,diff,render}.rs),scenario/fuzzer.rs(488→277 viafuzzer/{payloads,classify}.rs),serve/tools.rs(509→130 viaserve/tools/{deadlock_probe,sustained_load,compare_runs}.rs). - Wave 3:
run.rs(447→293 viarun/thresholds.rs),metrics/mod.rs(426→<300 viametrics/{types,per_tool}.rs+ module-doc trim),config.rs(376→217 viaconfig/{validate,example}.rs),main.rs(434→208 viacmd_run.rs+cmd_deadlock.rs+emit.rs). - Wave 4 (trim):
metrics/mod.rs,scenario/soak.rs,serve/mod.rs— module-doc trim brought them under the 300 cap. sse.rs(311→263 viasse/reader.rs),cmd_cross.rs(322→189 viacmd_cross/render.rs).
Public API paths preserved via pub use re-exports throughout. 264 tests pass, cargo fmt --check + cargo clippy -D warnings clean.
Labels: — done.tech-debt
Body:
Fuzzercurrently skips raw-transport payloads (GiantPayloadraw variant, etc.) because there's no API to bypass JSON-RPC framing. v0.2: add araw_sendmethod to theTransporttrait that letsFuzzersend arbitrary bytes. Enables full coverage of the malformed-input attack surface.
Labels: feature, v0.2
Body:
Currently the spawned MCP server's stderr inherits the parent's stderr. When
mcp-loadtestruns as a child of an LLM agent, the target server's stderr blends into the agent's view. Add a flag to redirect to a per-run file (runs/<ulid>/server-stderr.log).
Labels: feature, v0.2
Body:
IBM's mcp-context-forge perf testing wanted Docker Compose multi-server setup. We have
crosswhich drives N servers but doesn't scaffold the compose file. Addmcp-loadtest cross --emit-compose > docker-compose.yml.
Labels: feature, v0.2
Body:
Current HTML reporter uses inline SVG (static, no JS). v0.2 could optionally embed Chart.js + interactive percentile sliders. Stays self-contained (
<script>block, no CDN). Trade: report file grows from ~20 KB to ~200 KB.
Labels: feature, enhancement, v0.2
Body:
Pre-publish review added ADRs 0005–0009. As v0.2 features land (host-allowlist, raw-byte transport, etc.) each architectural decision should get an ADR. Template: copy
docs/adr/0001-language-rust.md.
Labels: docs, process
Body:
Once v0.2 wires bench baselines into CI (above), the README can quote real numbers:
Recorder::record: 47 ns,Session::call_tool loopback: 8.2 µs, etc. Replaces the current "Rust performance" handwave.
Labels: docs, v0.2
Body:
The
repositoryandhomepagefields inCargo.tomlpoint athttps://github.com/Teerapat-Vatpitak/mcp-loadtest. The previous repo at that URL was deleted during pre-publish review. Before runningcargo publish, recreate the public repo at the same URL OR update both fields to the new URL.
Labels: release, process
Body:
Pre-publish checklist:
cargo publish --dry-run -p mcp-loadtest(lib first)cargo publish --dry-run -p mcp-loadtest-cli(then CLI)- Both should be clean (no warnings about missing fields, no API surface issues)
- After actual publish:
cargo install mcp-loadtest-clion a fresh shell to verify the binary works end-to-end
Status (pre-publish, 2026-05-16): steps 1–3 done — mcp-loadtest dry-run packages clean; mcp-loadtest-cli dry-run fails with "no matching package mcp-loadtest" which is the expected workspace publish-ordering constraint (publish the lib first, then the CLI), not a defect. Local release-build smoke (--version / list-scenarios / a strict run) passed. Step 4 (cargo install from crates.io) remains for after the real publish.
Labels: release, process