Skip to main content
Glama

audit_code_resilience

Identify gaps in unit test coverage by running on-demand mutation testing against a source file. Surviving mutants reveal untested logic.

Instructions

Runs on-demand, sandbox-isolated mutation testing against a single source file to identify gaps in unit test coverage. Chaos-MCP generates mutants (logical faults like changing > to >=) and checks whether the local test suite catches them. Surviving mutants indicate test coverage holes. Supports TypeScript/JavaScript (StrykerJS), Python (cosmic-ray), Rust (cargo-mutants), and PHP (Infection). PATHS: filePath is resolved against the SERVER's working directory (or given absolute). The target in the result is relative to the audited file's own WORKSPACE, which differs whenever the file sits in a monorepo package or another root — packages/api/src/math.ts comes back as src/math.ts. When the two differ the result carries workspace (an absolute path) and join(workspace, target) is a filePath you can pass straight back; when it is absent, target already is one. A file from triage_test_coverage is always a valid filePath as-is.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
runIdNoVerify mode by id: re-run against the cached survivor baseline from a prior audit (the runId it returned). Auto-scoped to the baseline lines (StrykerJS) or whole-file (other languages). Mutually exclusive with baseline, diffBase, and lineScope. Example: "a1b2c3d4".
dryRunNoIf true, run only the dry-run phase to validate the test suite passes before mutation testing (StrykerJS only). Useful for pre-flight checks. Example: false
enrichNoAugment each surviving / no-coverage line with deterministic guidance: severity (high/medium/low), a "why it matters" explanation, a test-writing hint, and a source-context snippet — and rank survivors severity-first. Defaults to TRUE; pass false to disable and return the plain (unranked, unclassified) output. Richest for TypeScript; Python and PHP report severity "unknown".
baselineNoVerify mode: pass back the `survivors` and `noCoverage` arrays from a PRIOR run to re-test only those mutants and get a delta — which are now killed vs still surviving (plus any new regressions on the same lines). The re-run is auto-scoped to the baseline lines (StrykerJS) or whole-file (other languages). Mutually exclusive with diffBase and lineScope. Example: { "survivors": [{ "line": 42, "mutators": { "ConditionalExpression": 1 } }] }
diffBaseNoAuto-scope mutation to only the lines changed in git. The value selects the base to diff against: "HEAD" (all uncommitted changes), "staged" (staged changes only), or any git ref/branch/SHA (e.g. "main", resolved via merge-base with HEAD). Mutually exclusive with lineScope. Line-level scoping is StrykerJS-only; Python/Rust/PHP targets run whole-file with a note. If the file has no changes vs the base, the run is skipped. Example: "HEAD"
filePathYesPath to the file to audit, resolved against the server's working directory (an absolute path is also accepted). NOT relative to the audited file's workspace — in a monorepo that is the package root, and the two differ. Must end in .ts, .js, .tsx, .jsx, .mjs, .cjs, .mts, .cts, .py, .rs, or .php. Example: "src/utils/math.ts"
minScoreNoGate: if the mutation score is below this (0–100), the result reports gate.passed=false (never an error). Example: 80.
suppressNoMark mutants as equivalent (unkillable) so future runs exclude them from the score and output. Appended to .chaos-mcp/suppressions.json for this file, stamped with a fingerprint of the source line so a later edit to that line retires the suppression instead of silently re-pointing it. Re-issue the same entry to re-confirm one reported as drifted or unverified. A suppression is identified by its mutator and the CHANGE it makes, not by its line, so it follows the code when an edit moves it. Supply `change` (the "original → mutated" string from a survivor's `changes`) to name WHICH mutant when one line carries several of the same mutator; omit it and Chaos-MCP resolves it from this run's survivors, refusing the entry rather than suppressing all of them if several match. Example: [{ "line": 42, "mutator": "ConditionalExpression", "reason": "guard unreachable" }].
lineScopeNoConstrain mutations to a 1-based line range (inclusive). Only supported by StrykerJS; ignored for Python, Rust, and PHP targets. Useful for surgically auditing a specific function or block. Example: { "start": 10, "end": 45 }
timeoutMsNoMaximum time in milliseconds for the entire mutation run. Default: 300000 (5 minutes). Increase for large files or slow test suites. Must be <= 2147483647 (the largest delay a timer accepts). Example: 120000 for a 2-minute cap.
unsuppressNoRemove previously-suppressed mutants for this file (undo a wrong suppress). Supply `change` to remove one specific entry; omit it to remove every entry for that mutator. The `line` is ignored when matching, so an entry that has relocated is still removable.
concurrencyNoNumber of parallel mutation workers. Honoured by StrykerJS (--concurrency), cargo-mutants (-j) and Infection (--threads); cosmic-ray has no worker flag and reports this as an ignored option. When omitted, StrykerJS auto-detects CPU core count while cargo-mutants deliberately stays low (2 jobs, or 1 on a small machine) because each job wants its own multi-GB target directory. Lower this on memory-constrained machines; raise it on CI with spare cores. Must be an integer between 1 and 64. Example: 4
incrementalNoEnable incremental mode to reuse results from a previous run and skip unchanged mutants (StrykerJS only). Speeds up repeat audits of the same file. Example: true
maxSurvivorsNoCap on how many survivor (and how many no-coverage) line groups are returned, after severity ranking. Hidden groups are counted in survivorsTruncated/noCoverageTruncated. Precedence: this arg > config.defaultMaxSurvivors > 10. Example: 20
outputFormatNoOutput format for the result. "json" (default) returns a structured MutationResult object. "text" returns a human-readable summary. Example: "json"
severityFloorNoReport-time filter: drop survivor groups below this severity (requires enrichment, which is on by default). Dropped groups are counted in survivorsFiltered/noCoverageFiltered. "unknown"-severity groups are below "low" and are dropped by any floor. Ignored (with a note) when enrich is false. Example: "high"
ignorePatternsNoPath segments for files/directories to exclude from the sandbox, applied in addition to built-in exclusions. A path is skipped when any of its segments equals the pattern exactly. This now also suppresses the dependency-directory link, so excluding "node_modules" leaves the sandbox without it — which will usually break the run. A pattern is never a suffix or a substring: ".test.ts" excludes only a path segment named exactly that, not "billing.test.ts". One trailing separator is stripped, so "fixtures/" and "fixtures" are the same pattern. Example: ["fixtures/", "testdata"]
mutatorDenylistNoStryker mutator names to exclude — these are filtered out. StrykerJS only. Useful for skipping noisy or irrelevant mutators. Example: ["StringLiteral"]
prebuildCommandNoShell command to run in the sandbox BEFORE mutation testing begins. Use this to compile/build the target — the sandbox has a full workspace copy. Essential for TypeScript projects ("npm run build") and Rust projects ("cargo build"). DISABLED BY DEFAULT: because it runs an arbitrary shell command that can reach outside the sandbox, the server must opt in via "allowPrebuild": true in its config file or the CHAOS_MCP_ALLOW_PREBUILD=1 environment variable. Counts against the overall timeoutMs budget. Example: "npm run build"
mutatorAllowlistNoNOT SUPPORTED in StrykerJS v9 — REJECTED: passing this fails the call with an error. v9 has no way to express "only these mutators" without the full mutator list. Use mutatorDenylist to exclude noisy mutators instead, or supply your own stryker.config.json.
perMutantTimeoutMsNoMaximum time in milliseconds per individual mutant test (StrykerJS only). Distinct from timeoutMs (total run cap). Use this to prevent a single slow mutant from hanging the entire mutation run. Default: StrykerJS default (~5000ms). Must be <= 2147483647 (the largest delay a timer accepts). Example: 10000 for a 10-second per-mutant ceiling.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
gateNo
modeNo
noteNo
runIdNo
targetNo
summaryNo
completeNo
nowKilledNo
scopeNoteNo
survivorsNo
workspaceNoAbsolute workspace root that `target` is relative to. Present only when that root is not the server's working directory (a monorepo package, or another root via CHAOS_ALLOWED_ROOTS). `join(workspace, target)` is a path this tool accepts as `filePath`; when the field is absent, `target` already is one.
enrichNoteNo
noCoverageNo
incompetentNo
killedCountNo
fidelityNoteNo
newSurvivorsNo
baselineTotalNo
mutationScoreNo
stoppedReasonNo
batchesPlannedNo
ignoredOptionsNo
stillSurvivingNo
suppressedCountNo
batchesCompletedNo
unsuppressMissedNo
suggestedTestFileNo
survivorsFilteredNo
unsuppressedCountNo
noCoverageFilteredNo
survivorsTruncatedNo
driftedSuppressionsNo
noCoverageTruncatedNo
orphanedSuppressionsNo
rejectedSuppressionsNo
relocatedSuppressionsNo
unverifiedSuppressionsNo
Install Server

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description takes full responsibility for behavioral disclosure. It explains the sandbox isolation, on-demand execution, generation of logical mutants, and the nuanced path resolution behavior (`filePath` vs `target`/`workspace`). This goes beyond a simple statement of purpose and gives the agent operational expectations about environment and output paths.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but each sentence carries useful information: purpose, mutation mechanics, language support, and the critical path-resolution caveat. It is front-loaded with the main purpose. While the path section is dense, it addresses a real gotcha and is not filler. It is slightly longer than strictly necessary but never wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 21 parameters and an output schema, the description supplies the essential context: what the tool does, how it behaves in a sandbox, supported languages, and the subtle path semantics. It also references a sibling tool's output as a valid input, connecting the workflow. The output schema and parameter descriptions cover the remaining details, so the description is complete without needing to restate schema content.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% coverage of all 21 parameters with detailed descriptions, so the baseline is 3. The tool description adds crucial semantics for `filePath`: it is resolved against the server's working directory, and the result's `target` is relative to the audited file's own workspace, with guidance on reconstructing a usable `filePath`. This extra layer of context for a key parameter justifies a score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Runs on-demand, sandbox-isolated mutation testing against a single source file to identify gaps in unit test coverage.' It further explains the mutation generation and test-suite interaction, making the tool's function unambiguous. It also differentiates from siblings by focusing on coverage-hole detection via mutation testing and even references triage_test_coverage's output as valid input, showing awareness of the tool ecosystem.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states when to use the tool: to audit a single file for test coverage gaps via mutation testing, with per-language support. It implicitly positions itself as a follow-up to triage_test_coverage by noting that a `file` from that tool is a valid `filePath`. However, it does not explicitly mention when not to use it or name alternatives like estimate_audit, so it falls short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AraneaDev/Chaos-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server