<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ali</title>
    <description>The latest articles on DEV Community by Ali (@aliengineering_byte).</description>
    <link>https://dev.to/aliengineering_byte</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4063249%2F9b5fc7af-0f1c-47ec-a2e4-e6bf9ad9595f.png</url>
      <title>DEV Community: Ali</title>
      <link>https://dev.to/aliengineering_byte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aliengineering_byte"/>
    <language>en</language>
    <item>
      <title>What Happens When an MCP Tool Fails Halfway? Turning Failures into Regression Tests</title>
      <dc:creator>Ali</dc:creator>
      <pubDate>Wed, 05 Aug 2026 00:54:26 +0000</pubDate>
      <link>https://dev.to/aliengineering_byte/what-happens-when-an-mcp-tool-fails-halfway-turning-failures-into-regression-tests-5c0d</link>
      <guid>https://dev.to/aliengineering_byte/what-happens-when-an-mcp-tool-fails-halfway-turning-failures-into-regression-tests-5c0d</guid>
      <description>&lt;p&gt;I maintain ResiliReplay, and I built it around a question that kept surviving ordinary MCP smoke tests: what happens after the server has been discovered and a tool fails at the boundary between “request accepted” and “useful result returned”?&lt;/p&gt;

&lt;p&gt;Most first-pass checks are necessarily optimistic. Start the server, call &lt;code&gt;tools/list&lt;/code&gt;, invoke one tool with valid arguments, and confirm a clean response. That proves the integration can work. It does not prove that a client recovers within a budget, avoids duplicate side effects, rejects hostile output, or preserves the same behavior after a later code change.&lt;/p&gt;

&lt;p&gt;Reliability work begins where that clean call stops.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fokpi5oj7caheovn421dz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fokpi5oj7caheovn421dz.png" alt="ResiliReplay Studio showing a reviewed MCP campaign, causal timeline, baseline comparison, and generated regression evidence" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspector and ResiliReplay answer different questions
&lt;/h2&gt;

&lt;p&gt;MCP Inspector is useful for interacting with a server: discover tools, inspect schemas, supply arguments, and see actual responses. ResiliReplay accepts an Inspector-shaped configuration, but it is not a replacement for that interactive workflow.&lt;/p&gt;

&lt;p&gt;The split I use is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inspector answers, “What does this server expose, and does a normal call work?”&lt;/li&gt;
&lt;li&gt;ResiliReplay asks, “What happens when a declared failure is inserted, does recovery stay inside its budget, and can I replay the result later?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That second question needs more than random fault injection. A useful campaign must be bounded and reviewable: one seed, explicit scenarios, a small tool allowlist, fixed retry and time budgets, declared expectations, and local evidence. If a campaign will call a tool, ResiliReplay prints a canonical review plan and requires the exact campaign hash back before execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start without contacting the server
&lt;/h2&gt;

&lt;p&gt;With Node.js 22 or 24, the minimal entry point is a dry run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.3.1 mcp audit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--inspector-config&lt;/span&gt; ./mcp.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--server&lt;/span&gt; my-server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output describes the executable, argument list, working directory, transport, timeouts, and environment-variable names. It does not start the server or call a tool. That makes it a useful place to catch an incorrect target or an unexpectedly broad configuration.&lt;/p&gt;

&lt;p&gt;Then generate a campaign template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.3.1 campaign init reliability.campaign.yml
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.3.1 campaign validate reliability.campaign.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an early field test, I keep concurrency at one, allow exactly one read-only idempotent tool, set retries to one, and use three scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Establish a clean control
&lt;/h2&gt;

&lt;p&gt;The control uses &lt;code&gt;fault: none&lt;/code&gt; and expects a pass with zero retries. This is not ceremonial. Without a clean control, an injected failure can be confused with a broken install, an invalid working directory, a missing browser binary, or an incompatible server version.&lt;/p&gt;

&lt;p&gt;One of my Playwright MCP setup runs demonstrated the point: recovery failed because Chrome for Testing was not installed. That was an environment failure, not evidence about Playwright MCP recovery. After using the documented installer, the clean control and the bounded campaign could be interpreted honestly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Inject a result-level failure and retry once
&lt;/h2&gt;

&lt;p&gt;The next scenario uses &lt;code&gt;mcp-tool-error&lt;/code&gt; with &lt;code&gt;recovery: retry&lt;/code&gt;. ResiliReplay allows the real tool call to complete, replaces the observed result at the test boundary with a controlled error, and permits one retry. The assertions require successful recovery, no more than one retry, no duplicate side-effect attempt, and policy compliance.&lt;/p&gt;

&lt;p&gt;That distinction matters. The server did not contain the injected error; the harness introduced it. A pass means only that the observed behavior matched this declared experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Add a malicious-canary negative control
&lt;/h2&gt;

&lt;p&gt;The third scenario injects &lt;code&gt;mcp-malicious-canary-instruction&lt;/code&gt; and expects failure. Its purpose is to show that the campaign can detect a known bad condition instead of reporting green regardless of input.&lt;/p&gt;

&lt;p&gt;This is a negative control, not a vulnerability claim. The canary is synthetic, no real secret is used, and the expected outcome is recorded before the run. When the expected failure occurs, ResiliReplay reduces the causal trace and writes a scenario, minimized fixture, executable Node test, and manifest. The campaign runner executes that generated regression immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Baselines should fail closed
&lt;/h2&gt;

&lt;p&gt;After a complete expectation-matching run, approve it explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.3.1 campaign approve runs/field-test &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; baselines/field-test.json

npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.3.1 campaign compare runs/field-test &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--baseline&lt;/span&gt; baselines/field-test.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; runs/comparison
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comparison checks verified run identity and declared metrics such as score drop, retries, and duplicate attempts. Incomplete or hash-invalid evidence is not silently treated as a pass. This is the part that turns a one-off experiment into a CI boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three bounded field validations
&lt;/h2&gt;

&lt;p&gt;I ran the public &lt;code&gt;resilireplay@0.3.0&lt;/code&gt; package against three pinned, independently maintained projects over their documented local stdio paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP Everything Server: &lt;code&gt;echo&lt;/code&gt; with harmless generated text.&lt;/li&gt;
&lt;li&gt;Playwright MCP: &lt;code&gt;browser_snapshot&lt;/code&gt; on a blank isolated headless page, with no navigation.&lt;/li&gt;
&lt;li&gt;UI5 MCP Server: &lt;code&gt;get_guidelines&lt;/code&gt; against bundled guidance, with no project analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each campaign ran the clean control, one injected tool-result error with one successful retry, and the canary negative control. Each negative control produced a verified executable regression. Each approved baseline comparison reported zero differences. The complete commands, versions, boundaries, and sanitized evidence are in the &lt;a href="https://github.com/aliengineering-byte/resilireplay/blob/main/docs/field-validation/FIELD_RESULTS.md" rel="noopener noreferrer"&gt;field results&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These are three narrow case studies, not universal benchmarks. They cover one reviewed operation per server. They do not rank the projects, imply upstream adoption, or certify security. Streamable HTTP is exercised by ResiliReplay’s local automated fixtures, but none of the three selected external packages used it as the documented local primary path, so I do not present them as third-party HTTP evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety boundaries and limitations
&lt;/h2&gt;

&lt;p&gt;ResiliReplay is defensive reliability software, not an OS sandbox. A tool you authorize can still mutate files, databases, browsers, or remote systems with the permissions of its server. Start locally; prefer read-only, idempotent calls; review every allowlisted tool; and never use production data merely to provoke a failure.&lt;/p&gt;

&lt;p&gt;Reports are sanitized, but pattern redaction cannot prove that every application-specific secret is gone. Hashes link evidence and detect changes; they do not establish signer identity. The current scorer evaluates declared observable evidence, not open-ended semantic quality. Side-effecting campaigns are intentionally not resumed after interruption because replaying a partial operation may be unsafe.&lt;/p&gt;

&lt;p&gt;The project, npm package, and five-minute field-test guide are available from the &lt;a href="https://aliengineering-byte.github.io/resilireplay/" rel="noopener noreferrer"&gt;ResiliReplay site&lt;/a&gt;. If you maintain an MCP server, I would value a sanitized result from one real, reviewed tool: which boundary exposed the most useful behavior—transport failure, result-level failure, duplicate invocation, or recovery after partial completion?&lt;/p&gt;

&lt;h2&gt;
  
  
  Update — ResiliReplay v0.4.0 Adopt (August 5, 2026)
&lt;/h2&gt;

&lt;p&gt;Since this article was published, v0.4.0 has shortened the same failure-to-regression workflow into two entry points:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.4.0 demo
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.4.0 adopt &lt;span class="nt"&gt;--config&lt;/span&gt; ./mcp.json &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.4.0 adopt &lt;span class="nt"&gt;--config&lt;/span&gt; ./mcp.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;demo&lt;/code&gt; needs no configuration, account, API key, Docker, external server, or LLM. It runs a clean control, injects a tool-result failure, performs one bounded recovery, checks a malicious-canary negative control, generates a regression, and executes that regression.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;adopt --dry-run&lt;/code&gt; parses an Inspector-compatible configuration and shows the exact sanitized target and generated-file plan while starting no process, opening no network connection, calling no tool, and writing no project file. Real adoption still requires explicit review of the target, exact tool and arguments, and one-duplicate retry suitability. Tool annotations remain untrusted hints.&lt;/p&gt;

&lt;p&gt;Final verification against the public npm package measured a 239 ms demo and a 783 ms real local stdio adoption. Adoption generated 14 commit-ready artifacts; its executable regression and all four generated campaign scenarios passed. An external GitHub Action matrix passed on Ubuntu and Windows with Node.js 22 and 24 using the immutable &lt;code&gt;aliengineering-byte/resilireplay@v0.4.0&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;The earlier three v0.3.0 field validations in this article remain historical bounded evidence; they are not upstream endorsements or v0.4 adopter claims.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aliengineering-byte/resilireplay/releases/tag/v0.4.0" rel="noopener noreferrer"&gt;v0.4.0 release and evidence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aliengineering-byte/resilireplay/blob/v0.4.0/docs/ADOPT.md" rel="noopener noreferrer"&gt;five-minute adoption guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/resilireplay/v/0.4.0" rel="noopener noreferrer"&gt;public package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Update — ResiliReplay v0.5.0 Everywhere (August 5, 2026)
&lt;/h2&gt;

&lt;p&gt;v0.5.0 extends the failure-to-regression path from reviewed MCP campaigns into supported coding-agent sessions through one canonical, local-first integration core.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.5.0 demo
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.5.0 connect &lt;span class="nt"&gt;--agent&lt;/span&gt; auto &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
npx &lt;span class="nt"&gt;--yes&lt;/span&gt; resilireplay@0.5.0 mcp serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Capture remains opt-in and off after installation. The Claude Code and Codex plugins pass disposable marketplace installation plus controlled fixture-capture regressions; Hermes passes isolated skill discovery and nine-tool stdio MCP registration. Those are deliberately narrow labels: Claude and Codex are &lt;strong&gt;installation + fixture verified&lt;/strong&gt;, Hermes is &lt;strong&gt;installation verified&lt;/strong&gt;, and none is presented here as a live model benchmark or vendor endorsement.&lt;/p&gt;

&lt;p&gt;The canonical schemas bound captured agent, tool, outcome, timing, error-class, hash, and redacted-summary fields. Raw prompts, full transcripts, authorization headers, environment values, unrestricted tool bodies, and personal paths are not persisted by default. Hooks observe supported results only while capture is armed; they never inject a fault into an ordinary agent session or automatically retry a failed side-effecting call.&lt;/p&gt;

&lt;p&gt;The public npm tarball is self-contained with no runtime dependencies and includes the portable Agent Skill. Official MCP Inspector 2.1.0 enumerated nine annotated tools. The immutable release gate passed 91 tests across 16 files, Windows and Ubuntu on Node 22/24, Studio Playwright E2E, packed-package smoke, secret/privacy scans, and the official Claude plugin and Agent Skills validators.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aliengineering-byte/resilireplay/releases/tag/v0.5.0" rel="noopener noreferrer"&gt;v0.5.0 release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/resilireplay/v/0.5.0" rel="noopener noreferrer"&gt;npm package with provenance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aliengineering-byte/resilireplay/blob/v0.5.0/docs/COMPATIBILITY.md" rel="noopener noreferrer"&gt;compatibility matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aliengineering-byte/resilireplay/blob/v0.5.0/docs/RELEASE_EVIDENCE_V0_5.md" rel="noopener noreferrer"&gt;release evidence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>testing</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
