AI / Automation May 19, 2026

OpenClaw MCP Subprocess Orphans on Rented Mac mini: Exit Hygiene & launchd Recovery (2026-05-19)

ProxyMac Engineering Team May 19, 2026 ~18 min read

Teams running OpenClaw with Model Context Protocol (MCP) stdio servers on rented Mac mini M4 hosts in Hong Kong, Japan, Korea, Singapore, or the United States sometimes see RSS climb while traffic is idle, duplicate node binaries, or stuck tool calls after a gateway upgrade. This May 19, 2026 field note explains how those symptoms differ from JSON stalls, gives a five-column operator matrix, walks a nine-step launchd-safe cleanup, and links to deeper guides on parallel agent concurrency, stdio buffering, and gateway restart recovery.

What “MCP orphans” look like before swap thrash

Orphaned MCP children are not theoretical: upstream issue traffic describes long-lived CLI processes where each extra Node child can retain on the order of tens of megabytes of RSS while the parent gateway has already moved on. On a single-tenant mini that difference shows up quickly because there is no hypervisor hiding your mistake—you own the full page cache and the launchd job graph.

  • Process list drift: pgrep -lf mcp or pgrep -lf modelcontextprotocol returns more rows after an overnight soak than after a cold boot, even when no human touched SSH.
  • Tool latency stair-steps: first calls succeed, later calls queue behind pipes that never EOF because a zombie reader still holds stdin open.
  • Gateway version skew: you upgraded the CLI while an older gateway still supervises children spawned from the previous semver—signals may not propagate the way you expect.
  • False “model outage”: dashboards show healthy provider latency while local tools time out; always check local fork pressure before blaming the LLM.
Do not conflate with buffering: If logs show partial JSON lines and CPU is flat, read stdio line-buffering first. Orphans usually show rising resident set size and extra PIDs while prompts are idle.

Why stdio MCP is prone to sticky child trees

Stdio MCP is attractive on Apple Silicon because it avoids exposing random TCP ports, but the transport inherits POSIX semantics: any process that keeps a pipe write-end open prevents EOF on the read side, and npx-style bootstrappers can spawn grandchildren that survive the death of the intermediate shell. When OpenClaw runs under a LaunchAgent, the environment is narrower than your laptop shell—missing HOME normalization or a mismatched PATH can cause a server binary to respawn in a tight loop, which looks like an attack on the CPU scheduler even though it is “just” automation.

Pair this with resource limits & ulimit: a default soft limit of 2560 file descriptors per process on many macOS workloads sounds generous until fifty concurrent tool calls multiply by three pipes each. Hitting the limit mid-call leaves descriptors half-open, which is a classic prerequisite for orphaned MCP siblings.

Operator response matrix (signal → action)

Primary signalFirst response (order matters)Data you should captureRollback if wrongEscalation owner
RSS climbs 200 MB in 20 minutes without new promptsSnapshot ps -o pid,ppid,rss,command -p $(pgrep -f mcp) before touching anythingCSV of PPID chains + timestamps from JSONLRestart gateway only after labeling parent PIDPlatform SRE
Duplicate listeners on admin port (e.g., 18999)Follow gateway recovery single-listener checklistlsof -nP -iTCP:18999 -sTCP:LISTENbootout wrong plist label if two jobs fightAutomation lead
429 storms from provider while local CPU is lowLower concurrency per parallel agents guideHTTP 429 counts per 5-minute bucketRestore previous maxConcurrentTasksFinOps + ML
Tool call hangs with flat RSSInvestigate buffering / PTY, not SIGKILL daystrace-equivalent logs (dtruss sample if policy allows)Revert unbuffered experiment flagsClient engineer

Nine-step clean runbook (SSH session on ProxyMac mini)

  1. Announce maintenance in your team channel—even a 90-second recycle breaks CI if unannounced.
  2. Export evidence: copy the last 500 lines of gateway log plus launchctl print gui/$UID filtered to OpenClaw labels.
  3. Freeze new jobs: pause schedulers or webhook ingress so you are not racing new MCP spawns mid-kill.
  4. Identify parents: map PPIDs; never kill -9 the launchd-managed gateway until children are classified.
  5. TERM wave: send SIGTERM to known MCP leaves, wait 15 seconds, recount PIDs.
  6. KILL only labeled stragglers that still show the MCP argv you verified in step 4.
  7. Recycle gateway: use vendor-supported launchctl kickstart -k / bootout+bootstrap sequence documented for your plist label.
  8. Smoke test: run a read-only tool (two invocations) and confirm RSS returns to baseline within 10 minutes.
  9. Postmortem hook: if orphans repeat weekly, open a tracking ticket referencing this article and attach the PPID CSV.
Numbers worth citing to finance: Baseline RSS per idle gateway on M4 silicon is typically well under 512 MB for modest configs; sustained growth beyond that without matching traffic is a hygiene smell, not “models got heavier.”

launchd-specific recycle discipline

LaunchAgents are not systemd: ThrottleInterval, KeepAlive, and SuccessfulExit interact with how aggressively macOS respawns your gateway. If you only bounce the Node binary but leave an old MCP stdio pair attached to a stale PTY, launchd happily supervises a “healthy” gateway while tools randomly attach to half-dead pipes. After any manual kill, always reconcile plist state with launchctl print and confirm the EffectiveUserID matches the account that owns ~/Library/LaunchAgents.

When you need interactive confirmation (Keychain, TCC) once per release, use VNC for that session, then return to headless SSH operations documented in help center—mixing GUI approvals with unattended launchd cycles is how half-configured MCP servers get spawned twice.

Prevention: concurrency, timeouts, and blast-radius caps

Orphan mitigation is cheaper before production:

  • Cap parallel tool calls below the knee in your provider curve; reuse the queueing mental model from parallel OpenClaw.
  • Hard timeouts per MCP server in configuration (vendor keys differ—treat 120 seconds as a starting ceiling for network-bound tools, 15 seconds for read-only file stats).
  • One working directory per automation persona so git and package managers do not fight for locks across agents.
  • Separate disposable minis for experimental MCP servers vs production orchestration—ProxyMac regions (HK/JP/KR/SG/US) make that a purchasing decision, not a hardware procurement cycle.

FAQ

Why do MCP stdio servers stay alive after the OpenClaw gateway stops? Abrupt gateway exits, ignored SIGTERM propagation, or detached grandchildren launched by npx can leave MCP Node processes running. launchd may also respawn a gateway while older MCP children still hold pipes open, which prevents clean teardown until those descriptors close.

Is it safe to kill orphaned MCP PIDs on a production ProxyMac mini? Prefer SIGTERM first, capture logs, and confirm the PID maps to an MCP command line before SIGKILL. On shared automation hosts, snapshot open files with lsof so you do not terminate an unrelated developer session. After cleanup, restart the gateway via the vendor LaunchAgent flow and verify only one listener binds to the admin port.

How is this different from stdio line-buffering hangs? Buffering issues stall JSON-RPC while processes remain logically healthy. Orphan accumulation shows climbing RSS and extra Node binaries even when traffic is idle. Treat them as separate failure modes: buffering needs PTY or unbuffered flags; orphans need process supervision, concurrency caps, and gateway recycle discipline.

Why Mac mini on ProxyMac is the right place to contain MCP side effects

MCP multiplies operating-system surface area: every tool is another fork, another set of file descriptors, another chance to mishandle signals. Apple Silicon M4 gives enough single-threaded headroom to run multiple stdio servers without stealing laptop battery, macOS matches the stack your scripts assume, and choosing HK / JP / KR / SG / US placement keeps automation physically near the SaaS regions you already test against. ProxyMac’s rental model means you can stand up a sacrificial lab mini for aggressive MCP experiments, point stakeholders at the same pricing page you use for steady-state capacity, and recycle the machine when the process tree gets messy—without negotiating a capital purchase for what is fundamentally a software hygiene problem.

Isolate messy MCP on dedicated metal

Rent HK / JP / KR / SG / US Mac mini for OpenClaw + MCP labs