🔒

mutex_

flock(1) for agents that live on different machines.
Named locks and counting semaphores over plain HTTP.

# the whole integration:
curl -X POST 'https://mutex.legible.sh/migrate-prod-db?ttl=60'

200 {"lease":"9f2c…","fence":12,"expires":"…"}   # yours for 60s
409 {"code":"BUSY","holders":["worker-1"]}      # it isn't

Two of your agents just decided to migrate the same database — from different machines, different sandboxes. flock(1) stops at the network boundary; ZooKeeper costs a cluster. mutex is a named lock you acquire, renew, and release with nothing but HTTP. No signup, no SDK: the first request creates the topic.

This is a lease, not a lock. No network lock service can promise true mutual exclusion — a stalled holder can outlive its TTL. So every grant carries a fencing token: a per-topic number that only goes up. Stamp it on the resource you protect and reject lower fences. The zombie's write bounces. That's the fix etcd and ZooKeeper use, in every mutex grant by default.

The whole API

requestmeaning
POST /{topic}?ttl=60acquire — 200 {lease, fence, expires} or 409 {holders, waiting}
POST /{topic}?ttl=60&wait=300block like flock: long-poll, FIFO, 408 on timeout
POST /{topic}?capacity=3semaphore: at most 3 holders — "3 agents against staging, max"
POST /{topic}/{lease}/renew?ttl=60heartbeat — 404 means you lost it: stop working
DELETE /{topic}/{lease}release
GET /{topic}status: {capacity, holders, waiting} — lease tokens never shown
GET /{topic}/sselive events: grant · renew · release · expire

Topics are created by first use — an unguessable name is your access control. Errors are JSON with honest status codes. Open a topic in a browser for a live status page.

Or wrap a command

mutex run deploy --ttl 60 -- ./deploy.sh production
# acquire → heartbeat at ttl/3 → run (MUTEX_FENCE in env) → release
# lease lost mid-run? the command is killed. exit 75.

Self-host in one line

npx mutex-sh serve   # same API on 127.0.0.1:4185
# --data-dir to survive restarts · --token to require a bearer

Source on GitHub — MIT, Node ≥ 20, zero dependencies. Tests, docs, and a 12-line block that teaches your agent the whole tool.