Stops agents double-firing side effects: 1,000 racing duplicates, exactly one execution.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Public register: the Retry-Safety Index lists which agent-payment implementations pay once when the answer is lost β verified safe, found & fixed (with time-to-fix), and how to get verified. Every row links to its proof.
Your swarm doesn't need more memory. It needs a causal fence around tool side effects.
Free: submit any client, facilitator, SDK or toolkit that moves money β yours or someone else's β and we read it and publish a verdict on the Retry-Safety Index at no cost. Findings come back with the mechanism, the file and line, and a failing test. You are counted, never named, until you ship a fix. Submit for grading β
Run the attack yourself:
The storm above is one action, many racers. The harder case is different agents making contradictory decisions on the same production resource β the coordination failure now reported across production multi-agent systems (~a third of 2026 multi-agent incidents). Three autonomous SRE agents react to one latency spike:
Each agent was individually correct for the state it read. Run concurrently
without coordination, all three kubectl calls fire and the cluster ends in a
state none of them intended β the $100M outage. The fence lets exactly one act,
refuses the other two before their side effect runs, and tells each one why.
Nothing above is mocked β every call is the real crate API.
EffectFence is a causal concurrency fence for multi-agent tool calls. When more than one agent (or retry, or re-dispatch) can end up trying to run the same side-effecting operation β charge a card, send a payout, provision a resource β EffectFence guarantees exactly one attempt ever executes it: same-instant races are decided by an atomic compare-exchange reservation, and late duplicates get the recorded outcome replayed instead of running again. Every effect that does run gets a content-addressed certificate chained to whatever it was causally built on.
It ships as a Rust library (effectfence::fence) and as a stdio MCP server exposing three tools β fence_prepare, fence_commit, fence_abort β so agents can route side-effecting tool calls through the fence instead of racing each other directly.
In a multi-agent gateway, more than one caller can end up trying to run the same effect:
Naively, any of these double-runs the effect. Naively rejecting every duplicate with no memory of outcome is also wrong: if the first attempt crashed, the effect never runs at all, and a duplicate that arrives after success gets an error instead of the result it needs. EffectFence closes all of it with optimistic concurrency control (OCC) plus an intent ledger: attempts don't block each other, exactly one executes, and every other attempt learns what actually happened.
Four pieces compose into the fencing protocol:
The intent ledger is what stops duplicates, not just races. Every effect carries an intent β a stable id for the logical action (e.g. "charge:order-123"). Attempts sharing an intent are the same action: the first is admitted and holds a lease; concurrent duplicates are told an attempt is in flight; duplicates arriving after success get the recorded certificate replayed verbatim; duplicates after a failure are fenced (the side effect may or may not have fired β that must be reconciled, not blindly retried) until explicitly cleared. Crashed holders lose their lease after a TTL so the action isn't stuck forever.
Vector clocks (VectorClock) track causal "happened-before" relationships across agents β one logical counter per agent, joined via elementwise-max merge, compared via a le partial order, with a concurrent check for genuinely unordered events and a stable SHA-256 digest for inclusion in certificates.
OCC read-sets (ReadSetEntry) record the causal dependencies a decision was based on: "when I decided to act, domain D was at sequence S." Both prepare_effect_fence and commit_effect_cert validate every entry against live state β if anything moved, the attempt is rejected as stale rather than allowed to act on outdated information.
CAS domain fencing is where same-instant races are decided. Each domain (a named contention scope, e.g. "order:123") has an AtomicU64 sequence counter. The decision is a single atomic compare_exchange β exactly one concurrent caller can win for any given expected sequence. (Precision note: the counter lookup sits behind a short mutex; only the race decision itself is lock-free. Ideas for a fully lock-free path are welcome.)
Every committed effect becomes an EffectCert: a SHA-256 content hash over {intent, parent, domain, seq, tool, args, result, vector_clock, read_set, agent}, chained to a parent cert hash for causal lineage. Two certs with the same hash are, by definition, records of the same effect β EffectCert::verify() recomputes the hash and confirms it hasn't been tampered with or hand-built incorrectly.
This is a single-process fence with a durable ledger. Every admission,
outcome and operator clear is appended to a JSON-lines file and fsync'd before
the fence answers, so a restart of the proxy does not forget what already ran:
a duplicate after the restart is replayed, not re-executed. Anything that was
in flight when the process died is fenced as an unknown outcome on the next
start β the holder is gone and nobody can say whether the effect fired β until
an operator reconciles and clears it. (Library users: EffectFence::open(path, config); EffectFence::new() stays in-memory. The shipped binary picks
$EFFECTFENCE_LEDGER, else ~/.local/state/effectfence/<name>.jsonl, and
EFFECTFENCE_LEDGER=memory opts out.) Two things it deliberately does not do (yet):
SETNX+CAS in Redis, or an optimistic version column in Postgres) β the types here are meant to carry over directly to that backend.FenceConfig::lease_ttl (60 s by default). An effect that runs past its lease
without saying anything therefore has its claim taken over and runs a second
time, which is the very thing this crate exists to stop. The remedy is one
call: EffectFence::heartbeat(intent) while the effect is still running (about
every third of the lease). wrap does this for you on every forwarded call;
agents driving fence_prepare directly should call the fence_heartbeat tool.
Stop beating and the lease lapses on schedule, so a genuinely dead holder is
still recovered.Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/effectfence)<a href="https://allmcps.com/mcp/effectfence"><img src="https://allmcps.com/api/badge/effectfence?style=directory" alt="EffectFence on AllMCPs" /></a>