Skip to main content
Glama
LoganInTX

hass-mcp-extensions

by LoganInTX
README.md
# hass-mcp-extensions

An MCP server that layers additional Home Assistant tools on top of
[voska/hass-mcp](https://github.com/voska/hass-mcp). The base hass-mcp server
(MIT, © Matt Voska) is vendored under `mcp_server/vendor/` so the repo is
self-contained, and extra tools are registered via `mcp_server/extensions.py`.
See `mcp_server/vendor/NOTICE.md` for provenance and license.

## What this adds

| Tool | Description |
|------|-------------|
| `get_lovelace_dashboard` | Fetch a full Lovelace dashboard config via WebSocket |
| `get_lovelace_view` | Fetch a single view from a dashboard by title or path |
| `save_lovelace_dashboard` | Overwrite an entire Lovelace dashboard config |
| `get_ha_config_item` | Get a stored automation, scene, or script by numeric ID |
| `get_addon_logs` | Fetch Supervisor add-on logs as plain text |
| `get_core_log` | Fetch the HA Core log (replaces the removed `/api/error_log` endpoint) |
| `search_addon_logs` | Grep a Supervisor add-on's logs for a pattern |
| `read_ha_file` | Read a file from the HA host over SSH |
| `list_ha_dir` | List a directory on the HA host over SSH |
| `create_or_update_automation` | Create or overwrite a stored automation via the REST API |
| `update_stored_scene` | Update a stored scene's entity states |
| `get_device_info` | Resolve a device's entities, area, and metadata by entity ID or name |
| `query_recorder_db` | Run a read-only SQL query against the recorder (MariaDB) database |
| `get_logbook` | Fetch logbook entries from the recorder database |
| `get_zigbee_events` | Fetch recent Zigbee device events from the recorder database |

All base tools from the vendored hass-mcp are also available (`get_entity`,
`list_entities`, `entity_action`, `call_service_tool`, `get_history`,
`get_entities_by_area`, `restart_ha`, etc.).

## Requirements

- Python 3.13+
- [uv](https://docs.astral.sh/uv/)
- A running Home Assistant instance with a long-lived access token
- For SSH-backed tools (`read_ha_file`, `list_ha_dir`): SSH access to the HA
  host (e.g. via the [Advanced SSH & Web Terminal](https://github.com/hassio-addons/addon-ssh) add-on)
- For recorder DB tools (`query_recorder_db`, `get_logbook`, `get_zigbee_events`):
  a connection string to the recorder database (MariaDB/MySQL)

## Setup

### 1. Clone

```bash
git clone https://github.com/LoganInTX/home-assistant
cd home-assistant
```

The base hass-mcp code is vendored in the repo, so no submodule steps are
needed.

### 2. Install dependencies

```bash
uv sync
```

### 3. Configure credentials

Copy `.env.example` to `.env` and fill in your values:

```bash
cp .env.example .env
```

```ini
HA_URL=http://homeassistant.local:8123
HA_TOKEN=YOUR_LONG_LIVED_ACCESS_TOKEN
```

Generate a long-lived access token in Home Assistant under
**Profile > Long-Lived Access Tokens**.

#### SSH access (optional)

`read_ha_file` and `list_ha_dir` shell out to `ssh`. To use them:

1. Generate a dedicated key: `ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_hass`
2. Add the public key to the Advanced SSH add-on's `authorized_keys` setting
3. Set the optional env vars in `.env` if your host differs from the defaults:

```ini
HA_SSH_USER=hassio
HA_SSH_HOST=homeassistant.local
HA_SSH_KEY=~/.ssh/id_ed25519_hass
```

SSH reads are restricted to `/config`, `/share`, `/ssl`, `/addons`, `/media`,
and `/backup`.

#### Recorder database access (optional)

`query_recorder_db`, `get_logbook`, and `get_zigbee_events` connect directly to
the recorder database. Set `HA_DB_URL` in `.env` with the recorder's connection
string (find it under your recorder integration's `db_url`):

```ini
HA_DB_URL=mysql://homeassistant:YOUR_DB_PASSWORD@core-mariadb/homeassistant?charset=utf8mb4
```

### 4. Wire into Claude Code

The repo ships a `.mcp.json` that registers the server automatically when you
open the project in Claude Code. No additional configuration needed.

To use it in a different MCP client, run the server over stdio:

```bash
uv run python -m mcp_server
```

## Also included: `add_scenes_view.py`

A standalone script that pushes a Scenes view to the Home Assistant Overview
dashboard via WebSocket. Edit the `SCENES_VIEW` dict at the top of the file,
then run:

```bash
uv run python add_scenes_view.py
```

The script connects via WebSocket, finds the existing Scenes view (or appends
one), and saves the updated config back to HA. It reads `HA_URL` and `HA_TOKEN`
from `.env`.

## Adding a new tool

Add an `async def` decorated with `@mcp.tool()` to `mcp_server/extensions.py`.
The docstring becomes the tool description shown to MCP clients.

```python
@mcp.tool()
async def my_tool(arg: str) -> str:
    """One-line description shown to the client.

    Args:
        arg: What this argument does.
    """
    ...
```

## Updating the vendored hass-mcp

The base server under `mcp_server/vendor/app/` is a vendored copy of
[voska/hass-mcp](https://github.com/voska/hass-mcp) (currently v0.4.1). It is no
longer a submodule, so newer upstream features must be ported in manually:

```bash
# Pull the version you want from upstream, then copy its app/ over the vendored copy
git clone --depth 1 --branch <tag> https://github.com/voska/hass-mcp /tmp/hass-mcp
rsync -a --exclude='__pycache__' /tmp/hass-mcp/app mcp_server/vendor/
uv run python -m mcp_server  # smoke test
```

Update the version recorded in `mcp_server/vendor/NOTICE.md` when you do, and
re-apply any local modifications to the vendored code.

## Security

- Never commit `.env` — it holds your token and DB password, and is gitignored.
- SSH access uses a dedicated key with `IdentitiesOnly=yes` and `BatchMode=yes`.
- File reads over SSH are path-validated against an allowlist before the remote
  command is issued.

## License

This project is licensed under the MIT License — see [`LICENSE`](LICENSE)
(© 2026 Logan Boyd).

The vendored base server under `mcp_server/vendor/app/` is from
[voska/hass-mcp](https://github.com/voska/hass-mcp), also MIT-licensed
(© 2025 Matt Voska) — see [`mcp_server/vendor/LICENSE`](mcp_server/vendor/LICENSE)
and [`mcp_server/vendor/NOTICE.md`](mcp_server/vendor/NOTICE.md).

TDQS

A3.6/5.0

Scored across 28 tools

Disambiguation3/5

Several tools overlap in purpose (e.g., get_error_log vs get_core_log, call_service_tool vs entity_action, list_entities vs search_entities_tool), though descriptions help differentiate. Still, the boundaries are not always clear for an agent.

Naming Consistency3/5

Most tools follow a verb_noun pattern with snake_case, but some use noun_verb (e.g., entity_action) or have inconsistent suffixes like '_tool'. The pattern is recognizable but not fully consistent.

Tool Count3/5

28 tools is on the higher side for a single server, but given the breadth of Home Assistant, it is justifiable. Some redundancy suggests it could be streamlined.

Completeness3/5

Core operations are covered (read entities, call services, manage automations/scenes, logs), but missing delete operations for automations/scenes and no tool to create a scene from scratch. Gaps exist but are not critical.

Maintenance

ActivityMaintained
ResponsivenessSyncing