hass-cli: driving Home Assistant from a terminal
:computer: Command-line tool for Home Assistant
At a glance
- What is it?
- The Home Assistant Command-line interface works against a local or remote instance over the API, listing entity states as a table, calling services and rendering backups, with output formats for yaml and json and column selection by jsonpath. It ships as a Python package, a Docker image and packages for Fedora, macOS and NixOS.
- Who is it for?
- hass-cli suits a Home Assistant operator who wants to script against their instance, check state from a script or a cron job, and get machine readable output rather than scrolling a dashboard, and the table and jsonpath options are what make it usable in a pipeline. It does not suit you if you only interact with Home Assistant through its own web interface, since the value here is entirely in the scriptability.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 80 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Install paths, and the note about package versions lagging
hass-cli is the Home Assistant Command-line interface, and it lets you work with a local or a remote Home Assistant instance directly from the command line.
The base install is a pip install of the released package:
$ pip install homeassistant-cliTo use the latest pre-release from the dev branch, the same tool takes a git URL:
$ pip install git+https://github.com/home-assistant-ecosystem/home-assistant-cli@devThen there are the distribution packages, and here the caveat matters. The developers of hass-cli usually provide up-to-date packages for recent Fedora and EPEL releases, installed with dnf:
$ sudo dnf -y install home-assistant-cliThe community provides support for macOS through Homebrew:
$ brew install homeassistant-cliAnd the tool is also available for NixOS, where the latest release could only be available in the unstable channel:
$ nix-env -iA nixos.home-assistant-cliThe warning in the documentation covers all of these: keep in mind that the available releases in the distribution could be out-dated. If you are on Fedora or macOS and find a command missing, that is the likely explanation rather than a bug.
There is a Docker route for people with no Python setup, using the homeassistant/home-assistant-cli image:
$ docker run homeassistant/home-assistant-cliThe container has one limitation that is easy to hit. Auto-completion and environment access need a wrapper script, which the repository provides as a raw file:
$ curl https://raw.githubusercontent.com/home-assistant/home-assistant-cli/master/docker-hass-cli > hass-cli
$ chmod +x hass-cliPut that script on your path and you can use it as if it were installed normally, as long as you do not need file system access, and the example given is the hass-cli template command.
Authentication is a long lived token, and the Supervisor needs its own
Getting connected takes one thing, and it is a token rather than a password.
You need to have or generate a long lasting token on your Home Assistant profile page, for example at http://homeassistant.local:8123/profile, and scroll down to the Long-Lived Access Tokens section.
Then you can use the --server and --token parameters on each call, or, as the documentation recommends, set the HASS_SERVER and HASS_TOKEN environment variables:
$ export HASS_SERVER=http://homeassistant.local:8123
$ export HASS_TOKEN=<secret>The environment variable route is the one to prefer, because a token passed as an argument ends up in your shell history and in the process list.
There is a second, separate credential for the Home Assistant Operating System. For those users, the Remote API proxy add-on is needed, and the documentation is careful to note that this is not a feature for regular users, as it allows access to the Supervisor API. It is relevant to the ha commands in hass-cli.
The add-on prints the Supervisor API key in its logs, and the log excerpt in the documentation looks like this:
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
Your API key is: 89400091.....d0897You then pass it with --supervisor-token or through the environment:
$ export HASS_SUPERVISOR_TOKEN=<supervisor_secret>The distinction between the two tokens is worth holding onto. The long lived access token is scoped to what the Home Assistant user can do, while the Supervisor token is the more powerful credential that gives access to host level operations.
Entity states as a table, with jsonpath column selection
The core of the tool is that most commands return a table version of what the Home Assistant API returns.
To get basic info about the server, the command is config release:
$ hass-cli config release
VERSION
2026.4.1And if you prefer yaml, the output format flag changes the shape:
$ hass-cli --output=yaml config release
- 2026.4.1Entity states are the case that matters most. The state list command produces a table with an entity id, a description and the state itself:
$ hass-cli state list
ENTITY DESCRIPTION STATE
zone.school School zoning
zone.home Andersens zoning
sun.sun Sun below_horizon
camera.babymonitor babymonitor idle
timer.timer_office_lights idle
timer.timer_small_bathroom idle
[...]You can suppress the header with --no-headers, and you can pick the table format with --table-format. The default is simple, and the alternatives are any of the formats supported by the tabulate package, which the documentation lists as plain, simple, github, grid, fancy_grid, pipe, orgtbl, rst, mediawiki, html, latex, latex_raw, latex_booktabs and tsv.
The most flexible option is --columns, where each column has a name and a jsonpath. The default setup for entities is ENTITY=entity_id, DESCRIPTION=attributes.friendly_name, STATE=state, CHANGED=last_changed, and you can replace it with something like this:
$ hass-cli --columns=ENTITY="entity_id,ATTRIBUTES=attributes[*]" state list zone
ENTITY ATTRIBUTES
zone.school {'friendly_name': 'School', 'hidden': True, 'icon': 'mdi:school', 'latitude': 7.011023, 'longitude': 16.858151, 'radius': 50.0}
zone.unnamed_zone {'friendly_name': 'Unnamed zone', 'hidden': True, 'icon': 'mdi:home', 'latitude': 37.006476, 'longitude': 2.861699, 'radius': 50.0}
zone.home {'friendly_name': 'Andersens', 'hidden': True, 'icon': 'mdi:home', 'latitude': 27.006476, 'longitude': 7.861699, 'radius': 100}That is the piece that makes the tool scriptable rather than merely readable, because a jsonpath selector over the attributes of an entity is a query, not a column. For a single entity you can get the detail view with the yaml or json output format, using the shorthand of output, -o.
The documentation is upfront that the command list it shows is only some of the features, and that you should use --help and autocompletion to learn more as they become available. Autocompletion for bash, zsh and fish is enabled through the completion sources.
Calling services, and where a backup actually comes from
The second group of commands is about acting rather than reading.
Backups are made by calling a service, and the way to find the right one is to list the services and look:
$ hass-cli service list | grep backup
$ hass-cli service call backup.createThat is the whole backup story, and it is worth understanding what it means. hass-cli is not implementing backup itself. It is a front end to the Home Assistant API, and backup is a service the instance already exposes. Anything the API can do, the tool can do, and anything the API cannot do, the tool cannot do either.
This also explains the shape of the entity commands. state list and state get are the standard REST endpoints exposed as a command tree, service list and service call are the service registry and the action endpoint, and config release is a small piece of the config API. The command names map to the API surface rather than to a product design.
The Supervisor-backed ha commands are the exception, since they do not go through the ordinary API but through the Supervisor proxy add-on with its own token.
The practical upshot for scripting is that you are writing against the API with a nicer front end, which means the same rate limits, the same permissions and the same eventual consistency apply. A cron job calling hass-cli service call every minute is making an API call every minute, and the token in the environment is the credential doing it.
Packaging details, licence ambiguity and the alpha label
The project metadata is modern and worth reading, because it settles several questions at once.
The build backend is poetry-core, and the console script is declared as hass-cli = homeassistant_cli.cli:run, so the command name is hass-cli regardless of the package name homeassistant-cli. Python is pinned to ^3.13, and the classifiers list Python 3.13 and 3.14.
The runtime dependencies explain what the tool does. aiohttp and requests for the HTTP calls, jsonpath-ng for the column selection, jinja2 for templating, which is what the hass-cli template command uses, ruamel-yaml for yaml output and configuration, tabulate for the table rendering, click and click-log for the command line surface, dateparser for natural language time handling, netdisco for network discovery, zeroconf for finding instances on the local network, and packaging for version comparisons.
The test group is thorough in a modern way, with pytest 9, pytest-timeout, requests-mock for stubbing the API, pytest-sugar, pytest-cov, mypy, ruff and pre-commit, and type stubs for requests, dateparser and tabulate. There is a mypy.ini, a mypyrc, a pylintrc, a .coveragerc, a .pre-commit-config.yaml, a poetry.lock and a pyproject.toml, with the tool directory excluded from the distribution. The Dockerfile is based on python:3.13-alpine and installs the package in editable mode, with a second Dockerfile.armhf for ARM builds.
Two licence points to check. The pyproject declares Apache Software License 2.0, while the repository is recorded as using a custom licence that GitHub could not classify, with the LICENSE.md file named as the place to look. The LICENSE.md in the repository root is the authoritative text, and for a tool that holds a long lived access token to your home automation instance, the terms are worth a glance.
The version numbers disagree slightly in a harmless way, the manifest says 1.0.1 while the release list shows 1.0.0 published on 2026-04-12. The classifier that matters more is Development Status :: 3 - Alpha, which is a franker statement than the 1.0 number. The last push was on 2026-08-04, and the default branch is dev.
Editorial conclusion
hass-cli suits a Home Assistant operator who wants to script against their instance, check state from a script or a cron job, and get machine readable output rather than scrolling a dashboard, and the table and jsonpath options are what make it usable in a pipeline. It does not suit you if you only interact with Home Assistant through its own web interface, since the value here is entirely in the scriptability. Before you use it, generate a long lived access token on your profile page rather than your password, keep the token in the HASS_TOKEN environment variable instead of passing it on each call, and check the version you install, because the distribution packages can lag the release and the pyproject still marks the project as alpha.
Frequently asked questions
How do I install hass-cli?
Run pip install homeassistant-cli for the release, or install from the dev branch with pip install git+https://github.com/home-assistant-ecosystem/home-assistant-cli@dev. There are also packages for Fedora and EPEL through dnf, a Homebrew formula for macOS, a NixOS attribute, and a Docker image named homeassistant/home-assistant-cli.
How does hass-cli authenticate with Home Assistant?
With a long lived access token generated on the Home Assistant profile page under Long-Lived Access Tokens. You pass it with the --token parameter or, as recommended, through the HASS_TOKEN environment variable together with HASS_SERVER. Home Assistant OS users additionally need the Remote API proxy add-on and a Supervisor token.
How do I choose which fields hass-cli shows in its tables?
With the --columns option, where each column has a name and a jsonpath. The default for entities is ENTITY=entity_id, DESCRIPTION=attributes.friendly_name, STATE=state, CHANGED=last_changed. You can also change the table format with --table-format and suppress the header with --no-headers.
How do I create a Home Assistant backup from hass-cli?
By calling the service, so first run hass-cli service list | grep backup to find it, then hass-cli service call backup.create. The tool does not implement backup itself, it calls the service the instance exposes through the API.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/home-assistant-ecosystem-home-assistant-cli)Was this useful?