Writing ·

How to fault-inject MCP tool calls before an agent release

Test MCP-connected agents with seed-recorded error, content, and timing faults; verify exposure and grounded outcomes against pass-through controls.

By Youssef Hemimy · MCP · agent evaluation · agent reliability

Test an agent at the MCP call boundary, where a tool may return an error, believable but wrong data, a late response, or no response. Replay representative tasks with pass-through and faulted calls. Record the seed and actual fault exposure, then compare externally checked task quality, grounded tool use, timeouts, retries, latency, and the agent's final claim. Neither a larger model nor a plausible answer proves the workflow tolerated a bad tool response.

Build a fault matrix around the actual MCP contract

The MCP Tools specification distinguishes JSON-RPC protocol errors from tool-execution failures carried in a result with isError: true. It recommends exposing execution errors to models for possible correction, while clients should validate results, implement timeouts, and log tool use. A malformed request and a tool that ran but failed are different recovery surfaces.

Cross the failure surface with its persistence schedule, then compare only genuinely exposed runs with matched pass-through controls. A seed identifies the injection decision; it does not make the whole model run deterministic.

The MCP-Injector paper implements six example operators: a minor content mistake, an incorrect structured result, an invalid result, an explicit error, a delayed response, and a silent drop. Schedules can be permanent, transient, or intermittent. Cross the modes relevant to your tools with those persistence patterns. Add local cases such as schema drift or partial results when appropriate; the paper's six operators are not exhaustive.

Record for each caseWhy it matters
Tool, arguments, operator, schedule, and seedIdentify the intended failure and reproduce the injection decision.
Injected-call count and model-visible observationSeparate exposed runs from zero-dose or skipped-tool runs.
Externally verified outcome, retries, and latencyDistinguish recovery from fluent but unsupported success.

Use controls that expose harness and exposure mistakes

Run a no-proxy baseline, a pass-through proxy, and a faulted case on matched tasks. The study used these three conditions to separate proxy overhead from fault effects and paired faulted and pass-through runs by task and seed. Before counting a case as a robustness test, verify that the scheduled fault actually fired and reached the agent. Runs with no fired fault, or where the agent skipped the relevant tool, are not evidence of recovery.

In the study, 55 of 450 fault-profile cells received no fault. Some agents also gave plausible answers while bypassing tools, including in fault-free conditions. A task-quality score alone can reward an answer without the required tool evidence. For state-changing workflows, inspect the external result as well as the text. Bound retries and check the operation's replay semantics before repeating a write.

Interpret the study within its tested setting

The authors tested 25 single-server MCP tasks, two gpt-oss sizes (20B and 120B), three agent stacks, three proxy conditions, and three seeds: 1,350 experimental cells. Under their calibrated, permanent-heavy stress profile, average task-completion score fell from 8.08 to 3.23 out of 10, about 60% relative to pass-through. Partial degradation, rather than outright non-completion, was the most common faulted outcome (56% of fault-profile cells).

The larger tested backbone showed no detectable resilience-ratio advantage under these faults. Stack behavior differed, but the paper calls that effect suggestive because stacks received different numbers of fault events. The profile came from 57,240 English-language issue and pull-request threads across 1,774 public MCP repositories. Those proportions describe reported incidents, not live failure probabilities. The study also notes reporting bias, one model family, a 25-task benchmark, LLM-judge noise, and too few fired transient or intermittent events to characterize those regimes well. Its 60% effect is not a portable release threshold.

Decide what passes before the release

  1. Choose important workflows with externally checkable outcomes and authorized tool boundaries.
  2. Verify the selected fault reached the model; preserve the visible trace and mark zero-dose or tool-bypass runs separately.
  3. Check protocol versus execution-error semantics, result validation, timeouts, and bounded recovery.
  4. Score task correctness, evidence grounding, external state, false-success reporting, retry count, and latency against a matched control.
  5. Set thresholds from local consequences, then inspect failures by task, stack, fault mode, and persistence.

For the adjacent decisions, see validating fault-injection exposure, testing false success after tool failure, and setting agent release thresholds.

Sources

FAQ

What should an MCP fault-injection test measure?

Measure whether the fault reached the agent, grounded task quality, externally verified effects, completion or timeout, retry count, latency, and whether the final answer claims success without evidence. Compare each faulted run with a matched pass-through control.

Is an MCP tool error the same as a JSON-RPC protocol error?

No. The MCP Tools specification distinguishes protocol errors from execution failures returned in a tool result with isError: true. Test both surfaces because the agent and client may handle them differently.

Does a larger model make an agent resilient to MCP tool faults?

Do not assume so. One controlled study found no detectable resilience-ratio advantage for its tested 20B and 120B gpt-oss pair under a permanent-heavy stress profile. That does not establish a rule across model families or production workloads.

Building something that has to hold up?

We do this work for teams — agent reliability hardening, custom MCP servers, and full-stack AI systems built to survive production.