How Multica Locates Your Agent’s Machine: The Runtime and Daemon Deep Dive
The article explains Multica's counter‑intuitive design where tasks assigned to Claude Code actually run on a local MacBook, detailing the runtime concept, daemon registration, heartbeat‑based liveness, and the poisoned mechanism that together let the server reliably discover and manage agents across machines.
Multica assigns work to "Claude Code" on the web UI, but the actual process runs on the user’s own MacBook rather than in the cloud, raising questions about how the server knows which machine is online, how tasks are claimed, and how offline or expired‑key situations are handled.
Runtime as daemon × tool
The key abstraction is runtime = daemon × AI tool . A daemon runs on a machine and, for each workspace‑tool pair, registers a separate runtime. For example, a MacBook with Claude Code and Codex installed and belonging to two workspaces yields four distinct runtimes.
Daemon startup and registration
When the daemon starts ( multica daemon start), it reads credentials, scans the local PATH for installed AI tools, and registers each discovered (workspace × tool) as a runtime. The registration logic is idempotent, using a stable primary key composed of the machine identifier and tool version, preventing duplicate entries on restarts.
Example claim function from server/internal/daemon/client.go:
func (c *Client) ClaimTask(ctx context.Context, runtimeID string) (*Task, error) {
var resp struct{ Task *Task `json:"task"` }
if err := c.postJSON(ctx,
fmt.Sprintf("/api/daemon/runtimes/%s/tasks/claim", runtimeID),
map[string]any{}, &resp); err != nil {
return nil, err
}
return resp.Task, nil
}The daemon polls every 3 seconds for each runtime; if a task is available, it claims it, creating the "scheduling in the cloud, execution on the edge" seam.
Why multiply daemon × tool?
A naïve design would treat each machine as a single execution unit, but that fails when a machine hosts multiple AI tools (Claude Code, Codex, Cursor, etc.) and when a user belongs to multiple workspaces that require data isolation. By orthogonalizing the dimensions, runtimes capture both the tool identity and workspace context, allowing independent load and status tracking.
The daemon’s tool detection logic lives in server/pkg/agent/version.go. It iterates over 13 adapters, runs each tool’s version command, and registers only those that succeed. Many "agent not working" issues stem from the daemon not running, a missing tool, or an expired key, which prevents the corresponding runtime from being registered.
Heartbeat and offline detection
Each daemon sends a heartbeat every 15 seconds. The server classifies runtime liveness using a three‑tier sliding window:
30 s → active : normal operation
90 s → stale : possible network jitter
300 s (5 min) → offline : task reclamation required
This gradual approach avoids premature offline decisions that could discard healthy runtimes due to brief network hiccups.
Heartbeat handling code (excerpt from server/internal/handler/runtime_liveness_store.go) updates last_seen_at on each beat and relies on the SQL stale window for offline determination.
// DB-only behavior: rewrite last_seen_at every beat;
// trust the SQL stale windowPoisoned mechanism
Detecting a tool’s presence is not enough; the daemon also verifies usability. If a version check or health probe fails (e.g., an expired Anthropic key or a corrupted binary), the daemon marks the runtime as poisoned . Poisoned runtimes are registered with an "unavailable" flag, and the server never selects them for task claims.
Relevant snippet from server/internal/daemon/poisoned.go:
// Detected tool but unusable → mark poisoned
// Poisoned runtimes are excluded from ClaimTask selectionThis mechanism ensures that local environment failures do not cause task pile‑up; the affected runtime simply becomes silent until the user fixes the tool.
Resulting observability
Combining runtimes, heartbeat liveness, and the poisoned flag gives a complete implementation of the "workstation" concept: the system can reliably observe which machines are capable, trust their status, and recover from failures, enabling a small team to manage many agents.
Next article will explore how 13 AI coding tools share a common interface and how differences such as session recovery, MCP, and inference caching are abstracted.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
