A CLI utility designed for LLMs to build and manage Home Assistant configurations.
Vibe coded, use at own risk.
go install github.com/balloob/home-assistant-build-cli@latest
Or build locally:
git clone https://github.com/balloob/home-assistant-build-cli
cd home-assistant-build-cli
go build -o hab .
If you are driving hab from an LLM or automation, start with:
hab guide
hab guide list --json
hab schema overview --json
hab capability probe --json
For write workflows, inspect the command contract and preview the mutation first:
hab schema area create --json
hab area create "Kitchen" --plan --json
hab supports OAuth login, long-lived access tokens, stored encrypted credentials, and Home Assistant Supervisor credentials.
# Discover Home Assistant instances on the local network
hab auth discover
hab auth discover --timeout 5
# Authenticate using OAuth
hab auth login
# Authenticate using a long-lived access token
hab auth login --token --url http://homeassistant.local:8123 --access-token "your_token"
# Check authentication status
hab auth status
# Refresh OAuth credentials if needed
hab auth refresh
# Remove stored credentials
hab auth logout
--url is omitted during hab auth login, hab can discover servers and prompt for selection.credentials.json.HAB_URL + HAB_TOKEN or HAB_URL + HAB_REFRESH_TOKENSUPERVISOR_TOKEN fallback when running inside a Home Assistant add-on or app contextInteractive sessions default to human-readable text. Non-interactive sessions default to JSON.
hab entity get light.living_room --json
hab entity get light.living_room --text
Many list commands support:
--count / -c: return only the count--brief / -b: return only the ID and name fields--limit / -n: limit the number of returned itemsExamples:
hab entity list --count
hab device list --brief --limit 5
hab automation list --limit 10
hab script list --brief
hab area list --limit 2
Many mutating commands support --plan and --dry-run.
hab area create "Kitchen" --plan --json
hab dashboard card create my-dashboard --entity light.kitchen --plan --json
hab system restart --plan --json
hab thread delete <dataset_id> --plan --json
Destructive commands often require confirmation. Use --force to skip the prompt.
hab area delete <area_id> --force
hab device delete <device_id> --force
hab backup restore <backup_id> --agent backup.local --force
In non-interactive mode, commands that need confirmation return structured confirmation-required or cancelled errors instead of prompting.
hab overview returns a high-level snapshot of the instance, including counts for floors, areas, devices, entities, automations, scripts, dashboards, labels, and helpers.
hab overview
hab overview --json
# List entities
hab entity list
hab entity list --domain light
hab entity list --area kitchen
hab entity list --floor ground_floor
hab entity list --device abc123
hab entity list --device-class temperature
hab entity list --brief --limit 10
# Get entity state and registry data
hab entity get light.living_room
hab entity get light.living_room --device
hab entity get light.living_room --related
# Search entities by text
hab entity search motion
# Inspect state history
hab entity history sensor.temperature
hab entity history sensor.temperature --start "2025-01-01T00:00:00Z" --end "2025-01-02T00:00:00Z"
# View logbook entries
hab entity logbook light.living_room
hab entity logbook light.living_room --start "2024-01-01T00:00:00Z" --end "2024-01-02T00:00:00Z"
# Registry mutations
hab entity rename sensor.outdoor_temp "Outdoor Temperature"
hab entity disable sensor.outdoor_temp
hab entity enable sensor.outdoor_temp
# List and filter devices
hab device list
hab device list --area kitchen
hab device list --floor ground_floor
hab device list --brief --limit 5
# Inspect a device and its entities
hab device get <device_id>
hab device get <device_id> --related
hab device entities <device_id>
# Delete a device
hab device delete <device_id> --plan --json
hab device delete <device_id> --force
# Areas
hab area list
hab area list --floor ground_floor
hab area get <area_id>
hab area get <area_id> --related
hab area create "Kitchen"
hab area update <area_id> --name "Main Kitchen"
hab area delete <area_id> --force
# Floors
hab floor list
hab floor get <floor_id>
hab floor get <floor_id> --related
hab floor create "Ground Floor" --level 0
hab floor update <floor_id> --name "Ground Level"
hab floor delete <floor_id> --force
# Labels
hab label list
hab label get <label_id>
hab label get <label_id> --related
hab label create "Battery" --color red
hab label update <label_id> --name "Low Battery"
hab label assign <label_id> sensor.battery_level
hab label remove <label_id> sensor.battery_level
hab label delete <label_id> --force
# Zones
hab zone list
hab zone create "Office" --latitude 37.7749 --longitude -122.4194 --radius 100
hab zone update <zone_id> --name "HQ"
hab zone delete <zone_id> --force
# Persons
hab person list
hab person get <person_id>
hab person create "John Doe"
hab person update <person_id> --name "Jane Doe"
hab person delete <person_id> --force
hab search related entity light.living_room
hab search related device <device_id>
hab search related area <area_id>
action maps to Home Assistant services.
# Discover available actions and docs
hab action list
hab action list light
hab action docs homeassistant.turn_on
hab action data
# Call actions
hab action call light.turn_on --entity light.living_room
hab action call climate.set_temperature --entity climate.living_room --data '{"temperature": 22}'
hab action call weather.get_forecasts --entity weather.home --data '{"type":"daily"}' --return-response
hab action call light.turn_off --area living_room
Flags accepted by hab action call include --action, --entity, --entity-id, --area, --area-id, --data, and --return-response.
# List automations
hab automation list
hab automation list --extended
hab automation list --blueprint homeassistant/motion_light.yaml
hab automation list --blueprint "*"
# CRUD
hab automation create my_automation -d '{"alias":"My Automation","triggers":[],"conditions":[],"actions":[]}'
hab automation get my_automation
hab automation update my_automation -f automation.yaml
hab automation delete my_automation --force
# Run and inspect traces
hab automation run my_automation
hab automation run my_automation --skip-condition
hab automation trace my_automation
# Create from blueprint
hab automation create-from-blueprint my_motion homeassistant/motion_light.yaml -d '{"alias":"Motion","motion_entity":"binary_sensor.motion","light_target":{"entity_id":"light.kitchen"}}'
# Triggers
hab automation trigger list my_automation
hab automation trigger create my_automation -d '{"trigger":"state","entity_id":"sun.sun"}'
hab automation trigger get my_automation 0
hab automation trigger update my_automation 0 -d '{"trigger":"state","entity_id":"sun.sun","to":"above_horizon"}'
hab automation trigger delete my_automation 0 --force
# Conditions
hab automation condition list my_automation
hab automation condition create my_automation -d '{"condition":"state","entity_id":"sun.sun","state":"above_horizon"}'
hab automation condition get my_automation 0
hab automation condition update my_automation 0 -d '{"condition":"state","entity_id":"sun.sun","state":"below_horizon"}'
hab automation condition delete my_automation 0 --force
# Actions
hab automation action list my_automation
hab automation action create my_automation -d '{"action":"light.turn_on","target":{"entity_id":"light.kitchen"}}'
hab automation action get my_automation 0
hab automation action update my_automation 0 -d '{"action":"light.turn_off","target":{"entity_id":"light.kitchen"}}'
hab automation action delete my_automation 0 --force
# List scripts
hab script list
hab script list --count
hab script list --brief
# CRUD and execution
hab script create evening_routine -d '{"alias":"Evening Routine","sequence":[]}'
hab script get evening_routine
hab script update evening_routine -f script.yaml
hab script run evening_routine
hab script run evening_routine -d '{"target_room":"living_room"}'
hab script delete evening_routine --force
hab script action list evening_routine
hab script action create evening_routine -d '{"action":"light.turn_on","target":{"entity_id":"light.kitchen"}}'
hab script action get evening_routine 0
hab script action update evening_routine 0 -d '{"action":"light.turn_off","target":{"entity_id":"light.kitchen"}}'
hab script action delete evening_routine 0 --force
hab scene list
hab scene get scene.movie_mode
hab scene create movie_mode -d '{"name":"Movie Mode","entities":{"light.living_room":{"state":"on","brightness":50}}}'
hab scene update movie_mode -d '{"name":"Movie Mode Updated","entities":{}}'
hab scene activate scene.movie_mode
hab scene delete movie_mode --force
# Render inline
hab template render "{{ states('sun.sun') }}"
# Render from file
hab template render -f template.j2
# Render from stdin
echo "{{ 1 + 1 }}" | hab template render
hab category list --scope automation
hab category create "Security" --scope automation
hab category update <category_id> --scope automation --name "Safety"
hab category assign <category_id> automation.my_automation
hab category remove automation.my_automation
hab category delete <category_id> --scope automation --force
# List blueprints
hab blueprint list
hab blueprint list automation
hab blueprint list script
# Import, inspect, and delete
hab blueprint import https://raw.githubusercontent.com/home-assistant/core/dev/homeassistant/components/automation/blueprints/motion_light.yaml
hab blueprint get homeassistant/motion_light.yaml
hab blueprint get --domain script my_namespace/my_script_blueprint.yaml
hab blueprint delete homeassistant/motion_light.yaml --force
If you are new to Lovelace editing, start with:
hab guide dashboard
hab dashboard guide
hab dashboard list
hab dashboard create my-dashboard --title "My Dashboard"
hab dashboard get my-dashboard
hab dashboard update <dashboard_id> --title "Updated Dashboard"
hab dashboard delete <dashboard_id> --force
# Read and replace raw dashboard config
hab dashboard save-config my-dashboard -f dashboard.yaml
hab dashboard get my-dashboard --json
hab dashboard view list my-dashboard
hab dashboard view get my-dashboard 0
hab dashboard view create my-dashboard --title "Lights" --icon mdi:lightbulb
hab dashboard view update my-dashboard 0 --title "All Lights"
hab dashboard view delete my-dashboard 0 --force
hab dashboard badge list my-dashboard 0
hab dashboard badge get my-dashboard 0 0
hab dashboard badge create my-dashboard 0 --entity sun.sun
hab dashboard badge update my-dashboard 0 0 --entity person.jane_doe
hab dashboard badge delete my-dashboard 0 0 --force
hab dashboard section list my-dashboard 0
hab dashboard section get my-dashboard 0 0
hab dashboard section create my-dashboard 0 --title "Climate" --type grid
hab dashboard section update my-dashboard 0 0 --title "Indoor Climate"
hab dashboard section delete my-dashboard 0 0 --force
# Explicit section placement
hab dashboard card list my-dashboard 0 --section 0
hab dashboard card get my-dashboard 0 0 --section 0
hab dashboard card create my-dashboard 0 --section 0 --entity sensor.temperature
hab dashboard card update my-dashboard 0 0 --section 0 -d '{"type":"markdown","content":"Updated content"}'
hab dashboard card delete my-dashboard 0 0 --section 0 --force
# Auto-scaffold behavior: omit view/section and hab uses or creates the last one
hab dashboard card create my-dashboard --entity light.kitchen
hab dashboard card create my-dashboard --entity sun.sun --name "Sun Card"
hab dashboard card create can infer the last view and last section. If needed, it can also create missing scaffolding automatically.
Use hab helper types to discover helper families and their create parameters:
hab helper types
hab helper types --json
These helper families support list, create, and delete under hab helper <type>:
| Helper family | Example create command |
|---|---|
input-boolean |
hab helper input-boolean create "Presence" --icon mdi:toggle-switch |
input-number |
hab helper input-number create "Brightness" --min 0 --max 100 --step 5 --unit "%" |
input-text |
hab helper input-text create "Room Name" --max 50 |
input-select |
hab helper input-select create "Mode" --options Home,Away,Night |
input-datetime |
hab helper input-datetime create "Wake Time" --has-time |
input-button |
hab helper input-button create "Doorbell" --icon mdi:button-pointer |
counter |
`hab helper counter |
$ claude mcp add home-assistant-build-cli \
-- python -m otcore.mcp_server <graph>