Latest / Big Iron Radio / Exposing Your Homelab to an LLM: The Read-Only MCP Server Pattern
Transcript
- 0:02Here's a thing you probably want.
- 0:05To ask an LLM, hey, how's my home lab doing?
- 0:09And get a real answer drawn from your actual Proxmox,
- 0:12your actual containers, your actual ZFS pools,
- 0:16instead of SS hing into four boxes
- 0:18to piece it together yourself.
- 0:20The good news is that's very doable.
- 0:23The better news is that the safe way to do it
- 0:25is also the more powerful way.
- 0:27And it starts with one word, read only.
- 0:30Quick note before we start.
- 0:33This is an AI-generated voice,
- 0:35and everything here is adapted from a written guide
- 0:38over at Big Iron.
- 0:40The full pattern with the exact configs
- 0:42is linked in the show notes.
- 0:45The pattern in one sentence.
- 0:47Build a single MCP server that exposes Proxmox, Docker,
- 0:51and ZFS state as read-only tools.
- 0:54Think status list, get functions shaped to observe.
- 0:58Never functions that act.
- 1:00The model can look at everything and touch nothing.
- 1:04And that constraint is the entire source of the safety.
- 1:07An LLM wired to read-only tools can be flat wrong
- 1:11or completely jailbroken by some malicious text it ingested,
- 1:15and the absolute worst it can do is tell you something false.
- 1:19It cannot break anything because breaking simply isn't
- 1:22in the toolbox you handed it.
- 1:24You've made the dangerous case impossible instead of merely unlikely.
- 1:28On transport, start with SDDO, the server runs as a sub-process of your client.
- 1:34No network, no listening port, no attack surface.
- 1:37And that quietly covers the entire single user, single machine case.
- 1:42Most people building this never actually need anything more than SDDO.
- 1:47Network transport is a genuinely different project, and you should treat it as one.
- 1:53The moment that server listens on the network, you need real authentication forward auth,
- 1:58a bearer token, or mutual TLS.
- 2:01What you must never do is expose it on well, it's only on my LAN.
- 2:06Trust the LAN is not a security model.
- 2:09It's the absence of one.
- 2:12Now the single most important principle in this whole pattern,
- 2:15and people get it exactly backwards.
- 2:18Dockstrings are documentation, not enforcement.
- 2:21Writing, this tool is read-only, please do not modify anything,
- 2:26in a tool's description accomplishes nothing for security.
- 2:29A jailbroken model doesn't care what the comment says.
- 2:33The real security boundary is which tools exist at all not what their descriptions warn against.
- 2:40So you enforce read-only down at the credential layer, where the model's cooperation is irrelevant.
- 2:46And you scope narrowly at every single layer.
- 2:49Let me walk the three.
- 2:52Layer 1 Proxmox.
- 2:54Create a dedicated read-only role and token.
- 2:57Let your admin login a purpose-built token that is physically incapable of performing an action.
- 3:03Even if the model tries to call something destructive, Proxmox itself refuses,
- 3:08because the credential doesn't have the permission.
- 3:12Layer 2, Docker and this is the sharp edge people cut themselves on.
- 3:16Do not put the server in the Docker group.
- 3:19Docker group membership is effectively root on the host.
- 3:23Instead, run a Docker socket proxy with an explicit read-only allow list, so only the get and list endpoints
- 3:29are even reachable.
- 3:31The proxy is the fence.
- 3:33The allow list is what it permits.
- 3:36Layer 3, ZFS.
- 3:38Run your zpool and ZFS status commands as a non-root, non-sudo user.
- 3:43It can read the health of the pool and report it back.
- 3:47It cannot scrub, destroy, or alter anything.
- 3:50Read the dashboard, don't hold the controls.
- 3:54Notice the theme across all three.
- 3:56Defense in depth, enforced by credentials, so that even if the model goes completely rogue,
- 4:02every layer independently refuses to do harm.
- 4:05The model's honesty is never load-bearing.
- 4:08That's the design goal of system that's safe even when the AI is not.
- 4:13Now what about write actions restarting a container, destroying a snapshot, replacing a disk?
- 4:20Those are real, and sometimes you genuinely want them.
- 4:23But they belong in a separate server, with separate credentials.
- 4:27You do not bolt them onto the read-only one.
- 4:31They belong behind a human approval step one that is not satisfiable from inside the model's
- 4:36own context.
- 4:38That last part is the crux.
- 4:40The model can propose a change, but a human approves it out of band, and the model cannot
- 4:45approve itself no matter what clever text it generates.
- 4:50Propose in the model, approve outside it.
- 4:53That separation is what makes write survivable.
- 4:56Why the hard split into two servers?
- 4:59As if read and write live together, a single confused deputy moment one piece of malicious
- 5:05text the model reads and obeys now touches everything.
- 5:09Two separate servers with two separate credential sets keep the blast radius contained.
- 5:15The read-only side simply has no capacity to be turned against you.
- 5:20And here's the pleasant surprise the guide lands on.
- 5:23Read-only MCP is the 80% win.
- 5:27Read just that, live with it for a month, and you'll very likely find you don't even
- 5:31miss the right actions.
- 5:32Tell me what's happening across my home lab turns out to be almost everything you actually
- 5:37wanted.
- 5:39Because the value was never the LLM doing things to your infrastructure.
- 5:44It was the LLM saving you from logging into four machines to answer one simple question.
- 5:50Read-only delivers that completely at zero risk.
- 5:53So build the read-only server, scope every credential so the model's behavior can't matter, keep
- 5:59any rights in a separate approval-gated server, and never, ever trust a docstring to be a fence.
- 6:06The full pattern's in the show notes.
- 6:08Thanks for listening, I'll catch you next time.