Skip to content

Home Assistant's Admin AI Can Now Call Any Action. Treat It Like Root

Home Assistant's admin-only AI API just gained a tool that can run any action in the house. That turns the admin scope into close to full control. Here's what changed, a breaking change that came with it, and where the guardrails actually belong.

Home Assistant's Admin AI Can Now Call Any Action. Treat It Like Root

Last week I wrote about Home Assistant's new admin-only AI API learning to read your logs. That was read-only. Useful for troubleshooting, a privacy question, but nothing an agent could break.

That changed on October 27. The same API can now run any action in Home Assistant.

What merged

PR #188641, "Add call action tool to the Home Assistant LLM API," by Paulus Schoutsen (balloob), merged October 27. The description is short:

"Adds a tool to the Home Assistant LLM API to call any action. It always returns the response when the action has one. Target and data accept templates, rendered as in a script."

A few details matter here:

  • Any action. Not just lights and switches. Whatever actions your install has, the tool can call them.
  • Templates in target and data. The agent can build the call, not just fill in a fixed form.
  • It gets the response back. For actions that return data, the agent can use the result in its next step.
  • Errors go back to the model. An undefined variable or a slow template returns an error "so it can correct the call." That's good for reliability. It also means the agent retries instead of stopping.

Why this one is a bigger deal than it sounds

Home Assistant has two built-in AI APIs, and the difference is the whole story.

Assist controls and reads the entities you've chosen to expose. That's the one your household voice assistant and most chat setups use, and exposure is the fence.

The Home Assistant API (ID homeassistant) came in with PR #181958 on October 8. From that PR: it "manages Home Assistant itself and requires an admin user. Its scope is not bounded by entity exposure."

Put "not bounded by entity exposure" next to "call any action" and you've got an agent that can do close to anything an admin can do. The OHF Daily writeup says the new tool "belongs to that broader management scope" and isn't limited to what ordinary Assist can see.

From what the PR describes, there's no per-action allow list or confirmation step. I haven't read the code, so I won't say none exists, but nothing in the description mentions one.

My take: if you connect an MCP client or a conversation agent to the admin API, treat that connection the way you'd treat handing someone your admin password. Don't wire it up casually.

The breaking change that came with it

The same day, PR #188535 changed how conversations work. It's marked as a breaking change, and it's the one more likely to bite you this month.

A conversation now handles one message at a time. If you send a second message while Home Assistant is still working on the first, you get "This conversation is busy with another message." That applies to the conversation.process action too, when you call it several times at once with the same conversation ID.

If you have automations or scripts that fire conversation.process in parallel, give each one its own conversation ID.

The upside: when a message fails, say your AI provider is down, the message now stays in the conversation history with the error and any actions the agent already took. You can pick it back up by saying "continue." (OHF Daily's summary covers the same change.)

Guardrails belong in the tools, not the prompt

There's a good real-world account of why this matters. XDA's Anurag Singh wrote up what happened when he gave a small local model control of his Home Assistant: Qwen3 1.7B running through Ollama on a Mac, with "Control Home Assistant" turned on. That's the Assist side, so it could only touch exposed entities, and it still went sideways.

What he describes: asked to switch off the lamps, it switched off the lights. A question about whether a light was on triggered his "Good night" helper. Requests for one room hit lights across the house. A few times it read the function-call syntax out loud instead of doing anything.

His conclusion is the one I'd underline: "simply telling the model not to do something isn't enough." If you want to stop something, put the limit in the script or tool that actually runs the command. A thermostat tool that rejects temperatures outside a range. A lighting tool that only accepts one room. He also notes Home Assistant's own advice to expose fewer than 25 entities when you're experimenting with local models.

That was with a fenced-in API and a tiny model. A bigger model on the admin API is better at following instructions, but it's working with a much bigger set of actions and no fence. The lesson scales the wrong way.

How I'd set it up

  • Keep everyday voice and chat on Assist. Expose only what you'd want a guest to control.
  • Use the admin API only when you're actively managing the system, and disconnect it when you're done.
  • Give each AI client its own user and its own connection, so you can tell what did what and cut one off without touching the rest.
  • Wrap anything risky in a script that checks its own inputs, and expose the script instead of the raw devices.
  • Check your parallel conversation.process calls before you update.

When you'll get it

Both changes are in Home Assistant 2026.11, released November 4. The 2026.11 release notes put it plainly: "An assistant can look up your system information, search the actions that are available, and call one. It can list your integrations and reload one." Their advice matches mine: "give it the access you are comfortable with and no more." Both pull requests are in the 2026.11 changelog.

The release adds one guardrail I'd use right away: "You can set the MCP server to expose only read-only tools." Per the MCP server docs, it's off by default. You turn it on under Settings > Devices & services > Model Context Protocol > Configure, and it only covers the main /api/mcp URL. The per-tool-set URLs "are never read-only," so point your client at the main URL if you're counting on it. The notes also say "Any LLM API becomes available only once an administrator attaches it to a conversation agent or to the MCP server," so nothing gets connected for you.

Two caveats. The notes don't say which LLM API the call-action tool belongs to; the pull request puts it in the admin Home Assistant API. And the one-message-at-a-time conversation change is in the changelog, but it isn't listed in the final notes' backward-incompatible changes (I checked again on November 7), so test your parallel conversation.process calls rather than wait for a warning.

If you're still choosing how to connect an agent in the first place, my comparison of Home Assistant's native MCP server and ha-mcp is the place to start. New to the term? Here's what MCP means.

Permalink: https://homeautomationweekly.com/issues/28-home-assistant-llm-call-any-action-admin-scope