Skip to content

The Daemon

Status: Tier 2. Repo: fermi-daemon. A set of small processes on your Mac that turn the Worker's task queue into real work done by a real coding harness.

The core idea

The Worker cannot run Claude Code. Your Mac can. The daemon closes that gap pull-only: the Mac calls out to the Worker, claims tasks, runs the harness locally, and completes them. Without MacOSMCP, nothing on the internet can push into your Mac — the daemon holds an outbound bearer token, no inbound port.

What runs (who owns what)

ProcessFileOwns
Pollerpoll.shlane-based task drain: claims from its queue, spawns a fresh harness per task, completes with the result
Warm workerwarm-worker.mjslatency: keeps one harness pre-booted so the first token of a reply is seconds, not a cold boot; drains main
Channel bridgeswa-bridge, dc-bridge (in fermi-mcp packages/)sockets a Worker can't hold (WhatsApp Web); relay to Worker webhooks
Broker executortools/broker-executor.mjsthe only process anywhere that sees decrypted cookies; drives Playwright for fleet browser ops — see Session broker
Session capturetools/capture-session.mjslogs into a site headfully once, ships storageState to /admin/session/capture
Box runnerbox-runner.mjsnot run on the Mac — this is the file neutrinos boot; it lives here so it can be SHA-pinned from one repo

With vs. without MacOSMCP

Daemon only (Tier 2)+ MacOSMCP (Tier 3)
DirectionMac pulls tasksWorker can also push tool calls in
Latencyqueue poll (seconds)live round-trip
Surfacewhat your task prompt allows the harness25 mac_* tools for any connected host
Inbound exposurenoneCloudflare Tunnel + MACOS_MCP_TOKEN
Typical use"fix issue #12 and open a PR" from Telegram"log into the vendor portal and screenshot the invoice" from your phone

They compose: the reference deployment runs both. Tier 2 handles queued work; Tier 3 handles interactive control. The daemon's harness itself connects to Fermi over MCP, so queued tasks still get memory, skills, secrets, and channels.

Setup

bash
git clone https://github.com/abel30567/fermi-daemon && cd fermi-daemon
cp .env.example .env    # FERMI_URL, FERMI_BEARER_TOKEN, lane/queue names
bun install             # playwright, for the broker executor
./poll.sh               # or install the launchd plists for boot persistence
node warm-worker.mjs    # optional but worth it

What success looks like

  • [ ] Message your Telegram bot; a reply arrives produced on your Mac
  • [ ] task_list(status: done) shows the task claimed by your daemon's identity
  • [ ] Kill the daemon mid-task: the lease expires and the task becomes claimable again (no lost work)

Failure modes

SymptomCauseFix
Tasks pile up pendingdaemon not running / wrong queue namecheck lane config vs. enqueue queue
Replies from "root" or wrong git authorharness env leaks throughdaemon exports GIT_AUTHOR_*/GIT_COMMITTER_*; see Committing as root
Fleet tasks stolen by your Macyou're on a pre-Sep-2026 workerupdate: fleet queues are excluded from the channel drain
Two broker executors fightingyou ran it on two Macsexactly one owns the browser profiles; kill the rest

MIT licensed. Built for people who want to own their agent.