mcpField
O
once

once

Local
github.com/aurumflux20Developer Tools0Updated 12w ago

About once

once is a Python idempotency library for applications that must protect side effects from retries, duplicate delivery, and concurrent workers. It combines payload checks, leases, and interchangeable in-memory, SQLite, and PostgreSQL stores.

Key features

  1. 01Atomic election of one executor
  2. 02Payload fingerprinting and conflict detection
  3. 03Lease recovery with fencing tokens
  4. 04Sync and async APIs
  5. 05Memory, SQLite, and PostgreSQL stores

Use cases

  1. 01Guard payment calls against retries
  2. 02Deduplicate webhook or queue deliveries
  3. 03Share idempotency state across worker processes
  4. 04Run async side effects without blocking the event loop

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"aurumflux20-once-kernel": {
"command": "uvx",
"args": [
"once-kernel"
]
}
}
}
Run commanduvx once-kernel

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
pypionce-kernel0.2.1

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

once

Run any side effect exactly once — even when 1,000 callers demand it at the same instant.

1,000 concurrent duplicate charges, one execution

⚡ once — STORM DEMO
1,000 concurrent attempts to charge order #777 ($49.00)

ACTUAL EXECUTIONS   :      1   ← the whole point
served same answer  :  1,000 / 1,000
elapsed             :   0.1s

💰 double-spend prevented this run: $48,951.00

That's not a mock — it's a live attack you can run right now:

pip install once-kernel
python -m once.demo

The problem

Networks retry. Users double-click. Queues redeliver. AI agents re-fire tools at machine speed. Any of these turns one payment into two, one email into three, one server into two hundred.

Most teams hand-roll an idempotency table — and most of those are quietly broken under concurrent load: two identical requests both pass the "already done?" check, then both execute. The bugs are subtle, the failures are money.

once is that table done right, once, for everyone — a tiny idempotency kernel with the four defenses hand-rolled versions miss:

  1. Atomic leader election — concurrent duplicates can't all pass the check; exactly one executes, the rest coalesce onto its result.
  2. Payload fingerprinting (RFC 8785) — same key with a different body is a hard IdempotencyConflict, never someone else's cached answer.
  3. Fence tokens + generations — a crashed worker's lease can be taken over, and when the "dead" worker wakes up late, it is locked out of corrupting the record.
  4. Honest failure states — a failed attempt frees the key for retry; an unknown outcome never silently re-runs.

Use it

from once import Once

o = Once()

def charge():
    return gateway.charge(order_id="ord_1", amount_cents=4900)

# Retries, double submits, webhook redelivery, agent fan-out → runs ONCE
result = o.run("pay:ord_1", {"order": "ord_1", "amount_cents": 4900}, charge)

One box, several processes, no database server — SQLite, nothing to install:

from once import Once
from once.sqlite import SqliteStore

o = Once(SqliteStore("/var/lib/myapp/once.db"))  # schema auto-created

Survives restarts and works across processes (WAL mode). The default MemoryStore does neither — it is per-process, so the moment you run a second worker each one keeps its own private idea of what already ran, and the guard silently stops guarding.

Several machines — share state through the Postgres you already run:

from once import Once
from once.pg import PostgresStore

o = Once(PostgresStore("postgresql://user:pass@host/db"))  # table auto-created

Async (FastAPI, agents) — sync side effects go to a worker thread, waiters park on the event loop (no thread-pool starvation under duplicate storms; there's a test that proves it):

from once import AsyncOnce

ao = AsyncOnce()
result = await ao.run("pay:ord_1", payload, charge)

→ The full 5-minute guide

What you can rely on

If this happensYou get
Same key + same payload, againThe stored result — no second execution
Same key + different payloadIdempotencyConflict — never a silent wrong answer
1,000 concurrent first requestsOne executor; everyone else coalesces (wait=True) or is told to wait
Executing worker diesLease expires → another caller takes over
"Dead" worker wakes up lateFenced out — cannot complete, cannot fail, cannot corrupt
Long job outliving its leaseheartbeat() keeps it protected
Your function raisesKey freed — a later retry may execute

The honest model (put this on a poster): exactly-once execution + at-least-once result delivery. True network exactly-once is physically impossible — libraries claiming it are lying to you. We execute once and re-deliver the answer as many times as asked.

Tested like money depends on it

Because it does. Every claim above is enforced by the chaos suite — barrier-forced thread storms, dead-lease reclaim stampedes, zombie-writer fencing, frozen-clock timeout attacks, event-loop-starvation detection — run against both the in-memory store and real PostgreSQL on every commit (CI fails loudly if the Postgres bench is skipped). Silence in CI never means "untested."

And we run it on our own production mailer — a double-approved send replays instead of double-emailing a real prospect. Dogfood first.

Not this

  • Not a payment provider — it guards your calls to one
  • Not a workflow engine (no sagas, no multi-key transactions — by decision)
  • Not magic "exactly-once everywhere" — see the honest model above

Docs

Sibling project — EffectFence (Rust)

EffectFence (cargo add effectfence) is the Rust half of the same idea: a causal fence for tool side effects, with content-addressed certificates and an MCP proxy mode — effectfence wrap -- <any mcp server> fences another server's tool calls with zero code change (proven against once-mcp).

Use once when the side effect is Python and you want a durable store; use EffectFence when the fence lives in Rust or in front of an MCP server.

Commercial support

Free and Apache-2.0, and staying that way. If you want help applying it to a codebase that already moves money — side-effecting paths inventoried, storm-tested, fenced, with a CI test that keeps them fenced — email [email protected]. Details: the Fence Audit.

License

Apache-2.0

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.