Skip to content

Latest commit

 

History

History
111 lines (82 loc) · 6.55 KB

File metadata and controls

111 lines (82 loc) · 6.55 KB

mcp-loadtest

Cross-platform load tester for MCP (Model Context Protocol) servers. Detects deadlocks, hangs, and perf regressions that unit tests miss.

Working with Claude (collaboration rules)

These rules govern how Claude works on this repo. They override Claude defaults.

🔒 Git discipline

  • Never git push (any remote, any branch) unless the user confirms it in the current message.
  • Never make the repo public. It stays private until the user explicitly says "ok to public".
  • Never git tag, create releases, or publish to crates.io without confirmation.
  • Never git push --force — also denied by .claude/settings.json.
  • Commits land locally without confirmation. Just announce big or risky commits before making them.
  • Do not add Co-Authored-By: Claude trailers in commit messages.

💬 Explain before doing

  • Briefly state the plan before destructive or multi-step actions (max ~5 lines).
  • Skip the explanation for trivial actions (single file read, lint check, one-line edit).
  • When intent is ambiguous, ask before guessing.

⚙️ Command + agent patterns

  • Slash commands chain through phases (e.g. /simplify/security-review/code-review/engineering:documentation).
  • For large multi-file work, split across parallel agents with disjoint file ownership — two agents must never edit the same file.
  • After all agents return, the orchestrator (main Claude session) runs cargo build + cargo clippy -D warnings + cargo test + cargo fmt to integrate.
  • Commit in logical groups (security: / fix: / test: / docs:) — not one large blob.

🏃 Run discipline

  • All testing, linting, and CI smoke runs locally on this machine only. Never trigger remote CI before push.
  • Test: cargo nextest run --workspace --all-features (fallback: cargo test).
  • Lint: cargo fmt --check && cargo clippy --workspace --all-targets -- -D warnings.
  • CI smoke (full): bash scripts/ci-checks.sh — Windows: pwsh scripts/ci-checks.ps1.
  • Build: prefer cargo build --workspace --all-targets to catch test-only breakage early.

🛑 Decision points — must ask before proceeding

  • Any git push (any remote, any branch).
  • Making the repo public, transferring ownership, or changing visibility.
  • git tag / publishing to crates.io / creating a GitHub Release.
  • Invasive refactors: splitting files over the 300-line convention, introducing cargo feature flags, renaming public API.
  • cargo update (and the lockfile commit it produces — must be its own commit).
  • Adding new top-level *.md files at the repo root.
  • Deleting any committed file or directory.

📝 What to write where

  • Codesrc/ of the relevant crate. Files < 300 lines (split when longer).
  • Unit tests#[cfg(test)] mod tests { } next to the code under test.
  • Integration testscrates/<crate>/tests/<name>.rs. Spawn fixtures via helpers::spawn_fixture, not std::process::Command.
  • Docs → don't add new top-level *.md without confirmation. Sub-docs under docs/ are fine.
  • CHANGELOG[Unreleased] must be updated for every user-visible change (new flag, behavior change, public API delta, deprecation).
  • ADRsdocs/adr/NNNN-title.md (next number) for any architectural decision; update docs/adr/README.md.

Quick commands

  • Test: cargo nextest run --workspace --all-features (fallback: cargo test --workspace --all-features)
  • Lint: cargo fmt --check && cargo clippy --workspace --all-targets -- -D warnings
  • CI check (full): bash scripts/ci-checks.sh — Windows: pwsh scripts/ci-checks.ps1
  • Bench: cargo bench -p mcp-loadtest
  • Run tool against a real MCP server: cargo run -p mcp-loadtest-cli -- deadlock-probe -s "python -m foo"

Where things live

  • Design: DESIGN.md — what we're building (20 sections, types/algorithms/test-matrix)
  • Project structure: PROJECT-STRUCTURE.md — how this repo is laid out
  • Decisions: docs/adr/ — append-only architecture decisions
  • Core library: crates/mcp-loadtest/src/
  • CLI: crates/mcp-loadtest-cli/src/
  • Mock fixtures: crates/mcp-loadtest/tests/fixtures/*.py

Conventions

  • Files < 300 lines of production code (in-file #[cfg(test)] mod tests blocks are excluded from the count — they stay co-located with the code they test per Rust idiom). Split production code if longer.
  • Errors: thiserror enums, never bare unwrap() in lib code (allowed in tests).
  • No panic!() outside tests. Use Result<T, RunError>.
  • Public API stable across 0.x per CHANGELOG. Breaking changes: bump minor, document.
  • No tokio::spawn(async move { ... }) without keeping the JoinHandle and observing cancellation.
  • Async paths must not call blocking I/O — use tokio::fs, tokio::process.
  • Tests prefer helpers::spawn_fixture(...) over raw std::process::Command.

How to add things

Want to add... Where / how
New scenario crates/mcp-loadtest/src/scenario/CLAUDE.md — or /new-scenario <name>
New mock fixture crates/mcp-loadtest/tests/fixtures/CLAUDE.md — or /new-mock <name>
New ADR docs/adr/NNNN-title.md (next number); update docs/adr/README.md
New CLI flag crates/mcp-loadtest-cli/src/main.rs clap struct; thread through to lib via Run builder

Don't

  • Don't run cargo update without committing the lock change in a separate commit.
  • Don't add #[allow(clippy::...)] without an inline // reason: ... comment.
  • Don't change public types in lib.rs without bumping CHANGELOG [Unreleased].
  • Don't introduce blocking I/O in async paths.
  • Don't push to main directly. PRs only.
  • Don't git push --force (denied by .claude/settings.json).

Pre-release

Run /release-checks before tagging. See .claude/commands/release-checks.md for what it does.

Status

  • v0.1.0 — tagged (v0.1.0a3ff6d4, annotated, pushed); CI green (368 tests); M1–M7 + post-M7 shipped
  • Distribution: cargo install --git + GitHub Release binaries; crates.io deferred (ADR 0015, amends ADR 0004)
  • Pending gate before release: repo → public, then Gate A–D in docs/RELEASE.md