mcp-daemon-diet

August 28, 2026 · View on GitHub

One shared MCP daemon per machine, instead of a copy in every agent session.

Works with any MCP server and any MCP client. Nothing here is specific to one integration - it is the recipe, the launcher and autostart templates for all three operating systems, a watchdog that will not make things worse, two measurement scripts, and thirteen gotchas we paid for in production.

Built and run at Palo Alto AI Research Lab, where a fleet of Claude sessions across five machines talks to its MCP servers through exactly this setup.

The problem

An MCP server registered as stdio is spawned per client session. Ten parallel agent sessions means ten copies of the same server: ten times the memory, ten connections to whatever it talks to, ten holders of the same lock.

What we measured on one laptop, 2026-08-01 to 08-03:

servercopiessummed RSS
telegram~9~2.7 GB
mongodb~26~3.0 GB
n8n~15~2.9 GB
whatsapp~15~1.5 GB
launcher wrappers (npx/cmd)~60~5 GB

Read those numbers honestly. Summing RSS over-counts: copies share code pages, so the operating system is not holding that many distinct bytes and you will not get that many back. What is exact is the copy count - and that each copy is an independent client of the upstream service, with its own socket, its own lock and its own session.

Measure your own machine before you believe anyone's table, including this one:

python scripts/mcp_diet_measure.py

If it prints copies 1 everywhere, you have nothing to fix. That is also what a converted machine looks like: on our hub the same script now reports one telegram and one n8n process serving every open session.

The fix, in one line

Run the server once, bound to 127.0.0.1:PORT, and point every client at the URL:

"mcpServers": { "telegram": { "type": "sse", "url": "http://127.0.0.1:8765/sse" } }

Everything else in this repo is the part that makes that survive a reboot, a crash and a teammate.

What you get

docs/RECIPE.mdthe server-agnostic procedure, start to proof
PROMPT.mdpaste into Claude Code / Codex and it does the conversion for you
daemon/launcher + autostart templates for windows, macos, linux (HKCU Run key / launchd / systemd --user) - none need admin
daemon/windows/watchdog.ps1the careful watchdog: two probes, false alarms logged not "healed", evidence before action
scripts/mcp_diet_measure.pybefore/after: copies, memory, redundancy - stdlib only
scripts/mcp_diet_verify.pyproof: config is off stdio and the daemon actually answers
docs/GOTCHAS.mdthirteen dated failures, each with its fix
docs/SECURITY.mdwhat changes when a per-session child becomes a machine-wide service
patches/README.mdfor stdio-only servers: how to add a transport switch, and get it upstreamed

The one thing to know before you start

Restarting a shared daemon blinds every live session. They do not reconnect - every call answers -32602 Invalid request parameters until each session is restarted by hand. So a naive "port dead -> restart" watchdog causes worse outages than the crashes it fixes. Ours probes twice, logs a false alarm instead of acting on it, records evidence before it touches anything, and refuses to restart a daemon that is merely mute. Read its header before you edit it. Full story: GOTCHAS #1.

What this does not do

It does not save tokens. Context cost comes from tool schemas, which the client sends whatever the transport. One daemon saves memory, processes, sockets and locks. For tokens, disable the servers a project does not need.

License

MIT. Templates are meant to be copied, edited and shipped without asking.


Part of the connector kit series: telegram-mcp-kit, whatsapp-mcp-kit, mcp-daemon-diet, agent-approval-gate (what the agent does when it needs a human's OK and nobody is at the terminal). Broken step, or a gotcha we are missing? Open an issue - we answer within 24h.


🧰 Connector & Ops Kits

Eight kits, all published 2026-08-10, each lifted out of the same live fleet after it survived production rather than written as a demo. They are independent: take one, ignore the rest. All stdlib-only Python, all free.

kitwhat it solves
telegram-mcp-kitConnect your agent to your own Telegram account in ~15 minutes, with the production patches and every gotcha
whatsapp-mcp-kitLink WhatsApp, using a live self-refreshing QR page that makes pairing actually work
mcp-daemon-dietOne shared MCP daemon per machine instead of a stdio copy in every session, with a watchdog that will not blind your live sessions
agent-approval-gateYour agent needs a human's OK and nobody is at the terminal: the ask goes to a messenger, the answer comes back into the run
fleet-deployRoll a fix to N machines and prove it landed on each one: canary waves and a verify that must read a fact back
secondop-panelNobody reviews themselves, and one reviewer model is one blind spot: fan a change out to several model families with quorum and honest skips
oss-publishOpen up internal work without leaking it: plausible substitutions of the same shape, then a fail-closed gate over the whole tree
llm-spend-auditWhat your own wiring charges on every session, and which paid subscriptions are going undrawn

🧩 One piece of a working system

This repository is one piece lifted out of a live operation: one non-technical founder, an AI cofounder, and a fleet of machines that reach consensus with each other and wake the human only for money or the irreversible. It was extracted after it survived production, not written as a demo — and it runs on its own: nothing here phones home to the rest.

See how the whole thing fits together → SYSTEM.md

Its closest neighbours in the connectors layer: telegram-mcp-kit · whatsapp-mcp-kit

AI contributors

This project is built by a human + AI team, and the git log says so: Claude writes most of the code, Codex and Grok review it, Gemini feeds the research. Each is credited on a commit only if its output changed that commit's content — no decorative credits. Lab-wide policy, one source for every repo: AI-CONTRIBUTORS.md.

One finding in this repo came from exactly that: an external reviewer spotted that a marker built from an interpreter name ("command": "node") made mcp_diet_measure.py count every unrelated node process as a duplicate of that server. Fixed before the first release, and the regression is locked into the test suite.