Skip to main content
Glama

audit_code_resilience

Run mutation testing on a source file to expose gaps in unit test coverage. It generates code mutants, runs your test suite, and pinpoints survivors that 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 by StrykerJS — 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 and Rust). 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
resourcesNo
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
coverageNoteNo
fidelityNoteNo
newSurvivorsNo
baselineTotalNo
coverageScopeNo
mutationScoreNo
stoppedReasonNo
batchesPlannedNo
ignoredOptionsNo
stillSurvivingNo
suppressedCountNo
batchesCompletedNo
unsuppressMissedNo
suggestedTestFileNo
survivorsFilteredNo
unsuppressedCountNo
noCoverageFilteredNo
survivorsTruncatedNo
driftedSuppressionsNo
noCoverageTruncatedNo
orphanedSuppressionsNo
rejectedSuppressionsNo
relocatedSuppressionsNo
unverifiedSuppressionsNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv5.1.1
    • changedInput schema / properties / perMutantTimeoutMs / description
      Previous value: -"Maximum 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."New value: +"Maximum time in milliseconds per individual mutant test (StrykerJS and Rust). 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."
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "required": [
      -      "target",
      -      "mutationScore",
      -      "summary",
      -      "survivors",
      -      "noCoverage",
      -      "note"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "target",
      -      "mode",
      -      "baselineTotal",
      -      "killedCount",
      -      "nowKilled",
      -      "stillSurviving",
      -      "newSurvivors",
      -      "note"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "required": [
      +      "target",
      +      "mutationScore",
      +      "summary",
      +      "survivors",
      +      "noCoverage",
      +      "note",
      +      "resources"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "target",
      +      "mode",
      +      "baselineTotal",
      +      "killedCount",
      +      "nowKilled",
      +      "stillSurviving",
      +      "newSurvivors",
      +      "note"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / coverageNote
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / coverageScope
      Added value: +{
      +  "enum": [
      +    "project",
      +    "selected"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / resources
      Added value: +{
      +  "properties": {
      +    "availableAtStartBytes": {
      +      "type": "integer"
      +    },
      +    "fileConcurrency": {
      +      "type": "integer"
      +    },
      +    "limitBytes": {
      +      "type": "integer"
      +    },
      +    "overBudget": {
      +      "type": "boolean"
      +    },
      +    "perFileWorkers": {
      +      "type": "integer"
      +    },
      +    "source": {
      +      "enum": [
      +        "host",
      +        "cgroup",
      +        "unavailable"
      +      ],
      +      "type": "string"
      +    },
      +    "watchdogTrips": {
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "availableAtStartBytes",
      +    "limitBytes",
      +    "source",
      +    "fileConcurrency",
      +    "perFileWorkers",
      +    "overBudget",
      +    "watchdogTrips"
      +  ],
      +  "type": "object"
      +}
  2. Changed1 schema field changedv4.2.2
    • changedInput schema / properties / mutatorAllowlist / description
      Previous value: -"NOT 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."New value: +"NOT SUPPORTED by StrykerJS — 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."
  3. Changed13 schema fields changedv3.0.1
    • changedInput schema / properties / concurrency / description
      Previous value: -"Number of parallel mutation workers (StrykerJS only). When omitted, StrykerJS auto-detects CPU core count. Lower this on memory-constrained machines; raise it on CI with spare cores. Must be an integer between 1 and 64. Example: 4"New value: +"Number 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"
    • changedInput schema / properties / filePath / description
      Previous value: -"Workspace-relative path to the file to audit. Must end in .ts, .js, .tsx, .jsx, .mjs, .cjs, .mts, .cts, .py, .rs, or .php. Example: \"src/utils/math.ts\""New value: +"Path 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\""
    • changedInput schema / properties / ignorePatterns / description
      Previous value: -"Substring patterns for files/directories to exclude from the sandbox copy, applied in addition to built-in exclusions. Any path containing the pattern string is skipped. Example: [\".test.ts\", \"fixtures/\", \"snapshots/\"]"New value: +"Path 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\"]"
    • changedInput schema / properties / suppress / description
      Previous value: -"Mark 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. Example: [{ \"line\": 42, \"mutator\": \"ConditionalExpression\", \"reason\": \"guard unreachable\" }]."New value: +"Mark 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\" }]."
    • addedInput schema / properties / suppress / items / properties / change
      Added value: +{
      +  "type": "string"
      +}
    • changedInput schema / properties / unsuppress / description
      Previous value: -"Remove previously-suppressed mutants for this file (undo a wrong suppress)."New value: +"Remove 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."
    • addedInput schema / properties / unsuppress / items / properties / change
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / orphanedSuppressions
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / rejectedSuppressions
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / relocatedSuppressions
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / unsuppressMissed
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / unsuppressedCount
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / workspace
      Added value: +{
      +  "description": "Absolute 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.",
      +  "type": "string"
      +}
  4. Changed25 schema fields changedv1.7.0
    • addedInput schema / properties / baseline / anyOf
      Added value: +[
      +  {
      +    "required": [
      +      "survivors"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "noCoverage"
      +    ]
      +  }
      +]
    • addedInput schema / properties / baseline / properties / noCoverage / items / properties / line / maximum
      Added value: +100000
    • addedInput schema / properties / baseline / properties / noCoverage / items / properties / mutators / additionalProperties / minimum
      Added value: +1
    • addedInput schema / properties / baseline / properties / survivors / items / properties / line / maximum
      Added value: +100000
    • addedInput schema / properties / baseline / properties / survivors / items / properties / mutators / additionalProperties / minimum
      Added value: +1
    • changedInput schema / properties / filePath / description
      Previous value: -"Workspace-relative path to the file to audit. Must end in .ts, .js, .tsx, .jsx, .py, .rs, or .php. Example: \"src/utils/math.ts\""New value: +"Workspace-relative path to the file to audit. Must end in .ts, .js, .tsx, .jsx, .mjs, .cjs, .mts, .cts, .py, .rs, or .php. Example: \"src/utils/math.ts\""
    • addedInput schema / properties / lineScope / properties / end / maximum
      Added value: +100000
    • addedInput schema / properties / lineScope / properties / start / maximum
      Added value: +100000
    • changedInput schema / properties / mutatorAllowlist / description
      Previous value: -"NOT SUPPORTED in StrykerJS v9 and ignored — passing it has no effect. 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."New value: +"NOT 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."
    • addedInput schema / properties / mutatorAllowlist / minItems
      Added value: +1
    • changedInput schema / properties / perMutantTimeoutMs / description
      Previous value: -"Maximum 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). Example: 10000 for a 10-second per-mutant ceiling."New value: +"Maximum 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."
    • addedInput schema / properties / perMutantTimeoutMs / exclusiveMinimum
      Added value: +0
    • addedInput schema / properties / perMutantTimeoutMs / maximum
      Added value: +2147483647
    • changedInput schema / properties / suppress / description
      Previous value: -"Mark mutants as equivalent (unkillable) so future runs exclude them from the score and output. Appended to .chaos-mcp/suppressions.json for this file. Example: [{ \"line\": 42, \"mutator\": \"ConditionalExpression\", \"reason\": \"guard unreachable\" }]."New value: +"Mark 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. Example: [{ \"line\": 42, \"mutator\": \"ConditionalExpression\", \"reason\": \"guard unreachable\" }]."
    • addedInput schema / properties / suppress / items / properties / line / maximum
      Added value: +100000
    • addedInput schema / properties / suppress / minItems
      Added value: +1
    • changedInput schema / properties / timeoutMs / description
      Previous value: -"Maximum time in milliseconds for the entire mutation run. Default: 300000 (5 minutes). Increase for large files or slow test suites. Example: 120000 for a 2-minute cap."New value: +"Maximum 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."
    • addedInput schema / properties / timeoutMs / exclusiveMinimum
      Added value: +0
    • addedInput schema / properties / timeoutMs / maximum
      Added value: +2147483647
    • addedInput schema / properties / unsuppress / items / properties / line / maximum
      Added value: +100000
    • addedInput schema / properties / unsuppress / minItems
      Added value: +1
    • addedOutput schema / properties / driftedSuppressions
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / fidelityNote
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / gate / properties / reason
      Added value: +{
      +  "enum": [
      +    "partial_audit"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / unverifiedSuppressions
      Added value: +{
      +  "type": "integer"
      +}
  5. Changed4 schema fields changedv1.6.0
    • addedOutput schema / properties / batchesCompleted
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / batchesPlanned
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / complete
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / stoppedReason
      Added value: +{
      +  "enum": [
      +    "time_budget_exhausted"
      +  ],
      +  "type": "string"
      +}
  6. Changed18 schema fields changedv1.2.1
    • addedInput schema / properties / baseline / properties / noCoverage / items / properties
      Added value: +{
      +  "line": {
      +    "minimum": 1,
      +    "type": "integer"
      +  },
      +  "mutators": {
      +    "additionalProperties": {
      +      "type": "integer"
      +    },
      +    "type": "object"
      +  }
      +}
    • addedInput schema / properties / baseline / properties / noCoverage / items / required
      Added value: +[
      +  "line",
      +  "mutators"
      +]
    • addedInput schema / properties / baseline / properties / survivors / items / properties
      Added value: +{
      +  "line": {
      +    "minimum": 1,
      +    "type": "integer"
      +  },
      +  "mutators": {
      +    "additionalProperties": {
      +      "type": "integer"
      +    },
      +    "type": "object"
      +  }
      +}
    • addedInput schema / properties / baseline / properties / survivors / items / required
      Added value: +[
      +  "line",
      +  "mutators"
      +]
    • addedInput schema / properties / lineScope / properties / end / minimum
      Added value: +1
    • changedInput schema / properties / lineScope / properties / end / type
      Previous value: -"number"New value: +"integer"
    • addedInput schema / properties / lineScope / properties / start / minimum
      Added value: +1
    • changedInput schema / properties / lineScope / properties / start / type
      Previous value: -"number"New value: +"integer"
    • addedInput schema / properties / lineScope / required
      Added value: +[
      +  "start",
      +  "end"
      +]
    • addedOutput schema / oneOf
      Added value: +[
      +  {
      +    "required": [
      +      "target",
      +      "mutationScore",
      +      "summary",
      +      "survivors",
      +      "noCoverage",
      +      "note"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "target",
      +      "mode",
      +      "baselineTotal",
      +      "killedCount",
      +      "nowKilled",
      +      "stillSurviving",
      +      "newSurvivors",
      +      "note"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / baselineTotal
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / incompetent
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / killedCount
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / mode
      Added value: +{
      +  "enum": [
      +    "verify"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / newSurvivors
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "line": {
      +        "type": "integer"
      +      },
      +      "mutator": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "line",
      +      "mutator"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / nowKilled
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "line": {
      +        "type": "integer"
      +      },
      +      "mutator": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "line",
      +      "mutator"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / stillSurviving
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "line": {
      +        "type": "integer"
      +      },
      +      "mutator": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "line",
      +      "mutator"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "target",
      -  "mutationScore",
      -  "summary",
      -  "survivors",
      -  "noCoverage",
      -  "note"
      -]
  7. First observedv1.1.1

TDQS

A4.2/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure, and it delivers. It reveals sandbox isolation, side effects (suppression file append, prebuildCommand escaping the sandbox), language-specific limitations (lineScope Stryker-only, concurrency ignored by cosmic-ray), and the subtle path-resolution semantics (filePath vs workspace-relative target). This goes well beyond a simple 'mutates source' statement and gives agents the safety and operational expectations they need.

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 long but well-organized: a crisp opening statement followed by a focused PATHS paragraph. Every sentence earns its place by covering cross-language differences, path resolution, and safety-relevant side effects that are not in the schema. It could be slightly tighter, but the length is justified by the tool's 21-parameter complexity.

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 tool with 21 parameters, nested objects, and zero annotations, the description is thoroughly complete. It covers operational constraints (language support, path resolution, timeouts), side effects, and limitations across languages. An output schema exists so return values are covered elsewhere; the description provides everything else needed to call the tool correctly.

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?

Schema description coverage is 100%, so the baseline is 3. The description adds genuine extra meaning via the PATHS paragraph, explaining how the result's 'target' relates to the input 'filePath' and workspace in monorepo scenarios, and explicitly noting that a 'file' from triage_test_coverage is a valid filePath. This resolves the kind of ambiguity the schema alone leaves open.

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 opening sentence states a specific verb, resource, and method: 'Runs on-demand, sandbox-isolated mutation testing against a single source file to identify gaps in unit test coverage.' It clearly distinguishes the tool from siblings by describing the concrete mechanism (mutants, survivors) and the supported language/tool mappings, so an agent knows exactly what this tool does without reading the schema.

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

Usage Guidelines2/5

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

The description explains what the tool does and how it behaves, but never tells the agent when to choose it over the siblings 'estimate_audit' or 'triage_test_coverage' or when not to use it. There is no explicit 'use this when...' or 'for that, use X instead' guidance, so an agent must infer the appropriate usage context from the purpose alone.

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