Gregor Menih
← Writing
· 8 min read · Homelab

How I manage Home Assistant effectively with AI

My journey through Home Assistant, and how I ended up creating dashboards that even my wife loves.

I started building my Home Assistant setup in 2024, when we moved into our house. It was simple enough to set up, and right out of the box most of my devices were recognized, or really easy to add. The default dashboards, though, left a lot to be desired. For years I managed them with a combination of the visual editor and dropping into YAML when that reached its limits. It worked, but I didn’t really want to spend hours figuring it out — even figuring out what kind of data I wanted to show was a chore. So I kept the stock dashboards for a long time, broke them every now and then when I did try to change something, and honestly barely used HA at all. The dashboards were useless and a pain to manage, so I mostly just left it alone.

The MCP detour

What got me back into it was AI. Over the last year agentic coding actually became usable, and it’s been getting stronger by the month. I’d been using Claude Code for most of my real programming work, and it worked well enough that I started thinking about it as a way to finally deal with the Home Assistant mess I’d been avoiding. There’s a handy MCP built right into HA, so that was my first step. Setting it up was simple enough — add an integration and it’s already running on your server. It supports OAuth out of the box, and a few lines in the Claude config and you can start asking it what the temperature of any of your rooms is.

This was what I thought would be a good way to work with Home Assistant. I started asking it what kind of dashboards it thought I should have, and then I told it to create them. It started thinking… flabbergasting… thingamajiging… minutes passed, nothing. Then it finally started writing what looked like YAML. And sure enough, I saw my dashboard change. But half the things didn’t work. So I asked it to fix them, and then it got even worse — it broke the YAML indentation and the dashboards broke completely.

After some trial and error it got it right, but it was clear this is not a good way to manage dashboards. The same few problems kept coming back:

  • For any change, it pulled down the entire dashboard, edited it, and pushed the whole thing back.
  • That got slow fast — the bigger the dashboard, the worse it got.
  • Before it could do anything useful it had to fetch every device and entity just to figure out what I meant.
  • It kept writing invalid YAML, losing track of the structure mid-edit and breaking dashboards I’d asked it to improve.

So now the dashboards were broken again, except this time it wasn’t me doing it. The MCP is great at pulling a small bit of data or flipping the state of an entity, but it can’t manage whole dashboards, and it definitely can’t write automations.

Why it works on my code

What bugged me was that this made no sense — Claude basically never does this to my code. I’ll point it at a big messy project and it edits things cleanly, keeps the structure intact, doesn’t lose its place halfway through a file. The logic is often flawed and I have to steer it, but it doesn’t produce wrong syntax. For a while I just took that for granted. Then I actually thought about what was different. When Claude works on my code there’s no MCP in the way, no API it’s calling — it opens the files on disk, reads them, writes them back. That’s it. Home Assistant was the same Claude doing the same kind of work; the only thing that had changed was that everything now went through a slow API instead of files on disk.

Getting the files local

The obvious fix is to make the files actually local: run Claude on the machine where Home Assistant lives. I didn’t love that — call me old fashioned, but I wasn’t ready to hand an AI agent root access to my house. And mostly it was just impractical. HA runs in a small Docker container on my server, and getting Vim, claude-code, and everything I’d need in there is fiddly. SSH-ing into a container to chat with an agent is not a workflow I wanted to live with.

I know a lot of people version their HA config in Git, so they must somehow be getting these files out and pushing them back. Why don’t I do the same — keep the files stored locally, edit them with Claude, and push them back to HA. So I went back to the API. Home Assistant exposes pretty much everything over it: dashboards, scripts, scenes, automations, entities, devices — you can read and write all of it. My first thought was that this is exactly what the MCP already does, so what’s the point. Then it clicked: I’m not trying to let Claude work through the API at all. I just want a local copy of everything, and the API only to move files in and out. Claude edits the files on disk — the same setup that already works for my code — and the API only ever runs when I pull or push.

The solution

So I wrote a small script — some TypeScript that talks to the HA API over its WebSocket connection. yarn pull grabs everything: every dashboard, every automation, all the HA scripts, and drops it into local YAML. It also writes a reference/ folder — an entities.json with every entity grouped by domain, plus devices.json and areas.json. It produces a structure like this:

├── automations
│   ├── _index.json
│   ├── ask_to_vacuum_when_leaving_home.yaml
│   ├── ...
├── dashboards
│   ├── _index.json
│   ├── main-dashboard.yaml
│   ├── ...
├── scripts-ha
│   ├── _index.json
│   ├── close_all_blinds_downstairs.yaml
│   ├── ...
├── reference
│   ├── areas.json
│   ├── devices.json
│   ├── entities.json
│   ├── entity-registry.json
│   └── key-entities.yaml
├── scripts
│   ├── pull.ts
│   └── push.ts
├── CLAUDE.md
└── package.json

With a few simple commands I can pull and push any of these building blocks — yarn push dashboard main-dashboard for one dashboard, yarn push automation <id> for a single automation, or just yarn push for everything. Then a CLAUDE.md tells Claude to stay inside that: the dashboards live here, and when you need an entity ID it’s in reference/entities.json, don’t invent one. That last part is what killed the broken YAML. It isn’t guessing at entity names through a slow query anymore — the whole registry is just a file it can read. While it’s editing, nothing reaches across the network. It works on the local copy the way it works on any other repo. There’s still a catch — if something changes on the HA side and I don’t pull first, my local files go stale — but for the most part it just works, and I have a plan for that part.

Conclusion

After that I just talk to it. The other day it was:

Hey Claude, make the Home dashboard nicer — my wife keeps asking me whether the heat pump is heating water or the house, can you put that somewhere she can see it?

Claude opened the local YAML, found the heat-pump entity in reference/entities.json, added its state to the dashboard where it made sense, and left the rest intact. I read the diff, ran yarn push dashboard main-dashboard, and it was live. My wife stopped asking.

This approach has let me produce some genuinely good dashboards and automations, and the thing that still surprises me is that my wife actually uses HA now. She didn’t touch it before, and now she asks me to change dashboards, and has even come up with one for herself and a few automations she likes. The MCP didn’t go away, by the way. It’s still wired up, I just only use it for reading now. If I want to know what a sensor is doing right this second, asking through the MCP is fine — that’s one quick question, not a thousand-line file it has to round-trip and rewrite.

The one thing I still don’t like is the staleness. Right now I have to remember to pull before I touch anything, and if I forget, I push stale files over whatever changed on the HA side. So the next step is to take the pulling out of my hands entirely. I want this to work like a deploy tool — push the changes to a Git repo, and have something like a GitHub Action pick up whatever lands on main and push it to Home Assistant. Whatever is on main is the source of truth, and that’s what runs on HA. No more pulling, no more remembering, just edit, commit, and let it deploy.

Filed under Homelab