feat: combine ha_config_list_floors and ha_config_list_areas into ha_list_floors_areas - #1016
Conversation
Adds ha_get_home_topology, a read-only tool that combines the data from ha_config_list_floors and ha_config_list_areas into one nested hierarchy: floors sorted by level, each with its assigned areas, plus unassigned_areas for areas without a floor assignment. Collapses the two-call in-context join (by floor_id) into one server-side call, reducing agent reasoning for location-based queries such as 'which rooms are on the ground floor'. Existing ha_config_list_areas and ha_config_list_floors are unchanged. Implementation follows the ha_get_overview precedent (tools_search.py): sequential await on two WebSocket registry calls, fail-fast on either failure (both registries are essential here, unlike optional overview subparts). None-safe sort on level handles floors without a level set. Tests: schema-level standalone test plus two integration tests in TestAreaFloorIntegration (assigned and unassigned areas). Refs homeassistant-ai#902
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request implements a new tool, Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
Implementation SummaryChoices Made:
Problems Encountered:
Suggested Improvements (Optional Follow-ups):
|
There was a problem hiding this comment.
Code Review
This pull request introduces the ha_get_home_topology tool, which provides a hierarchical representation of floors and their associated areas, along with comprehensive end-to-end tests for its logic and schema. Feedback was provided regarding the tool's docstring, which needs to be updated to follow the project's mandatory structure template, including specific sections for usage guidance and starting with an action verb.
Adopts the docstring structure from AGENTS.md §Tool Docstrings (what / when NOT / when / caveats), matching the .gemini/styleguide.md requirement flagged on PR homeassistant-ai#1016 (MEDIUM). - Single-sentence lead with action verb - Explicit 'Do not use for flat listings' alternatives pointer - Concrete use-case and join semantics - Caveats as plain prose: None-level sort, unassigned_areas fate, sequential-read snapshot consistency Departs from the Gemini-suggested wording in two ways: explicit None-level sort note (previously implicit) and snapshot-consistency caveat (absent from Gemini's draft).
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request adds the ha_get_home_topology tool to the areas module, enabling a structured view of the home's layout by nesting areas within their respective floors. The implementation includes logic for sorting floors by level and handling unassigned areas, supported by new E2E tests for lifecycle and schema validation. Feedback identifies a logic error where areas could be lost if their floor ID is missing from the floor registry during a race condition, and notes a style guide violation regarding missing actionable suggestions in error responses.
Round-2 review on homeassistant-ai#1016 surfaced a real edge: an area whose floor_id is not present in the floors list would be lost from the response entirely — neither nested under a floor nor in unassigned_areas. In the standard flow HA Core's cascade listener (area_registry.py:516-529) sets floor_id=None when a floor is deleted, so this does not occur normally; it can surface from a race between the two sequential registry reads, or from manual .storage inconsistency. Guarded defensively either way. Changes: - Build a valid_floor_ids set from floors; route any area whose floor_id is absent (None, empty, or not in the floors list) into unassigned_areas - Add suggestions=[] to the registry-failure error response, matching the shape already in the generic exception handler below and .gemini/styleguide.md §Structured Error Responses - Docstring: extend the snapshot-consistency caveat with the concrete observable effect (area appears in unassigned_areas rather than being silently dropped) Declined Gemini suggestions: - 'initialize fields before try block' — this is a fail-fast shape, no partial response to initialize - separate error messages per registry — context={areas_success, floors_success} already carries per-registry flags for distinct debugging without splitting the top-level message
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the ha_get_home_topology tool, which provides a hierarchical view of floors and their associated areas, facilitating better location-based reasoning for AI agents. The implementation includes logic to handle unassigned areas and sorts floors by level. Corresponding E2E tests have been added to ensure schema validity and correct nesting behavior. A performance improvement was suggested to parallelize the sequential WebSocket requests for area and floor registries using asyncio.gather.
|
As I had mentioned in the issue, topology isn't a great name for this, should be something that has "areas" and "floor" (s) in the name. Will do more formal review when I can, but definitely shouldn't be a completely different name from the write tools. |
|
@kingpanther13 — fair point, and I owe you an apology here. I got so
That was clear feedback, and I should have treated it as a blocking On the name itself — three alternatives that keep the
My lean is (2) — closest to the existing On scope — your #902 comment proposed bundling read and write into @sergeykad — would appreciate your read on both questions (scope |
|
Either option 2 or 3 will probably be fine, but yeah let's wait till we get more feedback. I was hoping we could do some BAT testing on merging all 4 into 2 and then basing further decisions from that. Also, again I haven't done a formal review yet so this might have been covered already, but does this work cleanly for floors that don't have areas, and areas that don't have floors? I'm just putting the question there so it gets looked at as part of the formal review when I do it. |
kingpanther13
left a comment
There was a problem hiding this comment.
Thanks for the thorough write-up and the three naming alternatives — appreciate you sitting with this while we sort out scope.
Scope. Even though I originally wanted read and write consolidated together in #902, let's keep this PR to the read tool and do the write side in a separate PR down the road, armed with everything we've learned from #774 (reverted over the type discriminator) and #813 (landed only after dropping the area/floor consolidation under sergeykad's objection). BAT testing on 4→2 for the write tools can drive that next PR on its own evidence rather than ride on this one. This also lets the naming decision here be final instead of getting renamed twice.
Naming. Please rename to ha_list_floors_areas — drops the config_ since this is a read/view tool rather than a config mutation, and list matches AGENTS.md lines 444-447 (collections → list). Update the method, name= kwarg, the docstring leading verb, and the three call_tool sites in the tests.
My open question from earlier in the thread — now a formal ask. The tests cover "area without a floor" (test_home_topology_unassigned_area) but not "floor without any areas." Please add a test that creates an empty floor and verifies it appears in floors with "areas": [] rather than being filtered out or crashing a downstream iterator.
Silent-failure, tools_areas.py lines 437-438. areas_result.get("result", []) / floors_result.get("result", []) default to []. A malformed {"success": true} response with no result key would return floor_count: 0, area_count: 0, success: true on a populated instance. Please treat a missing result key the same as success: false and raise SERVICE_CALL_FAILED with the raw shape in context.
Orphaned floor_id is invisible to the caller. The valid_floor_ids guard correctly routes areas with a dangling floor_id into unassigned_areas, but the response has no way to distinguish "truly no floor assigned" from "pointed at a floor that no longer exists." Either a separate orphaned_areas key (with orphaned_count) or a per-area _orphaned_floor_id marker + response-level warning string would fix it. I lean toward the separate key so the LLM can surface the diagnosis without field-name introspection.
Sort order isn't tested. The docstring promises sort-by-level ascending with None alongside 0, but no test creates multiple floors with varying levels and asserts order. Please add a test with something like level=[-1, 0, None, 2] — easy silent regression otherwise.
Nit — docstring structure. AGENTS.md lines 486-515 wants action-verb summary → NOT-to-use → when-to-use → caveats. The final paragraph mixes implementation detail ("two registries are read sequentially") with the caveat. The registry-drift note is worth keeping; the sequential-read mechanic can go.
Happy to re-review as soon as these are in. Nothing here is a structural concern — the shape and direction are right.
AGENTS.md lines 444-447 reserve 'list' for collections and 'get' for single items. The tool returns a collection of floors (each with nested areas), so 'list' is the correct verb. 'floors_areas' over 'topology' makes the domain match the tool's purpose without agent-facing jargon. Updates: - @tool name kwarg + annotations.title - async def method name - first-sentence verb in docstring (full 4-part restructure in follow-up commit) - exception_to_structured_error context operation string - three call_tool sites in tests + docstring/log references No behaviour changes; rename only. Addresses review feedback from homeassistant-ai#1016.
Previously a malformed registry response with success=True but no
'result' key would fall through areas_result.get('result', []) and
return floor_count=0, area_count=0, success=True on a populated
instance — an observable silent failure.
The guard now requires both success=True and 'result' to be present.
On failure the raw response key sets are surfaced in context for
diagnosis. After the guard, indexing is direct since the key is
guaranteed to exist.
Addresses review feedback from homeassistant-ai#1016 (tools_areas.py lines 437-438).
Previously areas with a floor_id pointing to a non-existent floor
(registry drift, .storage inconsistency) were collapsed into
unassigned_areas alongside truly-unassigned areas, making it
impossible for callers to distinguish the two cases.
Partition areas into three disjoint sets:
- nested: floor_id resolves to a known floor
- orphaned: floor_id present but unknown — surfaced via
orphaned_areas + orphaned_count
- unassigned: no floor_id at all
The drift caveat in the docstring now points at orphaned_areas.
Full docstring restructure follows in a separate commit.
Addresses review feedback from homeassistant-ai#1016.
AGENTS.md lines 500-505 prescribe a 4-part multi-line docstring
structure (what / when NOT to use / when to use / caveats). The
previous docstring mixed the when-to-use section with an
implementation note ('pre-joins the two registries on floor_id')
and the caveats section with another ('the two registries are
read sequentially') — both are internals the agent does not need,
per AGENTS.md line 515.
Changes:
- when-to-use: drop the 'pre-joins two registries' sentence
- caveats: drop 'the two registries are read sequentially';
keep the registry-drift caveat, re-worded to reflect
the new orphaned_areas semantics
Addresses nit from homeassistant-ai#1016 review (docstring structure).
KP13 review homeassistant-ai#1016 flagged two untested paths: 1. 'Floor without any areas': the existing tests cover 'area without floor' but not the inverse. An empty floor must appear in the 'floors' list with 'areas': [] rather than being filtered out or crashing a downstream iterator. 2. Sort order: the docstring promises sort-by-level ascending with None alongside 0, but no test asserted it. The implementation uses 'level or 0' as the sort key, so -1 stays first, 2 stays last, and 0/None are a tie in the middle — stable sort preserves insertion order within the tie. New tests: - test_home_topology_empty_floor: creates a floor with level=3 and no areas, verifies it appears in floors with areas=[], and runs a downstream iterator smoke. - test_home_topology_sort_order: creates floors with levels [-1, 0, None, 2], asserts positions 0 and 3 are level=-1 and level=2 respectively, and the middle two positions are the 0/None pair (order-agnostic). Addresses review feedback from homeassistant-ai#1016.
…string case Second-opinion review flagged that the partition logic used a falsy check (if not fid) rather than an explicit None check, so an area with floor_id='' would be classified as unassigned even if an empty string were a distinct (if unusual) floor_id value, and a floor with floor_id='' would be silently excluded from the valid set. Using 'is None' / 'is not None' makes the partition reflect the actual semantic distinction the response schema claims: unassigned means 'no floor_id at all', orphaned means 'floor_id present but not resolvable'. No change for the common case (all real-world floor_ids are non-empty strings). Edge case now correctly routes area floor_id='' without a matching floor to orphaned_areas instead of unassigned.
|
Two notes from the parallel #902 thread before the items:
All seven items addressed across six commits on top of 306fbf5: 1. Scope — read-only final. Write-side bundle deferred to a separate PR; naming decision here is now final. (No code change; noted for the record.) 2. Rename → 3. Silent-failure guard (lines 437–438). 4. Orphaned floor_id — separate key. Three-way partition: 5. Empty-floor test. 6. Sort-order test. 7. Docstring nit. Restructured to the 4-part template (AGENTS.md lines 500–505): action-verb summary → NOT-to-use → when-to-use → caveats. Dropped the "pre-joins two registries" sentence and the "sequential reads" mechanic per AGENTS.md line 515; drift caveat kept and re-pointed at One additional edge-case fix caught before push — |
kingpanther13
left a comment
There was a problem hiding this comment.
Thanks — all 7 items from the previous round are addressed cleanly. One real gap + three polish asks, and we can move on.
Please fix in this PR:
-
Schema test missing
orphaned_*keys.test_home_topology_schemaasserts every other response field but notorphaned_areas/orphaned_count, both of which are documented in the docstring as part of the public contract. One-line fix mirroring theunassigned_*asserts:assert "orphaned_count" in topo_data assert "orphaned_areas" in topo_data assert isinstance(topo_data["orphaned_areas"], list) assert isinstance(topo_data["orphaned_count"], int)
-
Unit-test the orphaned partition branch and the
SERVICE_CALL_FAILEDguard. Both are untriggerable from E2E (orphaned needs.storagedrift, guard needs a malformed WS response) but trivial with a mocked client. Without them, the reason the guard exists and the reason for the three-way partition can regress silently. A small unit-test file with two mocks covers both. -
Sort key type-safety.
topology.sort(key=lambda f: f.get("level") or 0)is None-safe but not type-safe — a malformed stringlevelwould raiseTypeErrormid-sort and get flattened by the broadexcept Exception.int(f.get("level") or 0)inside a smalltrythat logs the offendingfloor_idwould be enough. -
Generic
except Exceptionloses context.tools_areas.py:492logs"Error listing floors and areas: {e}"without operation-specific IDs or partial state. A reader can't tell which of the two WS calls failed, or where in the partition/sort it blew up. Adding the partial state (e.g. whetherareas_resultwas fetched before the failure) to the log would make this debuggable six months from now.
On BAT testing: you've demonstrated this one is safe enough — no further BAT runs needed for this PR. The future write-side consolidation is a different story; that one will want thorough BAT evidence before we merge, given the type-discriminator history on #774/#813.
Re-requesting review once these land.
Address review items 3 and 4 on homeassistant-ai#1016: - Item 3: Replace `lambda f: f.get("level") or 0` with `_floor_sort_key` that coerces via `int()` inside a try/except and logs the offending floor_id as a warning. A malformed string `level` can no longer raise TypeError mid-sort and get flattened by the broad `except Exception`. - Item 4: Thread an explicit `progress` dict through the try-block (phases: start / areas_fetched / floors_fetched / partitioned / sorted) and pass it as the `context=` argument of exception_to_structured_error. The error log now names the phase in which the exception surfaced, so a six-months-later reader can tell whether areas_result was fetched, or the partition completed, or the sort was what blew up.
Address review items 1 and 2 on homeassistant-ai#1016: - Item 1: Extend test_home_topology_schema with assertions for orphaned_count and orphaned_areas (list, int). Log message now includes the orphaned count. Mirrors the existing unassigned_* block. - Item 2: New tests/src/unit/test_tools_areas.py covering the two paths that are untriggerable from E2E: * orphaned partition branch — area.floor_id points to a non-existent floor and surfaces in orphaned_areas (needs .storage drift in prod) * SERVICE_CALL_FAILED guard — WS response with success=True but no "result" key raises a structured error instead of silently returning floor_count=0 on a populated instance. Assertions parse the error payload and check error["code"] (KP13 PR-review convention: tight assertions, not presence-only).
|
All four items addressed —
|
kingpanther13
left a comment
There was a problem hiding this comment.
All four items addressed cleanly — phase-tracked error context, _floor_sort_key with int-coerce fallback, schema test extended for orphaned_*, and the new unit test covers both the orphaned partition branch and the SERVICE_CALL_FAILED guard with tight error["code"] assertions. CI green across the board.
LGTM.
🧪 Your changes are now in the dev channel!Your PR has been merged to master and is available for testing in the dev channel. Test your changes before the next stable release (biweekly Wednesday): Quick start# Run dev version
uvx ha-mcp-dev
# Check version
uvx ha-mcp-dev --versionDocker: docker pull ghcr.io/homeassistant-ai/ha-mcp:dev
docker run --rm -i \
-e HOMEASSISTANT_URL=http://your-ha:8123 \
-e HOMEASSISTANT_TOKEN=your_token \
ghcr.io/homeassistant-ai/ha-mcp:devFound an issue? Please open a new bug report and mention this PR for context. |
…1139) * refactor: consolidate area/floor set+remove tools into single tools Merges the four area/floor mutation tools into two consolidated tools, following the naming style introduced by #1016: ha_config_set_area + ha_config_set_floor -> ha_set_area_or_floor ha_config_remove_area + ha_config_remove_floor -> ha_remove_area_or_floor The new tools take a `kind: Literal["area", "floor"]` parameter to discriminate the registry, plus a shared `id` for the target area_id or floor_id when updating/removing. Kind-specific parameters (`level`, `floor_id`, `picture`) are documented as ignored when kind doesn't match. Net change: 87 -> 85 tools (4 mutation tools become 2). Background: PR #813 originally proposed consolidating areas + floors across list/set/remove (commit d9246ae) but the area/floor portion was reverted. PR #1016 then re-introduced a combined read-side tool (`ha_list_floors_areas`). This PR completes the consolidation on the write/delete side. - Drops the `ha_config_` prefix to match the #1016 naming - Same WebSocket API calls and response shapes as the originals; the consolidated tools reuse the existing `_build_*_message` helpers - E2E tests in tests/src/e2e/workflows/areas/test_lifecycle.py and affected helper_crud / entity_management tests updated - Regenerated tools.json / README / DOCS via scripts/extract_tools.py - AGENTS.md naming-convention reference and UAT stories s04/s10 updated Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(areas): reject cross-kind params and tighten docs/tests Addresses review findings on the consolidated area/floor tools: 1. ha_set_area_or_floor now raises VALIDATION_INVALID_PARAMETER when cross-kind params are supplied (kind='area' with level=, or kind='floor' with floor_id=/picture=). Previously these were silently dropped, producing a misleading success response. 2. id='' is also rejected explicitly. Previously the truthy check on id silently routed empty strings to the create branch — destructive if the caller meant to update. 3. Field descriptions reworded "Ignored when kind='X'" → "Only valid when kind='Y'" so the schema matches the validation behavior. 4. Added a fourth EXAMPLE for the floor-update mode. 5. ha_remove_area_or_floor docstring split into per-kind sentences (entities/devices unassign on area-delete; areas unassign on floor-delete) — the previous wording implied entities are attached directly to floors. 6. Fixed ha_call_write_tool example in categorized_search.py — was missing the required kind parameter. 7. Updated test_categorized_search.py:386 to use the new arg shape (kind/id) instead of the legacy area_id. 8. Added unit tests covering: kind→registry routing for both consolidated tools, cross-kind param rejection, and id='' rejection. 9. Regenerated tools.json / README / DOCS for the docstring change. Verification: ruff clean, mypy clean, tests/src/unit (104 passed) and tests/src/e2e/workflows/areas (17 passed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: align ha_remove_area_or_floor docstring verb with function name Sibling registry-remove tools (ha_remove_zone, ha_remove_todo_item) open their docstrings with "Remove" to match the function-name verb. Aligning this tool: "Delete..." → "Remove..." and "deleted/deleting" → "removed/removing" in the body. Both verbs are on the styleguide's valid action-verb list, but "Remove" is consistent with the function name and convention. Addresses one finding from Gemini Code Assist on PR #1139. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(areas): align ha_remove_area_or_floor runtime messages with verb Success and error messages still said "deleted/delete" while the function name and docstring already use "remove". Round out the verb alignment. --------- Co-authored-by: amccats3409 <amccats3409@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com>
…followup to #1016) (#1429) * refactor: remove duplicate flat area/floor list tools Removes `ha_config_list_areas` and `ha_config_list_floors`; their functionality is fully covered by `ha_list_floors_areas` (with the `fields=` and `area_fields=` projection params ported over). Finishes the consolidation that PR #1016's title promised but the implementation skipped — that PR was purely additive, leaving the two flat tools alongside the new nested-topology tool. Migrations: - Add `fields=` and `area_fields=` projection to `ha_list_floors_areas`; `area_fields=` applies uniformly across all 3 area buckets (nested, unassigned, orphaned), with the existing typo-guard warning behavior - Update src/ refs in tools_config_helpers.py and smart_search.py - Migrate e2e/workflows/areas/test_lifecycle.py (12 verification reads) with a small `_flatten_areas` helper for area-presence assertions - Migrate unit projection tests in tests/src/unit/test_tools_areas.py (delete two old test classes, add two new ones covering all 3 buckets) - Update tests/src/unit/test_fields_projection_docstring_completeness.py registry entry - Update UAT story catalog (s05, s10) and verify_story.py call site - Auto-regenerated docs (README, DOCS.md, tools.json) will refresh on merge via sync-tool-docs.yml Not breaking per AGENTS.md (functionality fully achievable via the combined tool). * chore(internal): apply ruff format to changed files Pre-existing master drift surfaced by ruff 0.15.13 (pinned in uv.lock) on three files this PR's previous commit touched. * fix: address review feedback from pre-merge audit - Drop stale comment reference to the now-deleted flat list tools (`tools_areas.py:183-184`) - Mirror `area_fields=[]` validation on `fields=[]` so empty-list projection is rejected symmetrically with VALIDATION_FAILED rather than silently collapsing the response (boy scout — asymmetry was inherited from the removed `ha_config_list_areas`) - Add empty-list rejection test for parity with the existing bad-shape tests - Augment `test_area_fields_unknown_key_emits_warning` to assert records are actually projected to {} across all 3 buckets (warning alone is necessary-but-not-sufficient; the deleted test had this check and the migration dropped it) - Seed an orphaned area in the TestListFloorsAreasFieldsProjection fixture so the shape test in test_no_fields_returns_full_response is non-vacuous on every bucket * docs(internal): clarify paired-facet docstrings on area/floor list tests After the consolidation to ha_list_floors_areas, these two tests now exercise the same endpoint. Docstrings updated to make explicit that they validate different facets (area-side vs floor-side) of the same combined response, not separate endpoints. * perf: parallelize area + floor registry fetches in ha_list_floors_areas Switches the two registry WS calls from sequential awaits to asyncio.gather(return_exceptions=True). Halves the tool-side WS latency (one round-trip max instead of two sequential). Preserves the existing post-fetch error contract: both per-registry success flags and response keys are still reported in SERVICE_CALL_FAILED context, and a transport-level exception on either side propagates to the broad exception handler for structured-error classification. Addresses initial BAT wall-time observation on this PR — sequential fetches were one structural contributor; response payload shape is the next lever if measurable regression persists. * fix(internal): narrow gather result types per-variable for mypy asyncio.gather(return_exceptions=True) types each result as `T | BaseException`. A loop-based isinstance check doesn't narrow the outer variables (`areas_result`, `floors_result`), so the subsequent .get() and ['result'] accesses tripped mypy on attribute access against BaseException. Replaced with two per-variable isinstance guards so mypy narrows each name to dict. * fix(internal): use indexed access + explicit annotations for gather results Tuple-unpacking from `asyncio.gather(return_exceptions=True)` triggers mypy `Cannot determine type [has-type]` errors at every downstream access — gather returns `list[Any]` which mypy can't statically narrow to a 2-tuple via destructuring. Switched to indexed access + explicit `dict[str, Any]` annotations after the isinstance guards, matching the pattern already in use in smart_search.py. --------- Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com>
….0 ) (#141) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.5.0` → `7.6.0` | --- ### Release Notes <details> <summary>homeassistant-ai/ha-mcp (ghcr.io/homeassistant-ai/ha-mcp)</summary> ### [`v7.6.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v760-2026-05-27) [Compare Source](homeassistant-ai/ha-mcp@v7.5.0...v7.6.0) ##### Added - Make HTTP bind host configurable via MCP\_HOST (closes [#​1434](homeassistant-ai/ha-mcp#1434)) ([#​1436](homeassistant-ai/ha-mcp#1436)) - Tool Security Policies — per-tool approval gating ([#​966](homeassistant-ai/ha-mcp#966)) ([#​1421](homeassistant-ai/ha-mcp#1421)) - Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target ([#​1424](homeassistant-ai/ha-mcp#1424)) - Auto-backup edited entities before write/destructive tool calls (closes [#​1288](homeassistant-ai/ha-mcp#1288)) ([#​1403](homeassistant-ai/ha-mcp#1403)) - Persistent settings UI for stdio mode ([#​1381](homeassistant-ai/ha-mcp#1381)) - Add fields= projection to ha\_search\_entities, ha\_get\_overview, ha\_get\_state, ha\_get\_history, ha\_config\_list\_areas, ha\_list\_services ([#​1199](homeassistant-ai/ha-mcp#1199)) ([#​1225](homeassistant-ai/ha-mcp#1225)) - Route entity-registration wait through WS events (closes [#​1152](homeassistant-ai/ha-mcp#1152)) ([#​1382](homeassistant-ai/ha-mcp#1382)) - Add config subentry support ([#​1393](homeassistant-ai/ha-mcp#1393)) - Add Assist pipeline management tool ([#​1392](homeassistant-ai/ha-mcp#1392)) - Add knx to ha\_config\_set\_yaml allowlist ([#​1374](homeassistant-ai/ha-mcp#1374)) - Extend automation\_id parity to set/remove automation responses ([#​1343](homeassistant-ai/ha-mcp#1343)) - **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon) ([#​1361](homeassistant-ai/ha-mcp#1361)) - Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#​1148](homeassistant-ai/ha-mcp#1148)) ([#​1328](homeassistant-ai/ha-mcp#1328)) - Return canonical script\_id from ha\_config\_get\_script ([#​1334](homeassistant-ai/ha-mcp#1334)) ([#​1352](homeassistant-ai/ha-mcp#1352)) - Add automation\_id parity key to ha\_config\_get\_automation ([#​1329](homeassistant-ai/ha-mcp#1329)) - Reject empty/whitespace identifiers on registry-metadata writes (closes [#​1294](homeassistant-ai/ha-mcp#1294)) ([#​1312](homeassistant-ai/ha-mcp#1312)) - Add HA brand assets for custom integration ([#​1317](homeassistant-ai/ha-mcp#1317)) - Unify ha\_config\_set\_helper response shape (closes [#​1293](homeassistant-ai/ha-mcp#1293)) ([#​1303](homeassistant-ai/ha-mcp#1303)) - Mirror create-side validation guards onto update path (closes [#​1292](homeassistant-ai/ha-mcp#1292)) ([#​1304](homeassistant-ai/ha-mcp#1304)) - Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST ([#​1063](homeassistant-ai/ha-mcp#1063)) ##### Changed - **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions ([#​1445](homeassistant-ai/ha-mcp#1445)) - Update contributors list \[contributors-updated] ([`c7665a6`](homeassistant-ai/ha-mcp@c7665a6)) - **overview**: Enumerate dismissed\_repair\_count in fields= description + static drift test ([#​1411](homeassistant-ai/ha-mcp#1411)) - Credit [@​tomwilkie](https://github.com/tomwilkie) and six other contributors in README ([#​1400](homeassistant-ai/ha-mcp#1400)) - **[#​1157](homeassistant-ai/ha-mcp#1157: Bump skills-vendor + auto-update via Renovate + native for: field + scrub eval\_template anti-patterns ([#​1383](homeassistant-ai/ha-mcp#1383)) - Extend Boy Scout weasel-phrase list with common variants; clarify semantic match ([#​1373](homeassistant-ai/ha-mcp#1373)) - Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate ([#​1359](homeassistant-ai/ha-mcp#1359)) - Categorize Issue Labels table and document 6 reverse-drift labels ([#​1335](homeassistant-ai/ha-mcp#1335)) - Strip stale L-refs from test\_identifier\_validation\_family docstrings ([#​1324](homeassistant-ai/ha-mcp#1324)) - Align label refs with live label set and fix triaged-removal trigger ([#​1316](homeassistant-ai/ha-mcp#1316)) - Surface tool-discovery / categorized search ([#​1123](homeassistant-ai/ha-mcp#1123)) - Fix two stale ha\_get\_skill\_guide references missed in [#​1289](homeassistant-ai/ha-mcp#1289) ([#​1305](homeassistant-ai/ha-mcp#1305)) - Clarify setup wizard placeholders need braces removed ([#​1284](homeassistant-ai/ha-mcp#1284)) ([#​1286](homeassistant-ai/ha-mcp#1286)) ##### Fixed - Remove counter from ha\_reload\_core targets ([#​1453](homeassistant-ai/ha-mcp#1453)) ([#​1456](homeassistant-ai/ha-mcp#1456)) - **backup**: Post-timeout match correctness + state-gate (closes [#​1433](homeassistant-ai/ha-mcp#1433)) ([#​1435](homeassistant-ai/ha-mcp#1435)) - Sync addon settings UI with Supervisor options end-to-end ([#​1420](homeassistant-ai/ha-mcp#1420)) - **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#​1413](homeassistant-ai/ha-mcp#1413), [#​1416](homeassistant-ai/ha-mcp#1416)) ([#​1418](homeassistant-ai/ha-mcp#1418)) - Error-shape consistency for non-entity not-found (closes [#​1297](homeassistant-ai/ha-mcp#1297)) ([#​1397](homeassistant-ai/ha-mcp#1397)) - Guard against silent automation overwrite on id mismatch ([#​1404](homeassistant-ai/ha-mcp#1404)) ([#​1405](homeassistant-ai/ha-mcp#1405)) - Cache YAML instance to prevent CPU spikes in bulk edits ([#​1370](homeassistant-ai/ha-mcp#1370)) ([#​1371](homeassistant-ai/ha-mcp#1371)) - **client**: Route get\_error\_log via hassio proxy on external-HAOS clients ([#​1360](homeassistant-ai/ha-mcp#1360)) - Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND ([#​1345](homeassistant-ai/ha-mcp#1345)) - Detect HA addon installs as http transport, not stdio ([#​1322](homeassistant-ai/ha-mcp#1322)) ([#​1327](homeassistant-ai/ha-mcp#1327)) - Actionable 403 suggestion when addon has unmapped container ports ([#​1319](homeassistant-ai/ha-mcp#1319)) ([#​1325](homeassistant-ai/ha-mcp#1325)) - Filter dismissed repairs in overview and system\_health ([#​1307](homeassistant-ai/ha-mcp#1307)) ([#​1309](homeassistant-ai/ha-mcp#1309)) - Exit on HA container death + daily reset before CI check ([#​1295](homeassistant-ai/ha-mcp#1295)) - Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#​1291](homeassistant-ai/ha-mcp#1291)) ([#​1301](homeassistant-ai/ha-mcp#1301)) - Allow str.replace in python\_transform; hint at search mode on IndexError ([#​1287](homeassistant-ai/ha-mcp#1287)) - **array\_patch**: Tighten validation and surface silent failures ([#​1285](homeassistant-ai/ha-mcp#1285)) - HA Core proxy fallback for ha\_get\_logs(source=system\_service) on non-addon installs ([#​1283](homeassistant-ai/ha-mcp#1283)) ##### Performance Improvements - Tighten \_poll\_for\_automation\_entity first-poll cadence ([#​1384](homeassistant-ai/ha-mcp#1384)) - Parallelize ha\_get\_system\_health optional sections via asyncio.gather ([#​1336](homeassistant-ai/ha-mcp#1336)) ##### Refactoring - **service**: Compact ha\_call\_service result default ([#​1446](homeassistant-ai/ha-mcp#1446)) ([#​1447](homeassistant-ai/ha-mcp#1447)) - Rename ha\_update\_device → ha\_set\_device ([#​1444](homeassistant-ai/ha-mcp#1444)) - Remove duplicate flat area/floor list tools (consolidation followup to [#​1016](homeassistant-ai/ha-mcp#1016)) ([#​1429](homeassistant-ai/ha-mcp#1429)) - **complexity**: Migrate tools\_utility.py to class-based pattern ([#​1423](homeassistant-ai/ha-mcp#1423)) - **complexity**: Reduce C901 violations in tools/ — batch 4 ([#​1408](homeassistant-ai/ha-mcp#1408)) - Route \_poll\_for\_automation\_entity through WS event waiter (closes [#​1395](homeassistant-ai/ha-mcp#1395)) ([#​1406](homeassistant-ai/ha-mcp#1406)) - **yaml**: Use threading.local subclass for cached instance ([#​1396](homeassistant-ai/ha-mcp#1396)) - Align dashboards 404 shape with sibling config tools ([#​1386](homeassistant-ai/ha-mcp#1386)) - Complete singular warning → warnings list migration repo-wide (closes [#​1332](homeassistant-ai/ha-mcp#1332)) ([#​1341](homeassistant-ai/ha-mcp#1341)) - Complete warnings-list migration for lifecycle-write tools ([#​1340](homeassistant-ai/ha-mcp#1340)) - Drop redundant identifier echo key from ha\_config\_get\_automation ([#​1354](homeassistant-ai/ha-mcp#1354)) - Drop logger.error in config-tool except blocks ([#​1302](homeassistant-ai/ha-mcp#1302)) ([#​1353](homeassistant-ai/ha-mcp#1353)) - Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#​1313](homeassistant-ai/ha-mcp#1313)) ([#​1321](homeassistant-ai/ha-mcp#1321)) - Migrate tools\_config\_scenes inline empty-id guards to shared helper ([#​1320](homeassistant-ai/ha-mcp#1320)) - Remove ha\_get\_helper\_schema (closes [#​1186](homeassistant-ai/ha-mcp#1186)) ([#​1315](homeassistant-ai/ha-mcp#1315)) - Consolidate skill tools; fix stable submodule packaging ([#​1289](homeassistant-ai/ha-mcp#1289)) - Align tools\_config\_automations.py error-handling with sibling pattern ([#​1290](homeassistant-ai/ha-mcp#1290)) ([#​1298](homeassistant-ai/ha-mcp#1298)) *** <details> <summary>Internal Changes</summary> ##### Fixed - **ci**: Install libguestfs in HAOS publish workflow ([#​1358](homeassistant-ai/ha-mcp#1358)) ##### Build System - **deps**: Bump esbuild from 0.24.2 to 0.25.0 in /tests/js ([#​1427](homeassistant-ai/ha-mcp#1427)) - **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site ([#​1282](homeassistant-ai/ha-mcp#1282)) - **deps**: Bump astro from 6.1.6 to 6.1.10 in /site ([#​1274](homeassistant-ai/ha-mcp#1274)) ##### Chores - **addon**: Publish dev addon version 7.5.0.dev360 \[skip ci] ([`ad7aed1`](homeassistant-ai/ha-mcp@ad7aed1)) - Sync tool docs after merge \[skip ci] ([`9c4984f`](homeassistant-ai/ha-mcp@9c4984f)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.4 ([#​1450](homeassistant-ai/ha-mcp#1450)) - **addon**: Publish dev addon version 7.5.0.dev359 \[skip ci] ([`b82d4ee`](homeassistant-ai/ha-mcp@b82d4ee)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.16 ([#​1449](homeassistant-ai/ha-mcp#1449)) - **addon**: Publish dev addon version 7.5.0.dev358 \[skip ci] ([`53fba6d`](homeassistant-ai/ha-mcp@53fba6d)) - Sync tool docs after merge \[skip ci] ([`dc7750d`](homeassistant-ai/ha-mcp@dc7750d)) - **addon**: Publish dev addon version 7.5.0.dev357 \[skip ci] ([`fd150c9`](homeassistant-ai/ha-mcp@fd150c9)) - **addon**: Publish dev addon version 7.5.0.dev356 \[skip ci] ([`5fa1463`](homeassistant-ai/ha-mcp@5fa1463)) - **addon**: Publish dev addon version 7.5.0.dev355 \[skip ci] ([`174ac5d`](homeassistant-ai/ha-mcp@174ac5d)) - **addon**: Publish dev addon version 7.5.0.dev354 \[skip ci] ([`4f93989`](homeassistant-ai/ha-mcp@4f93989)) - **addon**: Publish dev addon version 7.5.0.dev353 \[skip ci] ([`53f282f`](homeassistant-ai/ha-mcp@53f282f)) - **addon**: Publish dev addon version 7.5.0.dev352 \[skip ci] ([`4911d46`](homeassistant-ai/ha-mcp@4911d46)) - Sync tool docs after merge \[skip ci] ([`8a79837`](homeassistant-ai/ha-mcp@8a79837)) - **addon**: Publish dev addon version 7.5.0.dev351 \[skip ci] ([`13afa9d`](homeassistant-ai/ha-mcp@13afa9d)) - **addon**: Publish dev addon version 7.5.0.dev350 \[skip ci] ([`e93d680`](homeassistant-ai/ha-mcp@e93d680)) - **addon**: Publish dev addon version 7.5.0.dev349 \[skip ci] ([`1631ad1`](homeassistant-ai/ha-mcp@1631ad1)) - **addon**: Publish dev addon version 7.5.0.dev348 \[skip ci] ([`18a8aef`](homeassistant-ai/ha-mcp@18a8aef)) - Sync tool docs after merge \[skip ci] ([`9e0493d`](homeassistant-ai/ha-mcp@9e0493d)) - **addon**: Publish dev addon version 7.5.0.dev347 \[skip ci] ([`e2067e4`](homeassistant-ai/ha-mcp@e2067e4)) - Sync tool docs after merge \[skip ci] ([`7bdb3d4`](homeassistant-ai/ha-mcp@7bdb3d4)) - **addon**: Publish dev addon version 7.5.0.dev346 \[skip ci] ([`c2d4dd7`](homeassistant-ai/ha-mcp@c2d4dd7)) - Sync tool docs after merge \[skip ci] ([`393b354`](homeassistant-ai/ha-mcp@393b354)) - **addon**: Publish dev addon version 7.5.0.dev345 \[skip ci] ([`42ede8b`](homeassistant-ai/ha-mcp@42ede8b)) - **addon**: Publish dev addon version 7.5.0.dev344 \[skip ci] ([`e6cc7a1`](homeassistant-ai/ha-mcp@e6cc7a1)) - Sync tool docs after merge \[skip ci] ([`fb35f30`](homeassistant-ai/ha-mcp@fb35f30)) - **addon**: Publish dev addon version 7.5.0.dev343 \[skip ci] ([`401b7b4`](homeassistant-ai/ha-mcp@401b7b4)) - **addon**: Publish dev addon version 7.5.0.dev342 \[skip ci] ([`0679371`](homeassistant-ai/ha-mcp@0679371)) - Sync tool docs after merge \[skip ci] ([`f6796ec`](homeassistant-ai/ha-mcp@f6796ec)) - **addon**: Publish dev addon version 7.5.0.dev341 \[skip ci] ([`3654478`](homeassistant-ai/ha-mcp@3654478)) - **addon**: Publish dev addon version 7.5.0.dev340 \[skip ci] ([`64f00b6`](homeassistant-ai/ha-mcp@64f00b6)) - **addon**: Publish dev addon version 7.5.0.dev339 \[skip ci] ([`d6e8873`](homeassistant-ai/ha-mcp@d6e8873)) - Sync tool docs after merge \[skip ci] ([`7525e93`](homeassistant-ai/ha-mcp@7525e93)) - **addon**: Publish dev addon version 7.5.0.dev338 \[skip ci] ([`288ca4a`](homeassistant-ai/ha-mcp@288ca4a)) - **addon**: Publish dev addon version 7.5.0.dev337 \[skip ci] ([`f539ae5`](homeassistant-ai/ha-mcp@f539ae5)) - **addon**: Publish dev addon version 7.5.0.dev336 \[skip ci] ([`5568a86`](homeassistant-ai/ha-mcp@5568a86)) - **addon**: Publish dev addon version 7.5.0.dev335 \[skip ci] ([`e069405`](homeassistant-ai/ha-mcp@e069405)) - **addon**: Publish dev addon version 7.5.0.dev334 \[skip ci] ([`f7be6ea`](homeassistant-ai/ha-mcp@f7be6ea)) - **addon**: Publish dev addon version 7.5.0.dev333 \[skip ci] ([`cb480ea`](homeassistant-ai/ha-mcp@cb480ea)) - Sync tool docs after merge \[skip ci] ([`9a5bc3c`](homeassistant-ai/ha-mcp@9a5bc3c)) - **addon**: Publish dev addon version 7.5.0.dev332 \[skip ci] ([`e0e59ee`](homeassistant-ai/ha-mcp@e0e59ee)) - Sync tool docs after merge \[skip ci] ([`499ebf0`](homeassistant-ai/ha-mcp@499ebf0)) - **addon**: Publish dev addon version 7.5.0.dev331 \[skip ci] ([`3e0ce92`](homeassistant-ai/ha-mcp@3e0ce92)) - **addon**: Publish dev addon version 7.5.0.dev330 \[skip ci] ([`e48d056`](homeassistant-ai/ha-mcp@e48d056)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.15 ([#​1376](homeassistant-ai/ha-mcp#1376)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3 ([#​1377](homeassistant-ai/ha-mcp#1377)) - **addon**: Publish dev addon version 7.5.0.dev329 \[skip ci] ([`c523c50`](homeassistant-ai/ha-mcp@c523c50)) - Sync tool docs after merge \[skip ci] ([`5b7a8aa`](homeassistant-ai/ha-mcp@5b7a8aa)) - **addon**: Publish dev addon version 7.5.0.dev328 \[skip ci] ([`6c42fba`](homeassistant-ai/ha-mcp@6c42fba)) - **addon**: Publish dev addon version 7.5.0.dev327 \[skip ci] ([`aecd025`](homeassistant-ai/ha-mcp@aecd025)) - **addon**: Publish dev addon version 7.5.0.dev326 \[skip ci] ([`399c17c`](homeassistant-ai/ha-mcp@399c17c)) - **addon**: Publish dev addon version 7.5.0.dev325 \[skip ci] ([`b580b45`](homeassistant-ai/ha-mcp@b580b45)) - Sync tool docs after merge \[skip ci] ([`8567c3a`](homeassistant-ai/ha-mcp@8567c3a)) - **addon**: Publish dev addon version 7.5.0.dev324 \[skip ci] ([`a65579d`](homeassistant-ai/ha-mcp@a65579d)) - **addon**: Publish dev addon version 7.5.0.dev323 \[skip ci] ([`c7667ba`](homeassistant-ai/ha-mcp@c7667ba)) - **addon**: Publish dev addon version 7.5.0.dev322 \[skip ci] ([`44d15a8`](homeassistant-ai/ha-mcp@44d15a8)) - **addon**: Publish dev addon version 7.5.0.dev321 \[skip ci] ([`8739f6c`](homeassistant-ai/ha-mcp@8739f6c)) - **addon**: Publish dev addon version 7.5.0.dev320 \[skip ci] ([`02b6e47`](homeassistant-ai/ha-mcp@02b6e47)) - Sync tool docs after merge \[skip ci] ([`ab68c9a`](homeassistant-ai/ha-mcp@ab68c9a)) - **addon**: Publish dev addon version 7.5.0.dev319 \[skip ci] ([`4472904`](homeassistant-ai/ha-mcp@4472904)) - **addon**: Publish dev addon version 7.5.0.dev318 \[skip ci] ([`e030dbc`](homeassistant-ai/ha-mcp@e030dbc)) - **addon**: Publish dev addon version 7.5.0.dev317 \[skip ci] ([`d87855c`](homeassistant-ai/ha-mcp@d87855c)) - Sync tool docs after merge \[skip ci] ([`a72a4e8`](homeassistant-ai/ha-mcp@a72a4e8)) - **addon**: Publish dev addon version 7.5.0.dev316 \[skip ci] ([`bd9397f`](homeassistant-ai/ha-mcp@bd9397f)) - **addon**: Publish dev addon version 7.5.0.dev315 \[skip ci] ([`264bfc2`](homeassistant-ai/ha-mcp@264bfc2)) - **addon**: Publish dev addon version 7.5.0.dev314 \[skip ci] ([`df62881`](homeassistant-ai/ha-mcp@df62881)) - **addon**: Publish dev addon version 7.5.0.dev313 \[skip ci] ([`f6c47ca`](homeassistant-ai/ha-mcp@f6c47ca)) - **addon**: Publish dev addon version 7.5.0.dev312 \[skip ci] ([`2bb7a74`](homeassistant-ai/ha-mcp@2bb7a74)) - Sync tool docs after merge \[skip ci] ([`137e279`](homeassistant-ai/ha-mcp@137e279)) - **addon**: Publish dev addon version 7.5.0.dev311 \[skip ci] ([`28324ea`](homeassistant-ai/ha-mcp@28324ea)) - Sync tool docs after merge \[skip ci] ([`9a753d4`](homeassistant-ai/ha-mcp@9a753d4)) - **addon**: Publish dev addon version 7.5.0.dev310 \[skip ci] ([`f893b2e`](homeassistant-ai/ha-mcp@f893b2e)) - **addon**: Publish dev addon version 7.5.0.dev309 \[skip ci] ([`8cbdb7b`](homeassistant-ai/ha-mcp@8cbdb7b)) - **addon**: Publish dev addon version 7.5.0.dev308 \[skip ci] ([`2d18016`](homeassistant-ai/ha-mcp@2d18016)) - **addon**: Publish dev addon version 7.5.0.dev307 \[skip ci] ([`3fc3b28`](homeassistant-ai/ha-mcp@3fc3b28)) - Sync tool docs after merge \[skip ci] ([`9e6cff8`](homeassistant-ai/ha-mcp@9e6cff8)) - **addon**: Publish dev addon version 7.5.0.dev306 \[skip ci] ([`8bdd0fc`](homeassistant-ai/ha-mcp@8bdd0fc)) - **addon**: Publish dev addon version 7.5.0.dev305 \[skip ci] ([`83535b9`](homeassistant-ai/ha-mcp@83535b9)) - **addon**: Publish dev addon version 7.5.0.dev304 \[skip ci] ([`1435b3a`](homeassistant-ai/ha-mcp@1435b3a)) - **addon**: Publish dev addon version 7.5.0.dev303 \[skip ci] ([`e2da659`](homeassistant-ai/ha-mcp@e2da659)) - Sync tool docs after merge \[skip ci] ([`23789fa`](homeassistant-ai/ha-mcp@23789fa)) - **addon**: Publish dev addon version 7.5.0.dev302 \[skip ci] ([`6c8e574`](homeassistant-ai/ha-mcp@6c8e574)) - Sync tool docs after merge \[skip ci] ([`d2329cb`](homeassistant-ai/ha-mcp@d2329cb)) - **addon**: Publish dev addon version 7.5.0.dev301 \[skip ci] ([`bb538f7`](homeassistant-ai/ha-mcp@bb538f7)) - Sync tool docs after merge \[skip ci] ([`f70f0e1`](homeassistant-ai/ha-mcp@f70f0e1)) - **addon**: Publish version 7.5.0 \[skip ci] ([`9c5eb37`](homeassistant-ai/ha-mcp@9c5eb37)) ##### Continuous Integration - **deps**: Bump actions/upload-artifact in the github-actions group ([#​1437](homeassistant-ai/ha-mcp#1437)) - Share qcow2 cache + GHCR fallback between HAOS lanes ([#​1407](homeassistant-ai/ha-mcp#1407)) - Add ruff format --check on changed Python files ([#​1387](homeassistant-ai/ha-mcp#1387)) - Exempt assigned issues from stale bot ([#​1368](homeassistant-ai/ha-mcp#1368)) - **deps**: Bump the github-actions group with 3 updates ([#​1362](homeassistant-ai/ha-mcp#1362)) ##### Refactoring - Consolidate lovelace/dashboards/list through shared helper ([#​1344](homeassistant-ai/ha-mcp#1344)) ##### Testing - **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime ([#​1443](homeassistant-ai/ha-mcp#1443)) - **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep ([#​1430](homeassistant-ai/ha-mcp#1430)) - **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot ([#​1428](homeassistant-ai/ha-mcp#1428)) - JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script> ([#​1425](homeassistant-ai/ha-mcp#1425)) - **hacs**: Retry TestMcpToolsInstallation on flake ([#​1426](homeassistant-ai/ha-mcp#1426)) - **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#​1414](homeassistant-ai/ha-mcp#1414)) ([#​1419](homeassistant-ai/ha-mcp#1419)) - **e2e**: Assert backend dispatch matches workflow env on every lane ([#​1409](homeassistant-ai/ha-mcp#1409)) - Escape ideographic space and format file ([#​1237](homeassistant-ai/ha-mcp#1237)) ([#​1410](homeassistant-ai/ha-mcp#1410)) - **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#​1389](homeassistant-ai/ha-mcp#1389)) ([#​1398](homeassistant-ai/ha-mcp#1398)) - **e2e**: Wait for addon state=started in haos proxy header test ([#​1402](homeassistant-ai/ha-mcp#1402)) - Pin remaining \_classify\_by\_message branches ([#​1385](homeassistant-ai/ha-mcp#1385)) - **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#​1350](homeassistant-ai/ha-mcp#1350)) ([#​1379](homeassistant-ai/ha-mcp#1379)) - **haos-e2e**: Close out [#​1349](homeassistant-ai/ha-mcp#1349) — lifecycle, integrations, supervisor\_mock migration, no more skips ([#​1375](homeassistant-ai/ha-mcp#1375)) - **e2e**: Consolidate readiness gates onto /api/core/state (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1372](homeassistant-ai/ha-mcp#1372)) - **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1369](homeassistant-ai/ha-mcp#1369)) - Scaffold HAOS E2E tier image-build pipeline (refs [#​1281](homeassistant-ai/ha-mcp#1281)) ([#​1326](homeassistant-ai/ha-mcp#1326)) - **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1346](homeassistant-ai/ha-mcp#1346)) - **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1308](homeassistant-ai/ha-mcp#1308)) - **e2e**: Unify dict-error message extraction across e2e tests (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1311](homeassistant-ai/ha-mcp#1311)) - **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1310](homeassistant-ai/ha-mcp#1310)) </details> </details> --- ### Configuration 📅 **Schedule**: (in timezone America/New_York) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuNCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/141
…➔ 7.6.0) (#904) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.5.0` → `7.6.0` | --- ### Release Notes <details> <summary>homeassistant-ai/ha-mcp (ghcr.io/homeassistant-ai/ha-mcp)</summary> ### [`v7.6.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v760-2026-05-27) [Compare Source](homeassistant-ai/ha-mcp@v7.5.0...v7.6.0) ##### Added - Make HTTP bind host configurable via MCP\_HOST (closes [#​1434](homeassistant-ai/ha-mcp#1434)) ([#​1436](homeassistant-ai/ha-mcp#1436)) - Tool Security Policies — per-tool approval gating ([#​966](homeassistant-ai/ha-mcp#966)) ([#​1421](homeassistant-ai/ha-mcp#1421)) - Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target ([#​1424](homeassistant-ai/ha-mcp#1424)) - Auto-backup edited entities before write/destructive tool calls (closes [#​1288](homeassistant-ai/ha-mcp#1288)) ([#​1403](homeassistant-ai/ha-mcp#1403)) - Persistent settings UI for stdio mode ([#​1381](homeassistant-ai/ha-mcp#1381)) - Add fields= projection to ha\_search\_entities, ha\_get\_overview, ha\_get\_state, ha\_get\_history, ha\_config\_list\_areas, ha\_list\_services ([#​1199](homeassistant-ai/ha-mcp#1199)) ([#​1225](homeassistant-ai/ha-mcp#1225)) - Route entity-registration wait through WS events (closes [#​1152](homeassistant-ai/ha-mcp#1152)) ([#​1382](homeassistant-ai/ha-mcp#1382)) - Add config subentry support ([#​1393](homeassistant-ai/ha-mcp#1393)) - Add Assist pipeline management tool ([#​1392](homeassistant-ai/ha-mcp#1392)) - Add knx to ha\_config\_set\_yaml allowlist ([#​1374](homeassistant-ai/ha-mcp#1374)) - Extend automation\_id parity to set/remove automation responses ([#​1343](homeassistant-ai/ha-mcp#1343)) - **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon) ([#​1361](homeassistant-ai/ha-mcp#1361)) - Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#​1148](homeassistant-ai/ha-mcp#1148)) ([#​1328](homeassistant-ai/ha-mcp#1328)) - Return canonical script\_id from ha\_config\_get\_script ([#​1334](homeassistant-ai/ha-mcp#1334)) ([#​1352](homeassistant-ai/ha-mcp#1352)) - Add automation\_id parity key to ha\_config\_get\_automation ([#​1329](homeassistant-ai/ha-mcp#1329)) - Reject empty/whitespace identifiers on registry-metadata writes (closes [#​1294](homeassistant-ai/ha-mcp#1294)) ([#​1312](homeassistant-ai/ha-mcp#1312)) - Add HA brand assets for custom integration ([#​1317](homeassistant-ai/ha-mcp#1317)) - Unify ha\_config\_set\_helper response shape (closes [#​1293](homeassistant-ai/ha-mcp#1293)) ([#​1303](homeassistant-ai/ha-mcp#1303)) - Mirror create-side validation guards onto update path (closes [#​1292](homeassistant-ai/ha-mcp#1292)) ([#​1304](homeassistant-ai/ha-mcp#1304)) - Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST ([#​1063](homeassistant-ai/ha-mcp#1063)) ##### Changed - **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions ([#​1445](homeassistant-ai/ha-mcp#1445)) - Update contributors list \[contributors-updated] ([`c7665a6`](homeassistant-ai/ha-mcp@c7665a6)) - **overview**: Enumerate dismissed\_repair\_count in fields= description + static drift test ([#​1411](homeassistant-ai/ha-mcp#1411)) - Credit [@​tomwilkie](https://github.com/tomwilkie) and six other contributors in README ([#​1400](homeassistant-ai/ha-mcp#1400)) - **[#​1157](homeassistant-ai/ha-mcp#1157: Bump skills-vendor + auto-update via Renovate + native for: field + scrub eval\_template anti-patterns ([#​1383](homeassistant-ai/ha-mcp#1383)) - Extend Boy Scout weasel-phrase list with common variants; clarify semantic match ([#​1373](homeassistant-ai/ha-mcp#1373)) - Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate ([#​1359](homeassistant-ai/ha-mcp#1359)) - Categorize Issue Labels table and document 6 reverse-drift labels ([#​1335](homeassistant-ai/ha-mcp#1335)) - Strip stale L-refs from test\_identifier\_validation\_family docstrings ([#​1324](homeassistant-ai/ha-mcp#1324)) - Align label refs with live label set and fix triaged-removal trigger ([#​1316](homeassistant-ai/ha-mcp#1316)) - Surface tool-discovery / categorized search ([#​1123](homeassistant-ai/ha-mcp#1123)) - Fix two stale ha\_get\_skill\_guide references missed in [#​1289](homeassistant-ai/ha-mcp#1289) ([#​1305](homeassistant-ai/ha-mcp#1305)) - Clarify setup wizard placeholders need braces removed ([#​1284](homeassistant-ai/ha-mcp#1284)) ([#​1286](homeassistant-ai/ha-mcp#1286)) ##### Fixed - Remove counter from ha\_reload\_core targets ([#​1453](homeassistant-ai/ha-mcp#1453)) ([#​1456](homeassistant-ai/ha-mcp#1456)) - **backup**: Post-timeout match correctness + state-gate (closes [#​1433](homeassistant-ai/ha-mcp#1433)) ([#​1435](homeassistant-ai/ha-mcp#1435)) - Sync addon settings UI with Supervisor options end-to-end ([#​1420](homeassistant-ai/ha-mcp#1420)) - **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#​1413](homeassistant-ai/ha-mcp#1413), [#​1416](homeassistant-ai/ha-mcp#1416)) ([#​1418](homeassistant-ai/ha-mcp#1418)) - Error-shape consistency for non-entity not-found (closes [#​1297](homeassistant-ai/ha-mcp#1297)) ([#​1397](homeassistant-ai/ha-mcp#1397)) - Guard against silent automation overwrite on id mismatch ([#​1404](homeassistant-ai/ha-mcp#1404)) ([#​1405](homeassistant-ai/ha-mcp#1405)) - Cache YAML instance to prevent CPU spikes in bulk edits ([#​1370](homeassistant-ai/ha-mcp#1370)) ([#​1371](homeassistant-ai/ha-mcp#1371)) - **client**: Route get\_error\_log via hassio proxy on external-HAOS clients ([#​1360](homeassistant-ai/ha-mcp#1360)) - Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND ([#​1345](homeassistant-ai/ha-mcp#1345)) - Detect HA addon installs as http transport, not stdio ([#​1322](homeassistant-ai/ha-mcp#1322)) ([#​1327](homeassistant-ai/ha-mcp#1327)) - Actionable 403 suggestion when addon has unmapped container ports ([#​1319](homeassistant-ai/ha-mcp#1319)) ([#​1325](homeassistant-ai/ha-mcp#1325)) - Filter dismissed repairs in overview and system\_health ([#​1307](homeassistant-ai/ha-mcp#1307)) ([#​1309](homeassistant-ai/ha-mcp#1309)) - Exit on HA container death + daily reset before CI check ([#​1295](homeassistant-ai/ha-mcp#1295)) - Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#​1291](homeassistant-ai/ha-mcp#1291)) ([#​1301](homeassistant-ai/ha-mcp#1301)) - Allow str.replace in python\_transform; hint at search mode on IndexError ([#​1287](homeassistant-ai/ha-mcp#1287)) - **array\_patch**: Tighten validation and surface silent failures ([#​1285](homeassistant-ai/ha-mcp#1285)) - HA Core proxy fallback for ha\_get\_logs(source=system\_service) on non-addon installs ([#​1283](homeassistant-ai/ha-mcp#1283)) ##### Performance Improvements - Tighten \_poll\_for\_automation\_entity first-poll cadence ([#​1384](homeassistant-ai/ha-mcp#1384)) - Parallelize ha\_get\_system\_health optional sections via asyncio.gather ([#​1336](homeassistant-ai/ha-mcp#1336)) ##### Refactoring - **service**: Compact ha\_call\_service result default ([#​1446](homeassistant-ai/ha-mcp#1446)) ([#​1447](homeassistant-ai/ha-mcp#1447)) - Rename ha\_update\_device → ha\_set\_device ([#​1444](homeassistant-ai/ha-mcp#1444)) - Remove duplicate flat area/floor list tools (consolidation followup to [#​1016](homeassistant-ai/ha-mcp#1016)) ([#​1429](homeassistant-ai/ha-mcp#1429)) - **complexity**: Migrate tools\_utility.py to class-based pattern ([#​1423](homeassistant-ai/ha-mcp#1423)) - **complexity**: Reduce C901 violations in tools/ — batch 4 ([#​1408](homeassistant-ai/ha-mcp#1408)) - Route \_poll\_for\_automation\_entity through WS event waiter (closes [#​1395](homeassistant-ai/ha-mcp#1395)) ([#​1406](homeassistant-ai/ha-mcp#1406)) - **yaml**: Use threading.local subclass for cached instance ([#​1396](homeassistant-ai/ha-mcp#1396)) - Align dashboards 404 shape with sibling config tools ([#​1386](homeassistant-ai/ha-mcp#1386)) - Complete singular warning → warnings list migration repo-wide (closes [#​1332](homeassistant-ai/ha-mcp#1332)) ([#​1341](homeassistant-ai/ha-mcp#1341)) - Complete warnings-list migration for lifecycle-write tools ([#​1340](homeassistant-ai/ha-mcp#1340)) - Drop redundant identifier echo key from ha\_config\_get\_automation ([#​1354](homeassistant-ai/ha-mcp#1354)) - Drop logger.error in config-tool except blocks ([#​1302](homeassistant-ai/ha-mcp#1302)) ([#​1353](homeassistant-ai/ha-mcp#1353)) - Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#​1313](homeassistant-ai/ha-mcp#1313)) ([#​1321](homeassistant-ai/ha-mcp#1321)) - Migrate tools\_config\_scenes inline empty-id guards to shared helper ([#​1320](homeassistant-ai/ha-mcp#1320)) - Remove ha\_get\_helper\_schema (closes [#​1186](homeassistant-ai/ha-mcp#1186)) ([#​1315](homeassistant-ai/ha-mcp#1315)) - Consolidate skill tools; fix stable submodule packaging ([#​1289](homeassistant-ai/ha-mcp#1289)) - Align tools\_config\_automations.py error-handling with sibling pattern ([#​1290](homeassistant-ai/ha-mcp#1290)) ([#​1298](homeassistant-ai/ha-mcp#1298)) *** <details> <summary>Internal Changes</summary> ##### Fixed - **ci**: Install libguestfs in HAOS publish workflow ([#​1358](homeassistant-ai/ha-mcp#1358)) ##### Build System - **deps**: Bump esbuild from 0.24.2 to 0.25.0 in /tests/js ([#​1427](homeassistant-ai/ha-mcp#1427)) - **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site ([#​1282](homeassistant-ai/ha-mcp#1282)) - **deps**: Bump astro from 6.1.6 to 6.1.10 in /site ([#​1274](homeassistant-ai/ha-mcp#1274)) ##### Chores - **addon**: Publish dev addon version 7.5.0.dev360 \[skip ci] ([`ad7aed1`](homeassistant-ai/ha-mcp@ad7aed1)) - Sync tool docs after merge \[skip ci] ([`9c4984f`](homeassistant-ai/ha-mcp@9c4984f)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.4 ([#​1450](homeassistant-ai/ha-mcp#1450)) - **addon**: Publish dev addon version 7.5.0.dev359 \[skip ci] ([`b82d4ee`](homeassistant-ai/ha-mcp@b82d4ee)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.16 ([#​1449](homeassistant-ai/ha-mcp#1449)) - **addon**: Publish dev addon version 7.5.0.dev358 \[skip ci] ([`53fba6d`](homeassistant-ai/ha-mcp@53fba6d)) - Sync tool docs after merge \[skip ci] ([`dc7750d`](homeassistant-ai/ha-mcp@dc7750d)) - **addon**: Publish dev addon version 7.5.0.dev357 \[skip ci] ([`fd150c9`](homeassistant-ai/ha-mcp@fd150c9)) - **addon**: Publish dev addon version 7.5.0.dev356 \[skip ci] ([`5fa1463`](homeassistant-ai/ha-mcp@5fa1463)) - **addon**: Publish dev addon version 7.5.0.dev355 \[skip ci] ([`174ac5d`](homeassistant-ai/ha-mcp@174ac5d)) - **addon**: Publish dev addon version 7.5.0.dev354 \[skip ci] ([`4f93989`](homeassistant-ai/ha-mcp@4f93989)) - **addon**: Publish dev addon version 7.5.0.dev353 \[skip ci] ([`53f282f`](homeassistant-ai/ha-mcp@53f282f)) - **addon**: Publish dev addon version 7.5.0.dev352 \[skip ci] ([`4911d46`](homeassistant-ai/ha-mcp@4911d46)) - Sync tool docs after merge \[skip ci] ([`8a79837`](homeassistant-ai/ha-mcp@8a79837)) - **addon**: Publish dev addon version 7.5.0.dev351 \[skip ci] ([`13afa9d`](homeassistant-ai/ha-mcp@13afa9d)) - **addon**: Publish dev addon version 7.5.0.dev350 \[skip ci] ([`e93d680`](homeassistant-ai/ha-mcp@e93d680)) - **addon**: Publish dev addon version 7.5.0.dev349 \[skip ci] ([`1631ad1`](homeassistant-ai/ha-mcp@1631ad1)) - **addon**: Publish dev addon version 7.5.0.dev348 \[skip ci] ([`18a8aef`](homeassistant-ai/ha-mcp@18a8aef)) - Sync tool docs after merge \[skip ci] ([`9e0493d`](homeassistant-ai/ha-mcp@9e0493d)) - **addon**: Publish dev addon version 7.5.0.dev347 \[skip ci] ([`e2067e4`](homeassistant-ai/ha-mcp@e2067e4)) - Sync tool docs after merge \[skip ci] ([`7bdb3d4`](homeassistant-ai/ha-mcp@7bdb3d4)) - **addon**: Publish dev addon version 7.5.0.dev346 \[skip ci] ([`c2d4dd7`](homeassistant-ai/ha-mcp@c2d4dd7)) - Sync tool docs after merge \[skip ci] ([`393b354`](homeassistant-ai/ha-mcp@393b354)) - **addon**: Publish dev addon version 7.5.0.dev345 \[skip ci] ([`42ede8b`](homeassistant-ai/ha-mcp@42ede8b)) - **addon**: Publish dev addon version 7.5.0.dev344 \[skip ci] ([`e6cc7a1`](homeassistant-ai/ha-mcp@e6cc7a1)) - Sync tool docs after merge \[skip ci] ([`fb35f30`](homeassistant-ai/ha-mcp@fb35f30)) - **addon**: Publish dev addon version 7.5.0.dev343 \[skip ci] ([`401b7b4`](homeassistant-ai/ha-mcp@401b7b4)) - **addon**: Publish dev addon version 7.5.0.dev342 \[skip ci] ([`0679371`](homeassistant-ai/ha-mcp@0679371)) - Sync tool docs after merge \[skip ci] ([`f6796ec`](homeassistant-ai/ha-mcp@f6796ec)) - **addon**: Publish dev addon version 7.5.0.dev341 \[skip ci] ([`3654478`](homeassistant-ai/ha-mcp@3654478)) - **addon**: Publish dev addon version 7.5.0.dev340 \[skip ci] ([`64f00b6`](homeassistant-ai/ha-mcp@64f00b6)) - **addon**: Publish dev addon version 7.5.0.dev339 \[skip ci] ([`d6e8873`](homeassistant-ai/ha-mcp@d6e8873)) - Sync tool docs after merge \[skip ci] ([`7525e93`](homeassistant-ai/ha-mcp@7525e93)) - **addon**: Publish dev addon version 7.5.0.dev338 \[skip ci] ([`288ca4a`](homeassistant-ai/ha-mcp@288ca4a)) - **addon**: Publish dev addon version 7.5.0.dev337 \[skip ci] ([`f539ae5`](homeassistant-ai/ha-mcp@f539ae5)) - **addon**: Publish dev addon version 7.5.0.dev336 \[skip ci] ([`5568a86`](homeassistant-ai/ha-mcp@5568a86)) - **addon**: Publish dev addon version 7.5.0.dev335 \[skip ci] ([`e069405`](homeassistant-ai/ha-mcp@e069405)) - **addon**: Publish dev addon version 7.5.0.dev334 \[skip ci] ([`f7be6ea`](homeassistant-ai/ha-mcp@f7be6ea)) - **addon**: Publish dev addon version 7.5.0.dev333 \[skip ci] ([`cb480ea`](homeassistant-ai/ha-mcp@cb480ea)) - Sync tool docs after merge \[skip ci] ([`9a5bc3c`](homeassistant-ai/ha-mcp@9a5bc3c)) - **addon**: Publish dev addon version 7.5.0.dev332 \[skip ci] ([`e0e59ee`](homeassistant-ai/ha-mcp@e0e59ee)) - Sync tool docs after merge \[skip ci] ([`499ebf0`](homeassistant-ai/ha-mcp@499ebf0)) - **addon**: Publish dev addon version 7.5.0.dev331 \[skip ci] ([`3e0ce92`](homeassistant-ai/ha-mcp@3e0ce92)) - **addon**: Publish dev addon version 7.5.0.dev330 \[skip ci] ([`e48d056`](homeassistant-ai/ha-mcp@e48d056)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.15 ([#​1376](homeassistant-ai/ha-mcp#1376)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3 ([#​1377](homeassistant-ai/ha-mcp#1377)) - **addon**: Publish dev addon version 7.5.0.dev329 \[skip ci] ([`c523c50`](homeassistant-ai/ha-mcp@c523c50)) - Sync tool docs after merge \[skip ci] ([`5b7a8aa`](homeassistant-ai/ha-mcp@5b7a8aa)) - **addon**: Publish dev addon version 7.5.0.dev328 \[skip ci] ([`6c42fba`](homeassistant-ai/ha-mcp@6c42fba)) - **addon**: Publish dev addon version 7.5.0.dev327 \[skip ci] ([`aecd025`](homeassistant-ai/ha-mcp@aecd025)) - **addon**: Publish dev addon version 7.5.0.dev326 \[skip ci] ([`399c17c`](homeassistant-ai/ha-mcp@399c17c)) - **addon**: Publish dev addon version 7.5.0.dev325 \[skip ci] ([`b580b45`](homeassistant-ai/ha-mcp@b580b45)) - Sync tool docs after merge \[skip ci] ([`8567c3a`](homeassistant-ai/ha-mcp@8567c3a)) - **addon**: Publish dev addon version 7.5.0.dev324 \[skip ci] ([`a65579d`](homeassistant-ai/ha-mcp@a65579d)) - **addon**: Publish dev addon version 7.5.0.dev323 \[skip ci] ([`c7667ba`](homeassistant-ai/ha-mcp@c7667ba)) - **addon**: Publish dev addon version 7.5.0.dev322 \[skip ci] ([`44d15a8`](homeassistant-ai/ha-mcp@44d15a8)) - **addon**: Publish dev addon version 7.5.0.dev321 \[skip ci] ([`8739f6c`](homeassistant-ai/ha-mcp@8739f6c)) - **addon**: Publish dev addon version 7.5.0.dev320 \[skip ci] ([`02b6e47`](homeassistant-ai/ha-mcp@02b6e47)) - Sync tool docs after merge \[skip ci] ([`ab68c9a`](homeassistant-ai/ha-mcp@ab68c9a)) - **addon**: Publish dev addon version 7.5.0.dev319 \[skip ci] ([`4472904`](homeassistant-ai/ha-mcp@4472904)) - **addon**: Publish dev addon version 7.5.0.dev318 \[skip ci] ([`e030dbc`](homeassistant-ai/ha-mcp@e030dbc)) - **addon**: Publish dev addon version 7.5.0.dev317 \[skip ci] ([`d87855c`](homeassistant-ai/ha-mcp@d87855c)) - Sync tool docs after merge \[skip ci] ([`a72a4e8`](homeassistant-ai/ha-mcp@a72a4e8)) - **addon**: Publish dev addon version 7.5.0.dev316 \[skip ci] ([`bd9397f`](homeassistant-ai/ha-mcp@bd9397f)) - **addon**: Publish dev addon version 7.5.0.dev315 \[skip ci] ([`264bfc2`](homeassistant-ai/ha-mcp@264bfc2)) - **addon**: Publish dev addon version 7.5.0.dev314 \[skip ci] ([`df62881`](homeassistant-ai/ha-mcp@df62881)) - **addon**: Publish dev addon version 7.5.0.dev313 \[skip ci] ([`f6c47ca`](homeassistant-ai/ha-mcp@f6c47ca)) - **addon**: Publish dev addon version 7.5.0.dev312 \[skip ci] ([`2bb7a74`](homeassistant-ai/ha-mcp@2bb7a74)) - Sync tool docs after merge \[skip ci] ([`137e279`](homeassistant-ai/ha-mcp@137e279)) - **addon**: Publish dev addon version 7.5.0.dev311 \[skip ci] ([`28324ea`](homeassistant-ai/ha-mcp@28324ea)) - Sync tool docs after merge \[skip ci] ([`9a753d4`](homeassistant-ai/ha-mcp@9a753d4)) - **addon**: Publish dev addon version 7.5.0.dev310 \[skip ci] ([`f893b2e`](homeassistant-ai/ha-mcp@f893b2e)) - **addon**: Publish dev addon version 7.5.0.dev309 \[skip ci] ([`8cbdb7b`](homeassistant-ai/ha-mcp@8cbdb7b)) - **addon**: Publish dev addon version 7.5.0.dev308 \[skip ci] ([`2d18016`](homeassistant-ai/ha-mcp@2d18016)) - **addon**: Publish dev addon version 7.5.0.dev307 \[skip ci] ([`3fc3b28`](homeassistant-ai/ha-mcp@3fc3b28)) - Sync tool docs after merge \[skip ci] ([`9e6cff8`](homeassistant-ai/ha-mcp@9e6cff8)) - **addon**: Publish dev addon version 7.5.0.dev306 \[skip ci] ([`8bdd0fc`](homeassistant-ai/ha-mcp@8bdd0fc)) - **addon**: Publish dev addon version 7.5.0.dev305 \[skip ci] ([`83535b9`](homeassistant-ai/ha-mcp@83535b9)) - **addon**: Publish dev addon version 7.5.0.dev304 \[skip ci] ([`1435b3a`](homeassistant-ai/ha-mcp@1435b3a)) - **addon**: Publish dev addon version 7.5.0.dev303 \[skip ci] ([`e2da659`](homeassistant-ai/ha-mcp@e2da659)) - Sync tool docs after merge \[skip ci] ([`23789fa`](homeassistant-ai/ha-mcp@23789fa)) - **addon**: Publish dev addon version 7.5.0.dev302 \[skip ci] ([`6c8e574`](homeassistant-ai/ha-mcp@6c8e574)) - Sync tool docs after merge \[skip ci] ([`d2329cb`](homeassistant-ai/ha-mcp@d2329cb)) - **addon**: Publish dev addon version 7.5.0.dev301 \[skip ci] ([`bb538f7`](homeassistant-ai/ha-mcp@bb538f7)) - Sync tool docs after merge \[skip ci] ([`f70f0e1`](homeassistant-ai/ha-mcp@f70f0e1)) - **addon**: Publish version 7.5.0 \[skip ci] ([`9c5eb37`](homeassistant-ai/ha-mcp@9c5eb37)) ##### Continuous Integration - **deps**: Bump actions/upload-artifact in the github-actions group ([#​1437](homeassistant-ai/ha-mcp#1437)) - Share qcow2 cache + GHCR fallback between HAOS lanes ([#​1407](homeassistant-ai/ha-mcp#1407)) - Add ruff format --check on changed Python files ([#​1387](homeassistant-ai/ha-mcp#1387)) - Exempt assigned issues from stale bot ([#​1368](homeassistant-ai/ha-mcp#1368)) - **deps**: Bump the github-actions group with 3 updates ([#​1362](homeassistant-ai/ha-mcp#1362)) ##### Refactoring - Consolidate lovelace/dashboards/list through shared helper ([#​1344](homeassistant-ai/ha-mcp#1344)) ##### Testing - **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime ([#​1443](homeassistant-ai/ha-mcp#1443)) - **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep ([#​1430](homeassistant-ai/ha-mcp#1430)) - **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot ([#​1428](homeassistant-ai/ha-mcp#1428)) - JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script> ([#​1425](homeassistant-ai/ha-mcp#1425)) - **hacs**: Retry TestMcpToolsInstallation on flake ([#​1426](homeassistant-ai/ha-mcp#1426)) - **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#​1414](homeassistant-ai/ha-mcp#1414)) ([#​1419](homeassistant-ai/ha-mcp#1419)) - **e2e**: Assert backend dispatch matches workflow env on every lane ([#​1409](homeassistant-ai/ha-mcp#1409)) - Escape ideographic space and format file ([#​1237](homeassistant-ai/ha-mcp#1237)) ([#​1410](homeassistant-ai/ha-mcp#1410)) - **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#​1389](homeassistant-ai/ha-mcp#1389)) ([#​1398](homeassistant-ai/ha-mcp#1398)) - **e2e**: Wait for addon state=started in haos proxy header test ([#​1402](homeassistant-ai/ha-mcp#1402)) - Pin remaining \_classify\_by\_message branches ([#​1385](homeassistant-ai/ha-mcp#1385)) - **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#​1350](homeassistant-ai/ha-mcp#1350)) ([#​1379](homeassistant-ai/ha-mcp#1379)) - **haos-e2e**: Close out [#​1349](homeassistant-ai/ha-mcp#1349) — lifecycle, integrations, supervisor\_mock migration, no more skips ([#​1375](homeassistant-ai/ha-mcp#1375)) - **e2e**: Consolidate readiness gates onto /api/core/state (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1372](homeassistant-ai/ha-mcp#1372)) - **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1369](homeassistant-ai/ha-mcp#1369)) - Scaffold HAOS E2E tier image-build pipeline (refs [#​1281](homeassistant-ai/ha-mcp#1281)) ([#​1326](homeassistant-ai/ha-mcp#1326)) - **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1346](homeassistant-ai/ha-mcp#1346)) - **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1308](homeassistant-ai/ha-mcp#1308)) - **e2e**: Unify dict-error message extraction across e2e tests (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1311](homeassistant-ai/ha-mcp#1311)) - **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#​366](homeassistant-ai/ha-mcp#366)) ([#​1310](homeassistant-ai/ha-mcp#1310)) </details> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/904
…➔ 7.7.0) (#994)
This PR contains the following updates:
| Package | Update | Change |
|---|---|---|
| [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.5.0` → `7.7.0` |
---
### Release Notes
<details>
<summary>homeassistant-ai/ha-mcp (ghcr.io/homeassistant-ai/ha-mcp)</summary>
### [`v7.7.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v770-2026-06-10)
[Compare Source](https://github.com/homeassistant-ai/ha-mcp/compare/v7.6.0...v7.7.0)
##### Added
- User-configurable custom filesystem directories for the file tools (closes [#​1567](https://github.com/homeassistant-ai/ha-mcp/issues/1567))
([#​1568](https://github.com/homeassistant-ai/ha-mcp/pull/1568))
- Expose all user-tunable env vars in the settings UI (add-on parity)
([#​1554](https://github.com/homeassistant-ai/ha-mcp/pull/1554))
- Warn when default MCP\_SECRET\_PATH is bound non-loopback
([#​1472](https://github.com/homeassistant-ai/ha-mcp/pull/1472))
- **search**: Consolidate ha\_search\_entities + ha\_deep\_search into ha\_search
([#​1529](https://github.com/homeassistant-ai/ha-mcp/pull/1529))
- **addon**: Install the MCP Server add-on from the ha\_mcp\_tools integration
([#​1528](https://github.com/homeassistant-ai/ha-mcp/pull/1528))
- Add opt-in dashboard screenshot mode
([#​1510](https://github.com/homeassistant-ai/ha-mcp/pull/1510))
- Add Linux support for install & docs
([#​1096](https://github.com/homeassistant-ai/ha-mcp/pull/1096))
- Surface the web settings page for non-add-on installs ([#​1458](https://github.com/homeassistant-ai/ha-mcp/issues/1458))
([#​1511](https://github.com/homeassistant-ai/ha-mcp/pull/1511))
- Convert Pydantic arg-validation errors to actionable ToolErrors
([#​1491](https://github.com/homeassistant-ai/ha-mcp/pull/1491))
- Per-key toggles for automation/script/scene in packages/\*.yaml
([#​1476](https://github.com/homeassistant-ai/ha-mcp/pull/1476))
- Direct skills retrieval for write tools + improved best practice checker warnings with embedded skills responses ([#​1182](https://github.com/homeassistant-ai/ha-mcp/issues/1182))
([#​1448](https://github.com/homeassistant-ai/ha-mcp/pull/1448))
- Detect last\_changed/last\_updated duration math and suggest for: field ([#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157))
([#​1264](https://github.com/homeassistant-ai/ha-mcp/pull/1264))
- Advanced settings panel + nested beta master toggle ([#​1164](https://github.com/homeassistant-ai/ha-mcp/issues/1164))
([#​1431](https://github.com/homeassistant-ai/ha-mcp/pull/1431))
- Allow automation/script/scene yaml\_path in packages/\*.yaml only
([#​1452](https://github.com/homeassistant-ai/ha-mcp/pull/1452))
- Restrict ha\_mcp\_tools services to ha-mcp callers (caller token + ha\_call\_service refusal)
([#​1459](https://github.com/homeassistant-ai/ha-mcp/pull/1459))
##### Changed
- **security**: Soften vulnerability-response SLA to best-effort
([`a24e7da`](https://github.com/homeassistant-ai/ha-mcp/commit/a24e7da4787aad570ac2998a5732de06229fa160))
- Update contributors list \[contributors-updated]
([`7cc187f`](https://github.com/homeassistant-ai/ha-mcp/commit/7cc187f4de2f6eb58cafaa4fb21f8016cb180a61))
- Telemetry wording — follow HA analytics setting, not opt-in-only
([#​1481](https://github.com/homeassistant-ai/ha-mcp/pull/1481))
- **security**: Note that security-advisory disposition is API-blind (UI-only)
([#​1561](https://github.com/homeassistant-ai/ha-mcp/pull/1561))
- **tools**: Sharpen ha\_eval\_template usage routing for compute-from-state queries
([#​1550](https://github.com/homeassistant-ai/ha-mcp/pull/1550))
- Differentiate ha-mcp from Home Assistant's built-in MCP Server
([#​1542](https://github.com/homeassistant-ai/ha-mcp/pull/1542))
- Update advanced mode notes
([#​1533](https://github.com/homeassistant-ai/ha-mcp/pull/1533))
- **[#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157)**: Scripts native-for: guidance + fix numeric\_state-condition for: overclaim
([#​1480](https://github.com/homeassistant-ai/ha-mcp/pull/1480))
- Clarify add-on vs uvx; add Codex + HTTP-native client setup
([#​1478](https://github.com/homeassistant-ai/ha-mcp/pull/1478))
- **security**: Explicit threat model for trusted clients, LAN, sandbox, and OAuth tokens
([#​1463](https://github.com/homeassistant-ai/ha-mcp/pull/1463))
- Clarify telemetry is a planned future feature, not implemented
([#​1469](https://github.com/homeassistant-ai/ha-mcp/pull/1469))
##### Fixed
- **tools**: Bring HA API field names to 2026.6 — stale docstrings, automation plural canonicalization, fan speed (closes [#​1540](https://github.com/homeassistant-ai/ha-mcp/issues/1540))
([#​1566](https://github.com/homeassistant-ai/ha-mcp/pull/1566))
- **energy**: Accept "water" energy source in ha\_manage\_energy\_prefs
([#​1553](https://github.com/homeassistant-ai/ha-mcp/pull/1553))
- **tools**: Use action: not service: in automation docstring examples
([#​1539](https://github.com/homeassistant-ai/ha-mcp/pull/1539))
- **security**: Narrow GHSA-mc92-ww4q-6fg4 to the masker and log redaction
([#​1512](https://github.com/homeassistant-ai/ha-mcp/pull/1512))
- **addon**: Restrict settings UI root routes to HA ingress
([#​1508](https://github.com/homeassistant-ai/ha-mcp/pull/1508))
- Add name attributes to generated settings-UI form controls (a11y)
([#​1497](https://github.com/homeassistant-ai/ha-mcp/pull/1497))
- Add-on-aware code-mode locked note + suppress settings-UI favicon 404
([#​1494](https://github.com/homeassistant-ai/ha-mcp/pull/1494))
- Surface the real reason a WebSocket connection failed
([#​1495](https://github.com/homeassistant-ai/ha-mcp/pull/1495))
- Remove str from ha\_bulk\_control.operations schema + fix wrong-reason test
([#​1492](https://github.com/homeassistant-ai/ha-mcp/pull/1492))
- Remove str from bool/int param schemas across all tools
([#​1490](https://github.com/homeassistant-ai/ha-mcp/pull/1490))
- **addon**: Expose non-beta tool options on the stable add-on
([#​1488](https://github.com/homeassistant-ai/ha-mcp/pull/1488))
- **addon**: Enable ingress so the stable add-on shows the Open Web UI / Settings UI
([#​1486](https://github.com/homeassistant-ai/ha-mcp/pull/1486))
- Refine last\_changed/last\_updated duration-math detector ([#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157))
([#​1483](https://github.com/homeassistant-ai/ha-mcp/pull/1483))
- Remove str from config param schema on service and entity tools
([#​1487](https://github.com/homeassistant-ai/ha-mcp/pull/1487))
- Surface flow-helper config to agents reading UI-created templates
([#​1474](https://github.com/homeassistant-ai/ha-mcp/pull/1474))
- Remove str from config param schema on set tools
([#​1485](https://github.com/homeassistant-ai/ha-mcp/pull/1485))
- Route malformed ha\_mcp\_tools version to a distinct reinstall error
([#​1484](https://github.com/homeassistant-ai/ha-mcp/pull/1484))
- Persist DCR client registrations and HMAC secret across restarts ([#​1261](https://github.com/homeassistant-ai/ha-mcp/issues/1261))
([#​1265](https://github.com/homeassistant-ai/ha-mcp/pull/1265))
- Stop dev builds from publishing the :latest Docker tag
([#​1477](https://github.com/homeassistant-ai/ha-mcp/pull/1477))
- Subscribe to HACS dispatch signal instead of 10x1s blind poll
([#​1455](https://github.com/homeassistant-ai/ha-mcp/pull/1455))
- Reject python\_transform while loops
([#​1462](https://github.com/homeassistant-ai/ha-mcp/pull/1462))
##### Performance Improvements
- Fast-fail HACS not-found lookups + batch-verify deep-search E2E fixtures ([#​1515](https://github.com/homeassistant-ai/ha-mcp/issues/1515))
([#​1552](https://github.com/homeassistant-ai/ha-mcp/pull/1552))
##### Refactoring
- Add display title to ha\_get\_skill\_guide tool
([#​1543](https://github.com/homeassistant-ai/ha-mcp/pull/1543))
- Fold ha\_check\_config into ha\_get\_system\_health include="config\_check"
([#​1516](https://github.com/homeassistant-ai/ha-mcp/pull/1516))
- **c901**: Smart\_search.py below C901 threshold
([#​1507](https://github.com/homeassistant-ai/ha-mcp/pull/1507))
- **hacs**: Consolidate HACS tools into ha\_get\_hacs + ha\_manage\_hacs ([#​1045](https://github.com/homeassistant-ai/ha-mcp/issues/1045))
([#​1502](https://github.com/homeassistant-ai/ha-mcp/pull/1502))
- **c901**: Tools\_config\_helpers.py below C901 threshold
([#​1498](https://github.com/homeassistant-ai/ha-mcp/pull/1498))
- **complexity**: Reduce C901 in tools\_addons.py via class-based pattern
([#​1432](https://github.com/homeassistant-ai/ha-mcp/pull/1432))
***
<details>
<summary>Internal Changes</summary>
##### Changed
- Trim AGENTS.md below 40k + improve subdirectory CLAUDE.md files
([#​1499](https://github.com/homeassistant-ai/ha-mcp/pull/1499))
##### Chores
- **addon**: Publish dev addon version 7.6.0.dev415 \[skip ci]
([`2c0148b`](https://github.com/homeassistant-ai/ha-mcp/commit/2c0148ba512a02b5299edbb4086c38410777a295))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.6.1
([#​1571](https://github.com/homeassistant-ai/ha-mcp/pull/1571))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.19
([#​1570](https://github.com/homeassistant-ai/ha-mcp/pull/1570))
- **addon**: Publish dev addon version 7.6.0.dev414 \[skip ci]
([`0bf9e39`](https://github.com/homeassistant-ai/ha-mcp/commit/0bf9e39947e8bf87d18bae23877d6b0d955dd35f))
- Sync tool docs after merge \[skip ci]
([`8f5e037`](https://github.com/homeassistant-ai/ha-mcp/commit/8f5e037b89296fd483888d158d8f72f4b1b7dfa8))
- **addon**: Publish dev addon version 7.6.0.dev413 \[skip ci]
([`6729327`](https://github.com/homeassistant-ai/ha-mcp/commit/6729327de8c0747f5cc7bb639859f95bbe1f0cfc))
- Sync tool docs after merge \[skip ci]
([`4341e95`](https://github.com/homeassistant-ai/ha-mcp/commit/4341e9574b3270c67bc016676f854f585fec816f))
- **addon**: Publish dev addon version 7.6.0.dev412 \[skip ci]
([`148f506`](https://github.com/homeassistant-ai/ha-mcp/commit/148f506a98c8f89292616a3a05dd0c9156516439))
- **addon**: Publish dev addon version 7.6.0.dev411 \[skip ci]
([`287fe55`](https://github.com/homeassistant-ai/ha-mcp/commit/287fe5503917e551f2dcb363cd28250237ed880c))
- Sync tool docs after merge \[skip ci]
([`b642b8e`](https://github.com/homeassistant-ai/ha-mcp/commit/b642b8eba67d8015d8fe5a1c1f88c9dd72ffc45f))
- **addon**: Publish dev addon version 7.6.0.dev410 \[skip ci]
([`29e34dd`](https://github.com/homeassistant-ai/ha-mcp/commit/29e34dd6eb517399de3c0a6a886e45ecf4749923))
- **addon**: Publish dev addon version 7.6.0.dev409 \[skip ci]
([`dec16a1`](https://github.com/homeassistant-ai/ha-mcp/commit/dec16a12d2ac3341908b130e9ea79f950d02466b))
- Sync tool docs after merge \[skip ci]
([`dd72535`](https://github.com/homeassistant-ai/ha-mcp/commit/dd725357f5d48a00959aaa7eceb4bad67a7ba202))
- **addon**: Publish dev addon version 7.6.0.dev408 \[skip ci]
([`c3c89f1`](https://github.com/homeassistant-ai/ha-mcp/commit/c3c89f1a758b6086b59ff21f9044597da103fa25))
- **addon**: Publish dev addon version 7.6.0.dev407 \[skip ci]
([`94195ee`](https://github.com/homeassistant-ai/ha-mcp/commit/94195ee4c8dbd0d8eec13d7c3d7ee392e5b7240f))
- **addon**: Publish dev addon version 7.6.0.dev406 \[skip ci]
([`f439424`](https://github.com/homeassistant-ai/ha-mcp/commit/f4394240dd1170f9d978e3c4a5011bab12f17f54))
- Sync tool docs after merge \[skip ci]
([`7464277`](https://github.com/homeassistant-ai/ha-mcp/commit/746427745d3debccea57c844278d1ba834d7ebfb))
- **addon**: Publish dev addon version 7.6.0.dev405 \[skip ci]
([`146eb07`](https://github.com/homeassistant-ai/ha-mcp/commit/146eb073a6f260ed0b0653cdb71346e9d29deae7))
- **addon**: Publish dev addon version 7.6.0.dev404 \[skip ci]
([`6a707bb`](https://github.com/homeassistant-ai/ha-mcp/commit/6a707bba576b987f8c3395adca3d59f7dd8a1050))
- Sync tool docs after merge \[skip ci]
([`85f3935`](https://github.com/homeassistant-ai/ha-mcp/commit/85f3935f80d9677f791b3098b201ec9c27e643be))
- **addon**: Publish dev addon version 7.6.0.dev403 \[skip ci]
([`be1fa1d`](https://github.com/homeassistant-ai/ha-mcp/commit/be1fa1dd2693170cbe3c037e7a88cf02f1847dcf))
- Sync tool docs after merge \[skip ci]
([`d9adbd2`](https://github.com/homeassistant-ai/ha-mcp/commit/d9adbd2c27750c9bc8faa55470d24564c48b3dbf))
- **addon**: Publish dev addon version 7.6.0.dev402 \[skip ci]
([`41ad7ca`](https://github.com/homeassistant-ai/ha-mcp/commit/41ad7caf1e0d982dd9e7bda3420ba3ca577cf765))
- **addon**: Publish dev addon version 7.6.0.dev401 \[skip ci]
([`8205034`](https://github.com/homeassistant-ai/ha-mcp/commit/820503485386f13dc66a0da3d304739e1f03dafd))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.18
([#​1523](https://github.com/homeassistant-ai/ha-mcp/pull/1523))
- **addon**: Publish dev addon version 7.6.0.dev400 \[skip ci]
([`532cdc4`](https://github.com/homeassistant-ai/ha-mcp/commit/532cdc440a8db053c524579f3e6b48b099c13c66))
- Sync tool docs after merge \[skip ci]
([`e2c08ff`](https://github.com/homeassistant-ai/ha-mcp/commit/e2c08ff797ffabf7b39bfc4b22b498b1c02ce1fa))
- **addon**: Publish dev addon version 7.6.0.dev399 \[skip ci]
([`9501348`](https://github.com/homeassistant-ai/ha-mcp/commit/95013488ea99761535ea9532285839bcd0ec8e3b))
- Sync tool docs after merge \[skip ci]
([`e70a050`](https://github.com/homeassistant-ai/ha-mcp/commit/e70a050efcb6edeb65d51dabd5307a192a22e66c))
- **addon**: Publish dev addon version 7.6.0.dev398 \[skip ci]
([`0b61424`](https://github.com/homeassistant-ai/ha-mcp/commit/0b61424ed823453dec27bb173d049f901eddc2d3))
- Sync tool docs after merge \[skip ci]
([`6df7987`](https://github.com/homeassistant-ai/ha-mcp/commit/6df79877669686a9fee3ec04979dff3960bc5e3f))
- **addon**: Publish dev addon version 7.6.0.dev397 \[skip ci]
([`c34915f`](https://github.com/homeassistant-ai/ha-mcp/commit/c34915f40cd82f83f0eb4af5c3a5655843608770))
- Sync tool docs after merge \[skip ci]
([`6f88e7e`](https://github.com/homeassistant-ai/ha-mcp/commit/6f88e7e0c8dcb7fee27792e0f87f6acd8aa892c4))
- **addon**: Publish dev addon version 7.6.0.dev396 \[skip ci]
([`1490e19`](https://github.com/homeassistant-ai/ha-mcp/commit/1490e190382454b17fc14cd362b17612a6af253f))
- Sync tool docs after merge \[skip ci]
([`ac2c7d0`](https://github.com/homeassistant-ai/ha-mcp/commit/ac2c7d038a90fb44466afa8f047378d7e8daed94))
- **addon**: Publish dev addon version 7.6.0.dev395 \[skip ci]
([`11e5ee8`](https://github.com/homeassistant-ai/ha-mcp/commit/11e5ee8f07f63f63b8cdf017397263c7602e80f6))
- **addon**: Publish dev addon version 7.6.0.dev394 \[skip ci]
([`5fc3e0f`](https://github.com/homeassistant-ai/ha-mcp/commit/5fc3e0f572bfd1bb367e65b3f4d78b96cb78fa91))
- Flag untrusted third-party content in HACS and add-on tool responses
([#​1509](https://github.com/homeassistant-ai/ha-mcp/pull/1509))
- **addon**: Publish dev addon version 7.6.0.dev393 \[skip ci]
([`9a37c28`](https://github.com/homeassistant-ai/ha-mcp/commit/9a37c28cfa0d1f3f652fe441ce2fe1d72a7360ab))
- **addon**: Publish dev addon version 7.6.0.dev392 \[skip ci]
([`4f737ac`](https://github.com/homeassistant-ai/ha-mcp/commit/4f737ac7c116e9afa046ab45b1230e2cdb5ae959))
- **addon**: Publish dev addon version 7.6.0.dev391 \[skip ci]
([`fd5d3f2`](https://github.com/homeassistant-ai/ha-mcp/commit/fd5d3f2d4ce87baa4cfcc85a173bb0cc9d132a35))
- **addon**: Publish dev addon version 7.6.0.dev390 \[skip ci]
([`28dedf4`](https://github.com/homeassistant-ai/ha-mcp/commit/28dedf43f3cd094b1c40fb50e535166cc8c33388))
- **addon**: Publish dev addon version 7.6.0.dev389 \[skip ci]
([`9443446`](https://github.com/homeassistant-ai/ha-mcp/commit/9443446fdd607a75d8db5fdad009130b188267d6))
- Sync tool docs after merge \[skip ci]
([`94fcbeb`](https://github.com/homeassistant-ai/ha-mcp/commit/94fcbeb14bd9cfa3bef274182f95e4562a379971))
- **addon**: Publish dev addon version 7.6.0.dev388 \[skip ci]
([`ccc1816`](https://github.com/homeassistant-ai/ha-mcp/commit/ccc18162eec520950c58cc8eabb2aac04ac57ab3))
- Drop dead entity\_cache attr + ruff-format fuzzy\_search.py
([#​1503](https://github.com/homeassistant-ai/ha-mcp/pull/1503))
- **addon**: Publish dev addon version 7.6.0.dev387 \[skip ci]
([`057c108`](https://github.com/homeassistant-ai/ha-mcp/commit/057c108b2958959bfee34225899b47b5c989a119))
- **addon**: Publish dev addon version 7.6.0.dev386 \[skip ci]
([`66f4ac6`](https://github.com/homeassistant-ai/ha-mcp/commit/66f4ac6a37d85412b895962afef1b03707400e56))
- **addon**: Publish dev addon version 7.6.0.dev385 \[skip ci]
([`f331f11`](https://github.com/homeassistant-ai/ha-mcp/commit/f331f1150f525a18bf5bd2e27007b46a07a3492c))
- **addon**: Publish dev addon version 7.6.0.dev384 \[skip ci]
([`17c319e`](https://github.com/homeassistant-ai/ha-mcp/commit/17c319e68ba4b4d4e6acd84deb57c588aafcb48b))
- Sync tool docs after merge \[skip ci]
([`f36cbb7`](https://github.com/homeassistant-ai/ha-mcp/commit/f36cbb7e620839b16808b37b61dbc7602557b409))
- **addon**: Publish dev addon version 7.6.0.dev383 \[skip ci]
([`782ba3b`](https://github.com/homeassistant-ai/ha-mcp/commit/782ba3b2bbcfe50564c5524d6a2c018a4c9c9ba6))
- **addon**: Publish dev addon version 7.6.0.dev382 \[skip ci]
([`b647ab6`](https://github.com/homeassistant-ai/ha-mcp/commit/b647ab6eea76a030c7e3c46f72d732ff339398fe))
- **addon**: Publish dev addon version 7.6.0.dev381 \[skip ci]
([`e999c24`](https://github.com/homeassistant-ai/ha-mcp/commit/e999c242553a60561ca06dbefe3177c627bb9e2d))
- Sync tool docs after merge \[skip ci]
([`50d76b0`](https://github.com/homeassistant-ai/ha-mcp/commit/50d76b04a0691c565fafaabc76fd4bd3cf321953))
- **addon**: Publish dev addon version 7.6.0.dev380 \[skip ci]
([`ebdc69b`](https://github.com/homeassistant-ai/ha-mcp/commit/ebdc69bde929fd3342234149956af0710b9f260a))
- Sync tool docs after merge \[skip ci]
([`1f03967`](https://github.com/homeassistant-ai/ha-mcp/commit/1f03967160156cbffdfc9fc7deb5ed9a2b25f2ba))
- **addon**: Publish dev addon version 7.6.0.dev379 \[skip ci]
([`7cabb2e`](https://github.com/homeassistant-ai/ha-mcp/commit/7cabb2ec342561dbc74251f7697e3c4df0a8fcb3))
- **addon**: Publish dev addon version 7.6.0.dev378 \[skip ci]
([`7b631c7`](https://github.com/homeassistant-ai/ha-mcp/commit/7b631c75e0e4163ee13906b90ddad7a1b744e402))
- **addon**: Publish dev addon version 7.6.0.dev377 \[skip ci]
([`ea7b614`](https://github.com/homeassistant-ai/ha-mcp/commit/ea7b614615606a8fc05a0a18cb9cafa2f0a42c0d))
- **addon**: Publish dev addon version 7.6.0.dev376 \[skip ci]
([`fd33ecd`](https://github.com/homeassistant-ai/ha-mcp/commit/fd33ecd4d260f5fc2ab4f229c90b1a4514c5ccde))
- Sync tool docs after merge \[skip ci]
([`ba8fae3`](https://github.com/homeassistant-ai/ha-mcp/commit/ba8fae3cc4f451dc65022756a86cce5275f6e35f))
- **addon**: Publish dev addon version 7.6.0.dev375 \[skip ci]
([`afcd0d8`](https://github.com/homeassistant-ai/ha-mcp/commit/afcd0d8e061e1cba65fd119727fc64ed77f1818d))
- Sync tool docs after merge \[skip ci]
([`f9b55ad`](https://github.com/homeassistant-ai/ha-mcp/commit/f9b55ad59c6f03d6a98c3d3f6dd52ba9ff7c8a7a))
- **addon**: Publish dev addon version 7.6.0.dev374 \[skip ci]
([`eecdf8b`](https://github.com/homeassistant-ai/ha-mcp/commit/eecdf8b058ba932ba94cfb292ebf2331a54d2def))
- Sync tool docs after merge \[skip ci]
([`ef16a8a`](https://github.com/homeassistant-ai/ha-mcp/commit/ef16a8a197c76e51a49ae6ac69eecb15d202a194))
- **addon**: Publish dev addon version 7.6.0.dev373 \[skip ci]
([`9a93703`](https://github.com/homeassistant-ai/ha-mcp/commit/9a9370362fe5573ac71cd6e90353877faccce8a6))
- **addon**: Publish dev addon version 7.6.0.dev372 \[skip ci]
([`7352ce8`](https://github.com/homeassistant-ai/ha-mcp/commit/7352ce88ef59feef74c29ab47f6991cc2ac132a8))
- **addon**: Publish dev addon version 7.6.0.dev371 \[skip ci]
([`d7601f5`](https://github.com/homeassistant-ai/ha-mcp/commit/d7601f5796308e1c42a01dbce9861460027a93c4))
- Sync tool docs after merge \[skip ci]
([`d0a4482`](https://github.com/homeassistant-ai/ha-mcp/commit/d0a448276306a08f8a52c4645f1b9c5aeaafd68e))
- **addon**: Publish dev addon version 7.6.0.dev370 \[skip ci]
([`f83c32c`](https://github.com/homeassistant-ai/ha-mcp/commit/f83c32c747ddaeccffb040bc28d3e08d7507ded4))
- **addon**: Publish dev addon version 7.6.0.dev369 \[skip ci]
([`ea16661`](https://github.com/homeassistant-ai/ha-mcp/commit/ea16661f1d144feada93aee119b625f968f990cb))
- **addon**: Publish dev addon version 7.6.0.dev368 \[skip ci]
([`af49ea5`](https://github.com/homeassistant-ai/ha-mcp/commit/af49ea5aff5c9f54914943cc2f8a67ebeea2fdee))
- **addon**: Publish dev addon version 7.6.0.dev367 \[skip ci]
([`7dd5f4c`](https://github.com/homeassistant-ai/ha-mcp/commit/7dd5f4cd0237ef4d80a454efe4dfc0801f18fdbd))
- **addon**: Publish dev addon version 7.6.0.dev366 \[skip ci]
([`6273b7e`](https://github.com/homeassistant-ai/ha-mcp/commit/6273b7ec8695706948eefe8e617cac39363940ce))
- Sync tool docs after merge \[skip ci]
([`4e3fd5f`](https://github.com/homeassistant-ai/ha-mcp/commit/4e3fd5f331ce5fefa8e0e5560da411de17f2a8db))
- **addon**: Publish dev addon version 7.6.0.dev365 \[skip ci]
([`f3bf17b`](https://github.com/homeassistant-ai/ha-mcp/commit/f3bf17be132ebc67005c33a3c8fde85025d56809))
- Sync tool docs after merge \[skip ci]
([`5307b60`](https://github.com/homeassistant-ai/ha-mcp/commit/5307b608879154fccf67bc1894f61e97f26719c6))
- **addon**: Publish dev addon version 7.6.0.dev364 \[skip ci]
([`76ec1ae`](https://github.com/homeassistant-ai/ha-mcp/commit/76ec1aefab8e904abf620bf1c1130e5f5d0c4bd9))
- Sync tool docs after merge \[skip ci]
([`be864b5`](https://github.com/homeassistant-ai/ha-mcp/commit/be864b5d685f167334487d4fe83324afbb4999ca))
- **addon**: Publish dev addon version 7.6.0.dev363 \[skip ci]
([`da10c75`](https://github.com/homeassistant-ai/ha-mcp/commit/da10c75a248dcc19442e4db6f34f325683cb0a71))
- **addon**: Publish dev addon version 7.6.0.dev362 \[skip ci]
([`69f4527`](https://github.com/homeassistant-ai/ha-mcp/commit/69f45279707d18c724bd702ced46111b26cd000c))
- **addon**: Publish version 7.6.0 \[skip ci]
([`086d75d`](https://github.com/homeassistant-ai/ha-mcp/commit/086d75d72dd7d1c735413d96ef2fd38ae57b90ca))
##### Continuous Integration
- Vendor Puppet add-on as a pinned submodule + retry transient add-on builds
([#​1565](https://github.com/homeassistant-ai/ha-mcp/pull/1565))
- Make sync-tool-docs push resilient to concurrent master advances
([#​1564](https://github.com/homeassistant-ai/ha-mcp/pull/1564))
- Fix stale token-cap comment and harden triage budget tests ([#​1514](https://github.com/homeassistant-ai/ha-mcp/issues/1514))
([#​1560](https://github.com/homeassistant-ai/ha-mcp/pull/1560))
- **deps**: Bump the github-actions group with 2 updates
([#​1556](https://github.com/homeassistant-ai/ha-mcp/pull/1556))
- Budget triage prompt dynamically under the GitHub Models cap ([#​1514](https://github.com/homeassistant-ai/ha-mcp/issues/1514))
([#​1522](https://github.com/homeassistant-ai/ha-mcp/pull/1522))
- Reduce Docker Hub pulls in performance-tests workflow
([#​1549](https://github.com/homeassistant-ai/ha-mcp/pull/1549))
- Add JavaScript to the CodeQL code-quality gate
([#​1548](https://github.com/homeassistant-ai/ha-mcp/pull/1548))
- Add CodeQL code-quality CI gate and clear all code-quality findings
([#​1526](https://github.com/homeassistant-ai/ha-mcp/pull/1526))
- Drop tool list from evaluate prompt + tighten caps to fit 8K token limit
([`6f47c92`](https://github.com/homeassistant-ai/ha-mcp/commit/6f47c92507ef0d854153632107c0c702812f0c3c))
- Remove broken maintainer check (GITHUB\_TOKEN lacks read:org)
([`010ec58`](https://github.com/homeassistant-ai/ha-mcp/commit/010ec58d1f3b6d46b20aa83c3caee373dd826694))
- Switch evaluate step to gpt-4o-mini (16K token free tier vs 8K on gpt-4.1)
([#​1496](https://github.com/homeassistant-ai/ha-mcp/pull/1496))
- Issue bot v2 — GitHub Models triage, needs-info auto-close, duplicate detection
([#​1442](https://github.com/homeassistant-ai/ha-mcp/pull/1442))
##### Refactoring
- Extract settings-UI JavaScript and CSS to separate files
([#​1505](https://github.com/homeassistant-ai/ha-mcp/pull/1505))
- Collapse settings-UI route registration into one table
([#​1504](https://github.com/homeassistant-ai/ha-mcp/pull/1504))
##### Testing
- **oauth**: Add HTTP smoke tests for OAuth metadata-discovery endpoints
([#​1562](https://github.com/homeassistant-ai/ha-mcp/pull/1562))
- **uat**: Relabel c01 as a mode-discrimination probe (taxonomy consistency)
([#​1563](https://github.com/homeassistant-ai/ha-mcp/pull/1563))
- **uat**: Rework c01 routing probe to ha\_search registry-listing mode after [#​1529](https://github.com/homeassistant-ai/ha-mcp/issues/1529)
([#​1559](https://github.com/homeassistant-ai/ha-mcp/pull/1559))
- **uat**: Add response\_contains\_any check and always log agent responses
([#​1537](https://github.com/homeassistant-ai/ha-mcp/pull/1537))
- **uat**: Treat request timeout as per-story failure, not suite abort
([#​1536](https://github.com/homeassistant-ai/ha-mcp/pull/1536))
- **uat**: Harden BAT story runner against agent crashes
([#​1535](https://github.com/homeassistant-ai/ha-mcp/pull/1535))
- **uat**: Log model and quantization in BAT story results
([#​1525](https://github.com/homeassistant-ai/ha-mcp/pull/1525))
- Capture reasoning tokens and detect inert --no-think in BAT openai agent
([#​1524](https://github.com/homeassistant-ai/ha-mcp/pull/1524))
</details>
### [`v7.6.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v760-2026-05-27)
[Compare Source](https://github.com/homeassistant-ai/ha-mcp/compare/v7.5.0...v7.6.0)
##### Added
- Make HTTP bind host configurable via MCP\_HOST (closes [#​1434](https://github.com/homeassistant-ai/ha-mcp/issues/1434))
([#​1436](https://github.com/homeassistant-ai/ha-mcp/pull/1436))
- Tool Security Policies — per-tool approval gating ([#​966](https://github.com/homeassistant-ai/ha-mcp/issues/966))
([#​1421](https://github.com/homeassistant-ai/ha-mcp/pull/1421))
- Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target
([#​1424](https://github.com/homeassistant-ai/ha-mcp/pull/1424))
- Auto-backup edited entities before write/destructive tool calls (closes [#​1288](https://github.com/homeassistant-ai/ha-mcp/issues/1288))
([#​1403](https://github.com/homeassistant-ai/ha-mcp/pull/1403))
- Persistent settings UI for stdio mode
([#​1381](https://github.com/homeassistant-ai/ha-mcp/pull/1381))
- Add fields= projection to ha\_search\_entities, ha\_get\_overview, ha\_get\_state, ha\_get\_history, ha\_config\_list\_areas, ha\_list\_services ([#​1199](https://github.com/homeassistant-ai/ha-mcp/issues/1199))
([#​1225](https://github.com/homeassistant-ai/ha-mcp/pull/1225))
- Route entity-registration wait through WS events (closes [#​1152](https://github.com/homeassistant-ai/ha-mcp/issues/1152))
([#​1382](https://github.com/homeassistant-ai/ha-mcp/pull/1382))
- Add config subentry support
([#​1393](https://github.com/homeassistant-ai/ha-mcp/pull/1393))
- Add Assist pipeline management tool
([#​1392](https://github.com/homeassistant-ai/ha-mcp/pull/1392))
- Add knx to ha\_config\_set\_yaml allowlist
([#​1374](https://github.com/homeassistant-ai/ha-mcp/pull/1374))
- Extend automation\_id parity to set/remove automation responses
([#​1343](https://github.com/homeassistant-ai/ha-mcp/pull/1343))
- **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon)
([#​1361](https://github.com/homeassistant-ai/ha-mcp/pull/1361))
- Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#​1148](https://github.com/homeassistant-ai/ha-mcp/issues/1148))
([#​1328](https://github.com/homeassistant-ai/ha-mcp/pull/1328))
- Return canonical script\_id from ha\_config\_get\_script ([#​1334](https://github.com/homeassistant-ai/ha-mcp/issues/1334))
([#​1352](https://github.com/homeassistant-ai/ha-mcp/pull/1352))
- Add automation\_id parity key to ha\_config\_get\_automation
([#​1329](https://github.com/homeassistant-ai/ha-mcp/pull/1329))
- Reject empty/whitespace identifiers on registry-metadata writes (closes [#​1294](https://github.com/homeassistant-ai/ha-mcp/issues/1294))
([#​1312](https://github.com/homeassistant-ai/ha-mcp/pull/1312))
- Add HA brand assets for custom integration
([#​1317](https://github.com/homeassistant-ai/ha-mcp/pull/1317))
- Unify ha\_config\_set\_helper response shape (closes [#​1293](https://github.com/homeassistant-ai/ha-mcp/issues/1293))
([#​1303](https://github.com/homeassistant-ai/ha-mcp/pull/1303))
- Mirror create-side validation guards onto update path (closes [#​1292](https://github.com/homeassistant-ai/ha-mcp/issues/1292))
([#​1304](https://github.com/homeassistant-ai/ha-mcp/pull/1304))
- Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST
([#​1063](https://github.com/homeassistant-ai/ha-mcp/pull/1063))
##### Changed
- **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions
([#​1445](https://github.com/homeassistant-ai/ha-mcp/pull/1445))
- Update contributors list \[contributors-updated]
([`c7665a6`](https://github.com/homeassistant-ai/ha-mcp/commit/c7665a6f5a08737d8fcbebbbe6afdc88ec5c4901))
- **overview**: Enumerate dismissed\_repair\_count in fields= description + static drift test
([#​1411](https://github.com/homeassistant-ai/ha-mcp/pull/1411))
- Credit [@​tomwilkie](https://github.com/tomwilkie) and six other contributors in README
([#​1400](https://github.com/homeassistant-ai/ha-mcp/pull/1400))
- **[#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157)**: Bump skills-vendor + auto-update via Renovate + native for: field + scrub eval\_template anti-patterns
([#​1383](https://github.com/homeassistant-ai/ha-mcp/pull/1383))
- Extend Boy Scout weasel-phrase list with common variants; clarify semantic match
([#​1373](https://github.com/homeassistant-ai/ha-mcp/pull/1373))
- Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate
([#​1359](https://github.com/homeassistant-ai/ha-mcp/pull/1359))
- Categorize Issue Labels table and document 6 reverse-drift labels
([#​1335](https://github.com/homeassistant-ai/ha-mcp/pull/1335))
- Strip stale L-refs from test\_identifier\_validation\_family docstrings
([#​1324](https://github.com/homeassistant-ai/ha-mcp/pull/1324))
- Align label refs with live label set and fix triaged-removal trigger
([#​1316](https://github.com/homeassistant-ai/ha-mcp/pull/1316))
- Surface tool-discovery / categorized search
([#​1123](https://github.com/homeassistant-ai/ha-mcp/pull/1123))
- Fix two stale ha\_get\_skill\_guide references missed in [#​1289](https://github.com/homeassistant-ai/ha-mcp/issues/1289)
([#​1305](https://github.com/homeassistant-ai/ha-mcp/pull/1305))
- Clarify setup wizard placeholders need braces removed ([#​1284](https://github.com/homeassistant-ai/ha-mcp/issues/1284))
([#​1286](https://github.com/homeassistant-ai/ha-mcp/pull/1286))
##### Fixed
- Remove counter from ha\_reload\_core targets ([#​1453](https://github.com/homeassistant-ai/ha-mcp/issues/1453))
([#​1456](https://github.com/homeassistant-ai/ha-mcp/pull/1456))
- **backup**: Post-timeout match correctness + state-gate (closes [#​1433](https://github.com/homeassistant-ai/ha-mcp/issues/1433))
([#​1435](https://github.com/homeassistant-ai/ha-mcp/pull/1435))
- Sync addon settings UI with Supervisor options end-to-end
([#​1420](https://github.com/homeassistant-ai/ha-mcp/pull/1420))
- **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#​1413](https://github.com/homeassistant-ai/ha-mcp/issues/1413), [#​1416](https://github.com/homeassistant-ai/ha-mcp/issues/1416))
([#​1418](https://github.com/homeassistant-ai/ha-mcp/pull/1418))
- Error-shape consistency for non-entity not-found (closes [#​1297](https://github.com/homeassistant-ai/ha-mcp/issues/1297))
([#​1397](https://github.com/homeassistant-ai/ha-mcp/pull/1397))
- Guard against silent automation overwrite on id mismatch ([#​1404](https://github.com/homeassistant-ai/ha-mcp/issues/1404))
([#​1405](https://github.com/homeassistant-ai/ha-mcp/pull/1405))
- Cache YAML instance to prevent CPU spikes in bulk edits ([#​1370](https://github.com/homeassistant-ai/ha-mcp/issues/1370))
([#​1371](https://github.com/homeassistant-ai/ha-mcp/pull/1371))
- **client**: Route get\_error\_log via hassio proxy on external-HAOS clients
([#​1360](https://github.com/homeassistant-ai/ha-mcp/pull/1360))
- Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND
([#​1345](https://github.com/homeassistant-ai/ha-mcp/pull/1345))
- Detect HA addon installs as http transport, not stdio ([#​1322](https://github.com/homeassistant-ai/ha-mcp/issues/1322))
([#​1327](https://github.com/homeassistant-ai/ha-mcp/pull/1327))
- Actionable 403 suggestion when addon has unmapped container ports ([#​1319](https://github.com/homeassistant-ai/ha-mcp/issues/1319))
([#​1325](https://github.com/homeassistant-ai/ha-mcp/pull/1325))
- Filter dismissed repairs in overview and system\_health ([#​1307](https://github.com/homeassistant-ai/ha-mcp/issues/1307))
([#​1309](https://github.com/homeassistant-ai/ha-mcp/pull/1309))
- Exit on HA container death + daily reset before CI check
([#​1295](https://github.com/homeassistant-ai/ha-mcp/pull/1295))
- Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#​1291](https://github.com/homeassistant-ai/ha-mcp/issues/1291))
([#​1301](https://github.com/homeassistant-ai/ha-mcp/pull/1301))
- Allow str.replace in python\_transform; hint at search mode on IndexError
([#​1287](https://github.com/homeassistant-ai/ha-mcp/pull/1287))
- **array\_patch**: Tighten validation and surface silent failures
([#​1285](https://github.com/homeassistant-ai/ha-mcp/pull/1285))
- HA Core proxy fallback for ha\_get\_logs(source=system\_service) on non-addon installs
([#​1283](https://github.com/homeassistant-ai/ha-mcp/pull/1283))
##### Performance Improvements
- Tighten \_poll\_for\_automation\_entity first-poll cadence
([#​1384](https://github.com/homeassistant-ai/ha-mcp/pull/1384))
- Parallelize ha\_get\_system\_health optional sections via asyncio.gather
([#​1336](https://github.com/homeassistant-ai/ha-mcp/pull/1336))
##### Refactoring
- **service**: Compact ha\_call\_service result default ([#​1446](https://github.com/homeassistant-ai/ha-mcp/issues/1446))
([#​1447](https://github.com/homeassistant-ai/ha-mcp/pull/1447))
- Rename ha\_update\_device → ha\_set\_device
([#​1444](https://github.com/homeassistant-ai/ha-mcp/pull/1444))
- Remove duplicate flat area/floor list tools (consolidation followup to [#​1016](https://github.com/homeassistant-ai/ha-mcp/issues/1016))
([#​1429](https://github.com/homeassistant-ai/ha-mcp/pull/1429))
- **complexity**: Migrate tools\_utility.py to class-based pattern
([#​1423](https://github.com/homeassistant-ai/ha-mcp/pull/1423))
- **complexity**: Reduce C901 violations in tools/ — batch 4
([#​1408](https://github.com/homeassistant-ai/ha-mcp/pull/1408))
- Route \_poll\_for\_automation\_entity through WS event waiter (closes [#​1395](https://github.com/homeassistant-ai/ha-mcp/issues/1395))
([#​1406](https://github.com/homeassistant-ai/ha-mcp/pull/1406))
- **yaml**: Use threading.local subclass for cached instance
([#​1396](https://github.com/homeassistant-ai/ha-mcp/pull/1396))
- Align dashboards 404 shape with sibling config tools
([#​1386](https://github.com/homeassistant-ai/ha-mcp/pull/1386))
- Complete singular warning → warnings list migration repo-wide (closes [#​1332](https://github.com/homeassistant-ai/ha-mcp/issues/1332))
([#​1341](https://github.com/homeassistant-ai/ha-mcp/pull/1341))
- Complete warnings-list migration for lifecycle-write tools
([#​1340](https://github.com/homeassistant-ai/ha-mcp/pull/1340))
- Drop redundant identifier echo key from ha\_config\_get\_automation
([#​1354](https://github.com/homeassistant-ai/ha-mcp/pull/1354))
- Drop logger.error in config-tool except blocks ([#​1302](https://github.com/homeassistant-ai/ha-mcp/issues/1302))
([#​1353](https://github.com/homeassistant-ai/ha-mcp/pull/1353))
- Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#​1313](https://github.com/homeassistant-ai/ha-mcp/issues/1313))
([#​1321](https://github.com/homeassistant-ai/ha-mcp/pull/1321))
- Migrate tools\_config\_scenes inline empty-id guards to shared helper
([#​1320](https://github.com/homeassistant-ai/ha-mcp/pull/1320))
- Remove ha\_get\_helper\_schema (closes [#​1186](https://github.com/homeassistant-ai/ha-mcp/issues/1186))
([#​1315](https://github.com/homeassistant-ai/ha-mcp/pull/1315))
- Consolidate skill tools; fix stable submodule packaging
([#​1289](https://github.com/homeassistant-ai/ha-mcp/pull/1289))
- Align tools\_config\_automations.py error-handling with sibling pattern ([#​1290](https://github.com/homeassistant-ai/ha-mcp/issues/1290))
([#​1298](https://github.com/homeassistant-ai/ha-mcp/pull/1298))
***
<details>
<summary>Internal Changes</summary>
##### Fixed
- **ci**: Install libguestfs in HAOS publish workflow
([#​1358](https://github.com/homeassistant-ai/ha-mcp/pull/1358))
##### Build System
- **deps**: Bump esbuild from 0.24.2 to 0.25.0 in /tests/js
([#​1427](https://github.com/homeassistant-ai/ha-mcp/pull/1427))
- **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site
([#​1282](https://github.com/homeassistant-ai/ha-mcp/pull/1282))
- **deps**: Bump astro from 6.1.6 to 6.1.10 in /site
([#​1274](https://github.com/homeassistant-ai/ha-mcp/pull/1274))
##### Chores
- **addon**: Publish dev addon version 7.5.0.dev360 \[skip ci]
([`ad7aed1`](https://github.com/homeassistant-ai/ha-mcp/commit/ad7aed13d6843967e2a259ae46fec2bbc6abc896))
- Sync tool docs after merge \[skip ci]
([`9c4984f`](https://github.com/homeassistant-ai/ha-mcp/commit/9c4984fc44d30c15a96372fbc1b401fbd679dc8f))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.4
([#​1450](https://github.com/homeassistant-ai/ha-mcp/pull/1450))
- **addon**: Publish dev addon version 7.5.0.dev359 \[skip ci]
([`b82d4ee`](https://github.com/homeassistant-ai/ha-mcp/commit/b82d4eea85792b620368d4859e99c143f9fbfadf))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.16
([#​1449](https://github.com/homeassistant-ai/ha-mcp/pull/1449))
- **addon**: Publish dev addon version 7.5.0.dev358 \[skip ci]
([`53fba6d`](https://github.com/homeassistant-ai/ha-mcp/commit/53fba6da76ce8c78a0de035883233a36762601bc))
- Sync tool docs after merge \[skip ci]
([`dc7750d`](https://github.com/homeassistant-ai/ha-mcp/commit/dc7750de16b60f70e40e6e5c8908d9e84e544683))
- **addon**: Publish dev addon version 7.5.0.dev357 \[skip ci]
([`fd150c9`](https://github.com/homeassistant-ai/ha-mcp/commit/fd150c9b9c4bdb9026e67eae340226c36b270d94))
- **addon**: Publish dev addon version 7.5.0.dev356 \[skip ci]
([`5fa1463`](https://github.com/homeassistant-ai/ha-mcp/commit/5fa14630229ba0d6b97d9328768e247bf9c20af4))
- **addon**: Publish dev addon version 7.5.0.dev355 \[skip ci]
([`174ac5d`](https://github.com/homeassistant-ai/ha-mcp/commit/174ac5dca7667702cd664420c50e0101366e6c3a))
- **addon**: Publish dev addon version 7.5.0.dev354 \[skip ci]
([`4f93989`](https://github.com/homeassistant-ai/ha-mcp/commit/4f939892dea2d1951541b1a557c51e957f6751c0))
- **addon**: Publish dev addon version 7.5.0.dev353 \[skip ci]
([`53f282f`](https://github.com/homeassistant-ai/ha-mcp/commit/53f282f19ee736637106f5baececa3939393778e))
- **addon**: Publish dev addon version 7.5.0.dev352 \[skip ci]
([`4911d46`](https://github.com/homeassistant-ai/ha-mcp/commit/4911d4682c4a865a93a8e821bc86bd26cef0ed5a))
- Sync tool docs after merge \[skip ci]
([`8a79837`](https://github.com/homeassistant-ai/ha-mcp/commit/8a798373a7b2f1adb94b93e65d626ab582c7bd5d))
- **addon**: Publish dev addon version 7.5.0.dev351 \[skip ci]
([`13afa9d`](https://github.com/homeassistant-ai/ha-mcp/commit/13afa9df026dd27332277140c34f7d41d0229efd))
- **addon**: Publish dev addon version 7.5.0.dev350 \[skip ci]
([`e93d680`](https://github.com/homeassistant-ai/ha-mcp/commit/e93d6806025c6d7fd2ef94c509a607c4ac85c8e0))
- **addon**: Publish dev addon version 7.5.0.dev349 \[skip ci]
([`1631ad1`](https://github.com/homeassistant-ai/ha-mcp/commit/1631ad10bdada4487d7b54049e92df6ddb29439a))
- **addon**: Publish dev addon version 7.5.0.dev348 \[skip ci]
([`18a8aef`](https://github.com/homeassistant-ai/ha-mcp/commit/18a8aef50675c1a881b279666e0af1b093679850))
- Sync tool docs after merge \[skip ci]
([`9e0493d`](https://github.com/homeassistant-ai/ha-mcp/commit/9e0493d248e23a8042841e90847662926395a448))
- **addon**: Publish dev addon version 7.5.0.dev347 \[skip ci]
([`e2067e4`](https://github.com/homeassistant-ai/ha-mcp/commit/e2067e446b127097e61d07516ae0e742ae2de6c8))
- Sync tool docs after merge \[skip ci]
([`7bdb3d4`](https://github.com/homeassistant-ai/ha-mcp/commit/7bdb3d402b60900a1012b8269e52b7cbeb400f84))
- **addon**: Publish dev addon version 7.5.0.dev346 \[skip ci]
([`c2d4dd7`](https://github.com/homeassistant-ai/ha-mcp/commit/c2d4dd7091653a618326f665fd34b5458d26c8f6))
- Sync tool docs after merge \[skip ci]
([`393b354`](https://github.com/homeassistant-ai/ha-mcp/commit/393b354e8a8e1280029eee9521971c693526970a))
- **addon**: Publish dev addon version 7.5.0.dev345 \[skip ci]
([`42ede8b`](https://github.com/homeassistant-ai/ha-mcp/commit/42ede8b0e6066faf3ed6f6920629a8d94d77f69a))
- **addon**: Publish dev addon version 7.5.0.dev344 \[skip ci]
([`e6cc7a1`](https://github.com/homeassistant-ai/ha-mcp/commit/e6cc7a1b8ed252f1aaa2b8c964e56c97a27b94c2))
- Sync tool docs after merge \[skip ci]
([`fb35f30`](https://github.com/homeassistant-ai/ha-mcp/commit/fb35f305cbf7de6807c29bd3ada9da2f028ff730))
- **addon**: Publish dev addon version 7.5.0.dev343 \[skip ci]
([`401b7b4`](https://github.com/homeassistant-ai/ha-mcp/commit/401b7b4d707dbb3c56a3afecad9e9d22ecbc7d1e))
- **addon**: Publish dev addon version 7.5.0.dev342 \[skip ci]
([`0679371`](https://github.com/homeassistant-ai/ha-mcp/commit/06793710b04a985ed0d66861266b9b79494e4111))
- Sync tool docs after merge \[skip ci]
([`f6796ec`](https://github.com/homeassistant-ai/ha-mcp/commit/f6796ec19b4596455ff54b58746bd3e075d5d280))
- **addon**: Publish dev addon version 7.5.0.dev341 \[skip ci]
([`3654478`](https://github.com/homeassistant-ai/ha-mcp/commit/3654478f80428d15671e49162acecea19d67f672))
- **addon**: Publish dev addon version 7.5.0.dev340 \[skip ci]
([`64f00b6`](https://github.com/homeassistant-ai/ha-mcp/commit/64f00b658846cad0e0714f37d221fb65327015cf))
- **addon**: Publish dev addon version 7.5.0.dev339 \[skip ci]
([`d6e8873`](https://github.com/homeassistant-ai/ha-mcp/commit/d6e88731556464deb768524dc24c90fd0a622a96))
- Sync tool docs after merge \[skip ci]
([`7525e93`](https://github.com/homeassistant-ai/ha-mcp/commit/7525e930a872871fed78f9b1461aea8e78eb5ad7))
- **addon**: Publish dev addon version 7.5.0.dev338 \[skip ci]
([`288ca4a`](https://github.com/homeassistant-ai/ha-mcp/commit/288ca4abd00b2b366cbaf671c1ace3398cc8f2fd))
- **addon**: Publish dev addon version 7.5.0.dev337 \[skip ci]
([`f539ae5`](https://github.com/homeassistant-ai/ha-mcp/commit/f539ae5aa881853d831e6952ff3af8bc85eb8b2a))
- **addon**: Publish dev addon version 7.5.0.dev336 \[skip ci]
([`5568a86`](https://github.com/homeassistant-ai/ha-mcp/commit/5568a861002cfb909e29368bd4e93ef0bd2e4c03))
- **addon**: Publish dev addon version 7.5.0.dev335 \[skip ci]
([`e069405`](https://github.com/homeassistant-ai/ha-mcp/commit/e0694054bd8627f6464379c34c1e3eec5b080a44))
- **addon**: Publish dev addon version 7.5.0.dev334 \[skip ci]
([`f7be6ea`](https://github.com/homeassistant-ai/ha-mcp/commit/f7be6ead486a32840a935a1e5ec78a34f8003c0d))
- **addon**: Publish dev addon version 7.5.0.dev333 \[skip ci]
([`cb480ea`](https://github.com/homeassistant-ai/ha-mcp/commit/cb480eae4d855345c19a6465351e0bdef2bdf5c3))
- Sync tool docs after merge \[skip ci]
([`9a5bc3c`](https://github.com/homeassistant-ai/ha-mcp/commit/9a5bc3c61372159bb936d7b929166924343dc76f))
- **addon**: Publish dev addon version 7.5.0.dev332 \[skip ci]
([`e0e59ee`](https://github.com/homeassistant-ai/ha-mcp/commit/e0e59ee08072bb4aac51e90928fab2d68f6156ce))
- Sync tool docs after merge \[skip ci]
([`499ebf0`](https://github.com/homeassistant-ai/ha-mcp/commit/499ebf0c9d4c4ec3784dd72782fe301cd9c19d60))
- **addon**: Publish dev addon version 7.5.0.dev331 \[skip ci]
([`3e0ce92`](https://github.com/homeassistant-ai/ha-mcp/commit/3e0ce92e11777a8fd9c86153e4c248007b8edae9))
- **addon**: Publish dev addon version 7.5.0.dev330 \[skip ci]
([`e48d056`](https://github.com/homeassistant-ai/ha-mcp/commit/e48d056ab356e11f8b2952b6c675307d1e76a895))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.15
([#​1376](https://github.com/homeassistant-ai/ha-mcp/pull/1376))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3
([#​1377](https://github.com/homeassistant-ai/ha-mcp/pull/1377))
- **addon**: Publish dev addon version 7.5.0.dev329 \[skip ci]
([`c523c50`](https://github.com/homeassistant-ai/ha-mcp/commit/c523c502c5c6f282905620d3db489e9c69ec2472))
- Sync tool docs after merge \[skip ci]
([`5b7a8aa`](https://github.com/homeassistant-ai/ha-mcp/commit/5b7a8aa0794359a90d7b89a9cc61d73d8cf038d2))
- **addon**: Publish dev addon version 7.5.0.dev328 \[skip ci]
([`6c42fba`](https://github.com/homeassistant-ai/ha-mcp/commit/6c42fba92d4786d7498f738c53dfe50c899d0890))
- **addon**: Publish dev addon version 7.5.0.dev327 \[skip ci]
([`aecd025`](https://github.com/homeassistant-ai/ha-mcp/commit/aecd025eeea3d1edcd9466db3720cb17de71b90a))
- **addon**: Publish dev addon version 7.5.0.dev326 \[skip ci]
([`399c17c`](https://github.com/homeassistant-ai/ha-mcp/commit/399c17c36602a7767491df6e317186cb6291f3e4))
- **addon**: Publish dev addon version 7.5.0.dev325 \[skip ci]
([`b580b45`](https://github.com/homeassistant-ai/ha-mcp/commit/b580b452e9007deb33acc49098238988aa768603))
- Sync tool docs after merge \[skip ci]
([`8567c3a`](https://github.com/homeassistant-ai/ha-mcp/commit/8567c3a6e66e7bebbbad8e96b94058f8456deb14))
- **addon**: Publish dev addon version 7.5.0.dev324 \[skip ci]
([`a65579d`](https://github.com/homeassistant-ai/ha-mcp/commit/a65579d0b6e4a8bb7f8c1ed97fd432cd770c47a4))
- **addon**: Publish dev addon version 7.5.0.dev323 \[skip ci]
([`c7667ba`](https://github.com/homeassistant-ai/ha-mcp/commit/c7667ba66538f1ba8a06b7616fb15896bf021744))
- **addon**: Publish dev addon version 7.5.0.dev322 \[skip ci]
([`44d15a8`](https://github.com/homeassistant-ai/ha-mcp/commit/44d15a89cbacc2c38ab39868b380414507a6708b))
- **addon**: Publish dev addon version 7.5.0.dev321 \[skip ci]
([`8739f6c`](https://github.com/homeassistant-ai/ha-mcp/commit/8739f6c09121c88a596470df293ac8e7e0f1050a))
- **addon**: Publish dev addon version 7.5.0.dev320 \[skip ci]
([`02b6e47`](https://github.com/homeassistant-ai/ha-mcp/commit/02b6e47f8eb6c778f709d7adca115638c2fe98a2))
- Sync tool docs after merge \[skip ci]
([`ab68c9a`](https://github.com/homeassistant-ai/ha-mcp/commit/ab68c9a9aa94ac6861af7b59997ec679f1849503))
- **addon**: Publish dev addon version 7.5.0.dev319 \[skip ci]
([`4472904`](https://github.com/homeassistant-ai/ha-mcp/commit/44729040c11af0bd97189080c1ec59995fc563b4))
- **addon**: Publish dev addon version 7.5.0.dev318 \[skip ci]
([`e030dbc`](https://github.com/homeassistant-ai/ha-mcp/commit/e030dbcc99e002751834274b1d53da161ab27759))
- **addon**: Publish dev addon version 7.5.0.dev317 \[skip ci]
([`d87855c`](https://github.com/homeassistant-ai/ha-mcp/commit/d87855cf07cef9d9d7babf0bbec74d228149327d))
- Sync tool docs after merge \[skip ci]
([`a72a4e8`](https://github.com/homeassistant-ai/ha-mcp/commit/a72a4e8c0de99a8516f3820545642c37a31c17e5))
- **addon**: Publish dev addon version 7.5.0.dev316 \[skip ci]
([`bd9397f`](https://github.com/homeassistant-ai/ha-mcp/commit/bd9397f3a088a24a14af66a97afcf1c97904ef61))
- **addon**: Publish dev addon version 7.5.0.dev315 \[skip ci]
([`264bfc2`](https://github.com/homeassistant-ai/ha-mcp/commit/264bfc2fcb5ef6fe3ee6f9e073b69e0469eeafdd))
- **addon**: Publish dev addon version 7.5.0.dev314 \[skip ci]
([`df62881`](https://github.com/homeassistant-ai/ha-mcp/commit/df6288194cdde8b625132f19b0dd3edb2142a2b3))
- **addon**: Publish dev addon version 7.5.0.dev313 \[skip ci]
([`f6c47ca`](https://github.com/homeassistant-ai/ha-mcp/commit/f6c47caa21b0d82799b2be9330f97aa5494aa3c8))
- **addon**: Publish dev addon version 7.5.0.dev312 \[skip ci]
([`2bb7a74`](https://github.com/homeassistant-ai/ha-mcp/commit/2bb7a74f06e0652a729a735b08fc7cdc20a034f6))
- Sync tool docs after merge \[skip ci]
([`137e279`](https://github.com/homeassistant-ai/ha-mcp/commit/137e27943b1b704fe1d3e3a5b525b4d82bce33eb))
- **addon**: Publish dev addon version 7.5.0.dev311 \[skip ci]
([`28324ea`](https://github.com/homeassistant-ai/ha-mcp/commit/28324ea4a92fbf61f5ee40c561286c466af2309a))
- Sync tool docs after merge \[skip ci]
([`9a753d4`](https://github.com/homeassistant-ai/ha-mcp/commit/9a753d49abb4ccd84e874451dbcc563260f9e19d))
- **addon**: Publish dev addon version 7.5.0.dev310 \[skip ci]
([`f893b2e`](https://github.com/homeassistant-ai/ha-mcp/commit/f893b2ebf91967d0e2548f9205a15bfe0e7d86c2))
- **addon**: Publish dev addon version 7.5.0.dev309 \[skip ci]
([`8cbdb7b`](https://github.com/homeassistant-ai/ha-mcp/commit/8cbdb7bf318707fed1a0b3e8cb9922e6c170521e))
- **addon**: Publish dev addon version 7.5.0.dev308 \[skip ci]
([`2d18016`](https://github.com/homeassistant-ai/ha-mcp/commit/2d18016de8eb26a18cfb471e7b5f755f1309bd36))
- **addon**: Publish dev addon version 7.5.0.dev307 \[skip ci]
([`3fc3b28`](https://github.com/homeassistant-ai/ha-mcp/commit/3fc3b28881f237df02da8b65467fba9a7d693009))
- Sync tool docs after merge \[skip ci]
([`9e6cff8`](https://github.com/homeassistant-ai/ha-mcp/commit/9e6cff8f641bcd8122e94fc8be9c30aa18456e80))
- **addon**: Publish dev addon version 7.5.0.dev306 \[skip ci]
([`8bdd0fc`](https://github.com/homeassistant-ai/ha-mcp/commit/8bdd0fca9c107f45e4c3719e7616984b68876a9e))
- **addon**: Publish dev addon version 7.5.0.dev305 \[skip ci]
([`83535b9`](https://github.com/homeassistant-ai/ha-mcp/commit/83535b99e190fb56b7ce227334331ebf2affb3e1))
- **addon**: Publish dev addon version 7.5.0.dev304 \[skip ci]
([`1435b3a`](https://github.com/homeassistant-ai/ha-mcp/commit/1435b3a24d73503e189b83f8ea5aaeea20d9ebf3))
- **addon**: Publish dev addon version 7.5.0.dev303 \[skip ci]
([`e2da659`](https://github.com/homeassistant-ai/ha-mcp/commit/e2da6591d6ad2def0b48a9be750cb8a41f40524d))
- Sync tool docs after merge \[skip ci]
([`23789fa`](https://github.com/homeassistant-ai/ha-mcp/commit/23789fa978591b7d3966894082a2683ca6a6ae3b))
- **addon**: Publish dev addon version 7.5.0.dev302 \[skip ci]
([`6c8e574`](https://github.com/homeassistant-ai/ha-mcp/commit/6c8e574e7e3d8d78b3a2e48f6a70531d7a95eed8))
- Sync tool docs after merge \[skip ci]
([`d2329cb`](https://github.com/homeassistant-ai/ha-mcp/commit/d2329cbff39891d209317528fd7b42759c3414a8))
- **addon**: Publish dev addon version 7.5.0.dev301 \[skip ci]
([`bb538f7`](https://github.com/homeassistant-ai/ha-mcp/commit/bb538f70d2fc57072f09cfc6202e9d3dc1a2d257))
- Sync tool docs after merge \[skip ci]
([`f70f0e1`](https://github.com/homeassistant-ai/ha-mcp/commit/f70f0e14222b29a8923e706f113d1fafb4a5c23e))
- **addon**: Publish version 7.5.0 \[skip ci]
([`9c5eb37`](https://github.com/homeassistant-ai/ha-mcp/commit/9c5eb37779236ef19366a2a59a667d3916458e5a))
##### Continuous Integration
- **deps**: Bump actions/upload-artifact in the github-actions group
([#​1437](https://github.com/homeassistant-ai/ha-mcp/pull/1437))
- Share qcow2 cache + GHCR fallback between HAOS lanes
([#​1407](https://github.com/homeassistant-ai/ha-mcp/pull/1407))
- Add ruff format --check on changed Python files
([#​1387](https://github.com/homeassistant-ai/ha-mcp/pull/1387))
- Exempt assigned issues from stale bot
([#​1368](https://github.com/homeassistant-ai/ha-mcp/pull/1368))
- **deps**: Bump the github-actions group with 3 updates
([#​1362](https://github.com/homeassistant-ai/ha-mcp/pull/1362))
##### Refactoring
- Consolidate lovelace/dashboards/list through shared helper
([#​1344](https://github.com/homeassistant-ai/ha-mcp/pull/1344))
##### Testing
- **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime
([#​1443](https://github.com/homeassistant-ai/ha-mcp/pull/1443))
- **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep
([#​1430](https://github.com/homeassistant-ai/ha-mcp/pull/1430))
- **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot
([#​1428](https://github.com/homeassistant-ai/ha-mcp/pull/1428))
- JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script>
([#​1425](https://github.com/homeassistant-ai/ha-mcp/pull/1425))
- **hacs**: Retry TestMcpToolsInstallation on flake
([#​1426](https://github.com/homeassistant-ai/ha-mcp/pull/1426))
- **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#​1414](https://github.com/homeassistant-ai/ha-mcp/issues/1414))
([#​1419](https://github.com/homeassistant-ai/ha-mcp/pull/1419))
- **e2e**: Assert backend dispatch matches workflow env on every lane
([#​1409](https://github.com/homeassistant-ai/ha-mcp/pull/1409))
- Escape ideographic space and format file ([#​1237](https://github.com/homeassistant-ai/ha-mcp/issues/1237))
([#​1410](https://github.com/homeassistant-ai/ha-mcp/pull/1410))
- **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#​1389](https://github.com/homeassistant-ai/ha-mcp/issues/1389))
([#​1398](https://github.com/homeassistant-ai/ha-mcp/pull/1398))
- **e2e**: Wait for addon state=started in haos proxy header test
([#​1402](https://github.com/homeassistant-ai/ha-mcp/pull/1402))
- Pin remaining \_classify\_by\_message branches
([#​1385](https://github.com/homeassistant-ai/ha-mcp/pull/1385))
- **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#​1350](https://github.com/homeassistant-ai/ha-mcp/issues/1350))
([#​1379](https://github.com/homeassistant-ai/ha-mcp/pull/1379))
- **haos-e2e**: Close out [#​1349](https://github.com/homeassistant-ai/ha-mcp/issues/1349) — lifecycle, integrations, supervisor\_mock migration, no more skips
([#​1375](https://github.com/homeassistant-ai/ha-mcp/pull/1375))
- **e2e**: Consolidate readiness gates onto /api/core/state (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1372](https://github.com/homeassistant-ai/ha-mcp/pull/1372))
- **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1369](https://github.com/homeassistant-ai/ha-mcp/pull/1369))
- Scaffold HAOS E2E tier image-build pipeline (refs [#​1281](https://github.com/homeassistant-ai/ha-mcp/issues/1281))
([#​1326](https://github.com/homeassistant-ai/ha-mcp/pull/1326))
- **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1346](https://github.com/homeassistant-ai/ha-mcp/pull/1346))
- **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1308](https://github.com/homeassistant-ai/ha-mcp/pull/1308))
- **e2e**: Unify dict-error message extraction across e2e tests (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1311](https://github.com/homeassistant-ai/ha-mcp/pull/1311))
- **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1310](https://github.com/homeassistant-ai/ha-mcp/pull/1310))
</details>
</details>
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->
Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/994
What does this PR do?
Adds
ha_get_home_topology, a read-only tool that combinesconfig/area_registry/listandconfig/floor_registry/listinto one nested hierarchy: floors sorted by level ascending, each with its assigned areas nested underneath, plusunassigned_areasfor areas without a floor.Collapses the two-call in-context join (by
floor_id) into one server-side call, reducing agent reasoning for location-based queries such as "which rooms are on the ground floor". The existingha_config_list_areasandha_config_list_floorsare unchanged — this PR is purely additive (86 → 87 tools).Rationale (per AGENTS.md §Tool Consolidation): this is a "frequently chained operations → consolidate" case where tool-side logic adds value by combining multiple API calls. Follows the
ha_get_overviewprecedent for joined read-only tools (sequentialawait, fail-fast on registry error; both registries are essential here, unlike the optional subparts inha_get_overview).Closes #902.
Response shape
json { "success": true, "floor_count": 2, "area_count": 3, "unassigned_count": 1, "floors": [ {"floor_id": "basement", "name": "Basement", "level": -1, "icon": null, "aliases": [], "areas": [{"area_id": "storage", ...}]}, {"floor_id": "ground", "name": "Ground Floor", "level": 0, "icon": "mdi:home-floor-0", "aliases": [], "areas": [{"area_id": "kitchen", ...}, {"area_id": "living_room", ...}]} ], "unassigned_areas": [{"area_id": "garage", ...}] } Floor entries pass through all registry fields via dict-spread (
{**floor, "areas": [...]}) for forward compatibility with future HA Core additions. Areas are nested as full dicts so the LLM never needs to re-query.levelmay beNone(HA Core:FloorEntry.level: int | None); sort key usesx.get("level") or 0soNonefloors land next to level-0 instead of raisingTypeError.Type of change
Testing
uv run pytest)uv run ruff check)Three E2E tests added in
tests/src/e2e/workflows/areas/test_lifecycle.py:test_home_topology_schema— standalone schema check (works on any HA instance)test_home_topology_with_assignment— create floor + area-on-floor, verify area nested under floor and not inunassigned_areastest_home_topology_unassigned_area— create area withoutfloor_id, verify area inunassigned_areasand not leaked into any floor'sareaslistChecklist
scripts/extract_tools.pynot included in this PR;.github/workflows/sync-tool-docs.ymlregeneratestools.json/README.md/DOCS.mdautomatically after merge to master. Can push a follow-up commit if preferred.