Claude Code updates a production feature flag through an MCP tool. The tool returns 200 OK with this result:
{
"status": "success",
"flag": "checkout_v2",
"enabled": true
}
The agent records the change as complete. It runs the next deployment step and tells the reviewer that the new checkout path is active.
Thirty seconds later, the tool service restarts. The flag is back to false.
The endpoint had acknowledged the command after placing it in an in-memory queue. The durable store never committed the update. Every component told the truth according to its own narrow definition of success, but Claude Code was given the wrong conclusion.
A successful request is not always a durable effect. Production agents need to know which one they received.
Give every acknowledgement a precise meaning
success: true hides too much. It might mean the gateway parsed the request, a queue accepted a message, the primary database committed a row, or a later read found the intended value.
Name the level instead:
acknowledgement:
operation_id: op-7f19
target: flags/checkout_v2
level: accepted
accepted_at: 2026-09-07T09:42:16Z
durable_commit: unknown
externally_visible: unknown
safe_to_continue: false
The gateway can return this record quickly without pretending that the effect is finished. Claude Code may report progress, but it cannot close the step or trigger dependent work while safe_to_continue is false.
Use a small acknowledgement vocabulary that maps to real system guarantees:
accepted: the service received and validated the requestqueued: durable queue storage accepted the operationcommitted: the system of record confirmed the writeverified: an independent read observed the intended version and value
Do not infer one state from another. A durable queue protects the command from loss, but it does not prove that the consumer applied it. A database commit proves persistence in that store, but it may not prove that downstream readers can see it yet.
Set the minimum level per tool and per effect. A cache refresh may tolerate queued. A production permission change should usually require verified through the authorization path that will enforce it. Put that requirement in policy rather than leaving Claude Code to judge from prose in a tool response. The gateway should reject any response whose claimed level lacks the required fields.
Bind the commit to the intended effect
The write response needs evidence from the component that owns durability. An application server saying “done” is weak evidence if a database or external provider owns the final state.
Ask the adapter to return a commit token tied to the operation and resource version:
commit_evidence:
operation_id: op-7f19
intent_hash: sha256:8ce4...
system_of_record: feature-store-eu-west-2
resource: flags/checkout_v2
previous_version: 184
committed_version: 185
committed_value_hash: sha256:31bb...
commit_token: lsn:4F2/A9918C0
committed_at: 2026-09-07T09:42:17Z
The operation_id must refer to one immutable intent. Yesterday’s article showed why parallel writes need centrally allocated operation identity. That identity also gives the durability check something stable to verify.
A version number alone is not enough. Another writer could have changed the same resource between dispatch and verification. Compare the intended value or its canonical hash as well as the version returned by the write.
For external APIs that expose no commit token, be honest about the weaker guarantee. Record the provider job ID, poll its authoritative status endpoint, and classify the result as provider-confirmed rather than inventing database-level proof.
Verify through a separate read path
The write handler can repeat the value it was asked to store even when storage failed. Verification should read from the system of record or from the same path that production consumers use.
write(intent):
ack = mcp_gateway.dispatch(intent)
if ack.level < committed:
wait_for_commit(ack.operation_id, deadline)
observed = production_reader.get(intent.resource)
require observed.version == ack.committed_version
require hash(observed.value) == intent.value_hash
require observed.operation_id == intent.operation_id
return durability_receipt(ack, observed)
Choose the read path based on the next dependent action. If Claude Code will immediately run a deployment that reads from a regional replica, verifying only the primary database can still create a race. Either check the serving replica or hold the dependent action until replication reaches the committed version.
This is different from blindly polling until the expected value appears. The read must have a deadline, a required version, and a named authority. Otherwise an old matching value can satisfy the check by accident.
The same discipline applies when a timed-out MCP write has an unknown outcome. Reconcile first. Retry only after the system proves that the original operation did not commit.
Put the guarantee in a durability receipt
The final artifact should fit inside the review packet without asking a reviewer to reconstruct distributed-system semantics from traces.
durability_receipt:
operation_id: op-7f19
intent_hash: sha256:8ce4...
target: flags/checkout_v2
acknowledgement_level: verified
committed_version: 185
commit_token: lsn:4F2/A9918C0
verification_source: feature-reader-eu-west-2
observed_version: 185
observed_value_hash: sha256:31bb...
verified_at: 2026-09-07T09:42:19Z
dependent_actions_released: true
unresolved_checks: []
If the commit succeeds but the verification deadline expires, record committed_unverified. Do not convert it to failure and retry the write. Hold dependent actions, investigate visibility, and keep the original operation identity during reconciliation.
If the service only reached accepted, the receipt should say that. Clear incomplete evidence is safer than a confident fiction.
Break the storage path in your evals
A happy-path integration test usually misses this failure. Make the durability boundary fail on purpose:
- acknowledge the request, then kill the worker before persistence
- commit to the primary while delaying the serving replica
- return a commit token for the wrong resource version
- make the verification read return an older matching value
- restart the gateway between acceptance and commit polling
- expire the verification deadline after commit but before visibility
Check that Claude Code does not release dependent actions on accepted, queued, or committed_unverified. It should preserve the operation as incomplete and present the exact missing guarantee to the reviewer.
HTTP status codes describe requests. Production workflows care about effects. Teach the MCP boundary to separate acceptance, commitment, and observed visibility, then let Claude Code continue only when the durability receipt matches the guarantee the next step needs.
Claude Code: Building Production Agents That Actually Scale is my field guide to MCP boundaries, retries, observability, rollback, evals, cost controls, and review evidence for teams running coding agents against real systems.