I have not heard of one. It is an interesting idea.
You can get everything from Incus as JSON using the CLI tools. That might be enough to connect an LLM or to build a simple MCP interface. If you decide to build a MCP service then Go should work pretty well. Incus is written in Go.
Thanks for the comment, I will definitely check that. I’m not really familiar with Go but I guess that worst a try.\
I didn’t yet really realized that I just could use directly the cli tool directly with a LLM. But you right, that’s so simple as that. I will try with Claude code. Great tips
It’s freaking thinking we can nowdays do such things using LLM …
▎ Thanks Jarrod — agreed, Go is the natural fit here since it can use Incus’s own github.com/lxc/incus/client SDK directly instead of shelling out to the CLI and parsing JSON.
▎
▎ I’m going to start on a minimal MCP server for Incus. Planned first-pass tool surface (read-heavy, safe-by-default):
▎
▎ - list_instances, instance_info, instance_state
▎ - start_instance / stop_instance / restart_instance (explicit, no bulk/destructive ops in v1)
▎ - list_projects, list_networks, list_storage_pools
▎ - exec_in_instance (opt-in, since this is the one genuinely sensitive capability)
▎
▎ Deliberately leaving out instance creation/deletion and cluster-admin operations for a first pass — those need more thought around confirmation/safety before exposing them to an LLM-driven client. Will follow up here once there’s something runnable to look at.
I experimentally vibe coded one, and it was ‘VERY’ secure for lab products, but a bit hard to use. It did do things, but I REALLY don’t trust ‘self hosted’ models on my incus infra! The fronteir models mostly don’t mess it up, but I would be VERY hesitant to use one on prod!
@Thomas_Munn , Mostly agree. I don’t plug MCP server in prod for the moment, even with frontier model. I trust them, but not enough to take the risk. Not yet at least.
I actively use mine in lab (and preprod), largely running the Incus cluster containerized in Podman. Thinking about experimenting with a K8s-native IaC setup next. But overall that’s basically why I split the tool surface into tiers rather than shipping one flat set of capabilities:
read-only tools (list/info/state) are always on,
and everything else is opt-in and additive —
–enable-write for power state + a single bounded exec_in_instance (no persistent shell, no TTY, 60s timeout, one command per call),
–enable-create separately,
–enable-delete separately again, and every delete call has to echo back the resource’s exact name in a confirm_name field or it’s refused before it ever reaches Incus.
So you can hand a model “restart things and run one diagnostic command” without it ever being one flag-flip away from also being able to delete a storage pool.
Curious whether that tiering would’ve addressed what made your version “hard to use,” or if the friction was somewhere else.