Skip to content

feat: combine ha_config_list_floors and ha_config_list_areas into ha_list_floors_areas - #1016

Merged
kingpanther13 merged 11 commits into
homeassistant-ai:masterfrom
Patch76:feat/ha-get-home-topology
Apr 22, 2026
Merged

feat: combine ha_config_list_floors and ha_config_list_areas into ha_list_floors_areas#1016
kingpanther13 merged 11 commits into
homeassistant-ai:masterfrom
Patch76:feat/ha-get-home-topology

Conversation

@Patch76

@Patch76 Patch76 commented Apr 19, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Adds ha_get_home_topology, a read-only tool that combines config/area_registry/list and config/floor_registry/list into one nested hierarchy: floors sorted by level ascending, each with its assigned areas nested underneath, plus unassigned_areas for 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 existing ha_config_list_areas and ha_config_list_floors are 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_overview precedent for joined read-only tools (sequential await, fail-fast on registry error; both registries are essential here, unlike the optional subparts in ha_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. level may be None (HA Core: FloorEntry.level: int | None); sort key uses x.get("level") or 0 so None floors land next to level-0 instead of raising TypeError.

Type of change

  • ✨ New feature

Testing

  • I have tested these changes with a LLM agent
  • All automated tests pass (uv run pytest)
  • Code follows style guidelines (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 in unassigned_areas
  • test_home_topology_unassigned_area — create area without floor_id, verify area in unassigned_areas and not leaked into any floor's areas list

Checklist

  • I have updated documentation if needed

scripts/extract_tools.py not included in this PR; .github/workflows/sync-tool-docs.yml regenerates tools.json / README.md / DOCS.md automatically after merge to master. Can push a follow-up commit if preferred.

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
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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, ha_get_home_topology, designed to streamline how agents retrieve the home's spatial configuration. By pre-joining floor and area registries, it simplifies the data structure for downstream tasks and reduces the number of required API calls, aligning with the project's goal of tool consolidation for frequently chained operations.

Highlights

  • New Tool Added: Introduced ha_get_home_topology, a read-only tool that consolidates floor and area registry data into a single hierarchical structure.
  • Performance Optimization: Reduced agent reasoning overhead by collapsing two separate API calls into one server-side operation for location-based queries.
  • Enhanced Testing: Added three comprehensive E2E tests to verify schema integrity, area-to-floor assignment, and handling of unassigned areas.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Patch76

Patch76 commented Apr 19, 2026

Copy link
Copy Markdown
Member Author

Implementation Summary

Choices Made:

  • Sequential await on both WS calls, not asyncio.gather — follows the ha_get_overview precedent (tools_search.py:645–712). Two registry calls are fast; gather adds complexity without measurable benefit, and ha_get_overview is the only existing pattern for combined read-only WS calls in this repo.
  • Fail-fast on registry error, not graceful degradationha_get_overview can degrade on optional subparts (notifications, repairs) because the core payload stands on its own. Here, both registries are essential: a "topology" missing either side is misleading, not partial. Explicit SERVICE_CALL_FAILED with per-registry success flags in context.
  • if fid: rather than if fid is None: for the area→floor grouping — treats both None and empty string as "unassigned". The area-create code path in _build_area_create_message (tools_areas.py:72) already maps empty input to None, so "" should not occur in well-formed data; if fid: is defensive against legacy or corrupted entries. The stricter if fid is None: would route floor_id="" into an empty-string floor bucket — semantically worse for a nonexistent floor.
  • None-safe sort: key=lambda f: f.get("level") or 0 — HA Core defines FloorEntry.level: int | None, so None is a real value. None or 0 treats unlevelled floors as co-located with level 0 (ground floor). An explicit sentinel like -1 or float("inf") would force an unlevelled floor to sort at the extremes, which is a stronger assumption than warranted.
  • Dict-spread {**floor, "areas": [...]}, not field-by-field copy — the WS handler in components/config/floor_registry.py:158–167 returns a fixed seven-key shape; passing through all fields is forward-compatible with any HA Core additions and keeps the response LLM-discoverable without a follow-up lookup. Verified no key collision: areas is not a field on FloorEntry.
  • Single commit containing both production code and tests — squash-merge collapses the branch anyway, and a code-only intermediate commit would be a "formally working but untested" bisect-target. Atomic unit is preferable.
  • Naming: ha_get_home_topology (issue title), not ha_get_floor_area_hierarchy — kp13 raised an LLM-discoverability concern about "topology" in the issue thread. Retained the issue-title name to keep the PR scope narrow; the detailed docstring and return structure should mitigate discoverability. Open to a rename if the concern proves valid in practice.
  • No entry in _SEARCH_KEYWORDS (server.py) — consistent with the existing Area/Floor tools, which also have no entries. Can be added later as a separate commit if BAT/discovery testing shows it's needed.
  • Scope: read-only only, no CRUD consolidation — keeps this PR narrow and issue-faithful, and sidesteps the type-discriminator discussion from [FEATURE] Consolidate 5 redundant tools: areas+floors, rename entity, operation status #774/refactor: consolidate 2 redundant tools (merge after #806) #813 by construction (read-only has no update-ID overloading). A separate consolidation proposal can revisit the write/remove side with its own BAT evidence.

Problems Encountered:

  • None during implementation. BAT results shared earlier in the issue thread (−50% tool calls, −33% input tokens on location-join queries with Gemini 2.5 Flash, single run per scenario) motivated the read-only scope decision.

Suggested Improvements (Optional Follow-ups):

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/ha_mcp/tools/tools_areas.py
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).
@Patch76

Patch76 commented Apr 19, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/ha_mcp/tools/tools_areas.py Outdated
Comment thread src/ha_mcp/tools/tools_areas.py
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
@Patch76

Patch76 commented Apr 19, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/ha_mcp/tools/tools_areas.py
@Patch76
Patch76 marked this pull request as ready for review April 19, 2026 16:53
@Patch76
Patch76 requested review from a team and sergeykad April 19, 2026 16:53
@kingpanther13

Copy link
Copy Markdown
Member

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.

@Patch76

Patch76 commented Apr 20, 2026

Copy link
Copy Markdown
Member Author

@kingpanther13 — fair point, and I owe you an apology here. I got so
locked onto the consolidation scope question that I let the naming
concern slide, even though you flagged it in #902:

"I think the name 'topology' might confuse an LLM as that doesn't
reflect any terms that HA uses afaik"

That was clear feedback, and I should have treated it as a blocking
constraint from the start rather than parking it behind the
discriminator debate from #774/#813. Given that history — #774 reverted
over the type discriminator, #813 landed only after dropping the
area/floor consolidation under sergeykad's objection — the naming
alignment with write tools is exactly the kind of detail that turns
into a hold or outright blocker late in review. I should have caught
that.

On the name itself — three alternatives that keep the ha_config_*
prefix and include both "area" and "floor":

  1. ha_config_get_floor_area_hierarchy — what I proposed in
    [FEATURE] Add ha_get_home_topology — single read-only call returning floor/area hierarchy #902. Describes the output shape directly. Verb get is a
    deviation from the existing list_areas/list_floors but
    signals "pre-joined" semantics.

  2. ha_config_list_floor_areas — stays with the list_ verb
    from list_areas/list_floors. Reads as "list the areas,
    grouped by floor." Tightest fit to the existing write-tool
    naming pattern.

  3. ha_config_get_areas_and_floors — mirrors the areas_and_floors
    wording from your original refactor: consolidate 2 redundant tools (merge after #806) #813 attempt. Most faithful to your
    earlier framing, though it under-describes the hierarchy aspect
    in the name.

My lean is (2) — closest to the existing ha_config_list_* pattern,
no verb deviation — but I'll defer to you and sergeykad.

On scope — your #902 comment proposed bundling read and write into
two separate tools (4 → 2), pending sergeykad's input. I'd rather
get that decision settled before renaming: if 4→2 is the direction,
this PR should be closed and reopened with the full scope rather
than renamed twice. If the read-only additive framing stands, I'll
rename to the agreed name and push.

@sergeykad — would appreciate your read on both questions (scope
and naming). #1016 stays in its current state until there's alignment.

@kingpanther13

Copy link
Copy Markdown
Member

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 kingpanther13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Patch76 added 6 commits April 21, 2026 21:19
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.
@Patch76

Patch76 commented Apr 21, 2026

Copy link
Copy Markdown
Member Author

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 → ha_list_floors_areas. Method, @tool(name=…), annotations.title, docstring leading verb, exception_to_structured_error context string, and all three call_tool sites in the tests. Repo-wide grep confirms zero ha_get_home_topology residue. — 728655d

3. Silent-failure guard (lines 437–438). success=True without "result" now raises SERVICE_CALL_FAILED; context carries areas_success, floors_success, areas_response_keys, floors_response_keys for diagnosis. After the guard, indexing is direct (areas_result["result"]) since the key is guaranteed present. — 4aa1359

4. Orphaned floor_id — separate key. Three-way partition: nested (floor_id resolves), orphaned_areas + orphaned_count (floor_id present but unknown), unassigned_areas (no floor_id). Schema additive; unassigned_count preserved for the truly-unassigned case. — cf8eab4

5. Empty-floor test. test_home_topology_empty_floor creates a floor with no areas, asserts it appears in floors with "areas": [], and runs a downstream-iterator smoke. — f9b8ed2

6. Sort-order test. test_home_topology_sort_order creates floors with level=[-1, 0, None, 2], asserts position 0 is level=-1 and position 3 is level=2; the middle two positions are validated as the {0, None} set (the level or 0 tie; stable-sort order-agnostic). — f9b8ed2

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 orphaned_areas. — a6fd5db

One additional edge-case fix caught before push — is None vs. falsy. The partition used a falsy check (if not fid), which would route an area with floor_id="" into unassigned_areas instead of orphaned_areas. Switched to explicit is None / is not None on both the valid_floor_ids comprehension and the area loop. No change for real-world floor_ids; the edge case now matches the schema semantics introduced in item 4. — b773270

@Patch76
Patch76 requested a review from kingpanther13 April 21, 2026 21:58

@kingpanther13 kingpanther13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Schema test missing orphaned_* keys. test_home_topology_schema asserts every other response field but not orphaned_areas / orphaned_count, both of which are documented in the docstring as part of the public contract. One-line fix mirroring the unassigned_* 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)
  2. Unit-test the orphaned partition branch and the SERVICE_CALL_FAILED guard. Both are untriggerable from E2E (orphaned needs .storage drift, 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.

  3. Sort key type-safety. topology.sort(key=lambda f: f.get("level") or 0) is None-safe but not type-safe — a malformed string level would raise TypeError mid-sort and get flattened by the broad except Exception. int(f.get("level") or 0) inside a small try that logs the offending floor_id would be enough.

  4. Generic except Exception loses context. tools_areas.py:492 logs "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. whether areas_result was 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.

Patch76 added 2 commits April 22, 2026 01:51
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).
@Patch76

Patch76 commented Apr 21, 2026

Copy link
Copy Markdown
Member Author

All four items addressed — a1c13ef (code) + 0e582f9 (tests).

  1. Schema test + orphaned_*. Extended test_home_topology_schema with the one-liner mirror you suggested (test_lifecycle.py:872-877); log message picks up the orphaned count.

  2. Unit tests for orphaned partition + SERVICE_CALL_FAILED guard. New tests/src/unit/test_tools_areas.py — two mocks, two tests:

    • TestHomeTopologyPartition.test_orphaned_area_partition — seeds areas with floor_id="deleted_floor_id" against a floor registry that only has "ground", asserts the orphaned/unassigned/nested split.
    • TestHomeTopologyMalformedResponseGuard.test_malformed_ws_response_triggers_guardsuccess=True without "result", asserts ToolError is raised and error["code"] == "SERVICE_CALL_FAILED".
  3. Sort key type-safety. Replaced the lambda with _floor_sort_key (tools_areas.py:479-495): int() inside try, logger.warning naming the offending floor_id on TypeError/ValueError, fallback to 0.

  4. Broad-except context. Explicit progress dict threaded through the try-block with five phase labels (start / areas_fetched / floors_fetched / partitioned / sorted). The error log now names the phase ("in phase 'sorted'"), and progress is passed as context= into exception_to_structured_error. I went with an explicit dict rather than locals() introspection so the phase tracking survives future refactors of the function.

@Patch76
Patch76 requested a review from kingpanther13 April 21, 2026 23:59

@kingpanther13 kingpanther13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@kingpanther13 kingpanther13 changed the title feat: add ha_get_home_topology for pre-joined floor/area hierarchy feat: combine floor and area registries into ha_list_floors_areas Apr 22, 2026
@kingpanther13 kingpanther13 changed the title feat: combine floor and area registries into ha_list_floors_areas feat: combine ha_config_list_floors and ha_config_list_areas into ha_list_floors_areas Apr 22, 2026
@kingpanther13
kingpanther13 merged commit 90db3eb into homeassistant-ai:master Apr 22, 2026
15 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🧪 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):
📖 Dev Channel Documentation

Quick start

# Run dev version
uvx ha-mcp-dev

# Check version
uvx ha-mcp-dev --version

Docker:

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:dev

Found an issue? Please open a new bug report and mention this PR for context.

@Patch76
Patch76 deleted the feat/ha-get-home-topology branch April 22, 2026 00:11
kingpanther13 added a commit that referenced this pull request May 8, 2026
…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>
kingpanther13 added a commit that referenced this pull request May 24, 2026
…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>
doonga pushed a commit to greyrock-labs/home-ops that referenced this pull request May 28, 2026
….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 [#&#8203;1434](homeassistant-ai/ha-mcp#1434))
  ([#&#8203;1436](homeassistant-ai/ha-mcp#1436))
- Tool Security Policies — per-tool approval gating ([#&#8203;966](homeassistant-ai/ha-mcp#966))
  ([#&#8203;1421](homeassistant-ai/ha-mcp#1421))
- Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target
  ([#&#8203;1424](homeassistant-ai/ha-mcp#1424))
- Auto-backup edited entities before write/destructive tool calls (closes [#&#8203;1288](homeassistant-ai/ha-mcp#1288))
  ([#&#8203;1403](homeassistant-ai/ha-mcp#1403))
- Persistent settings UI for stdio mode
  ([#&#8203;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 ([#&#8203;1199](homeassistant-ai/ha-mcp#1199))
  ([#&#8203;1225](homeassistant-ai/ha-mcp#1225))
- Route entity-registration wait through WS events (closes [#&#8203;1152](homeassistant-ai/ha-mcp#1152))
  ([#&#8203;1382](homeassistant-ai/ha-mcp#1382))
- Add config subentry support
  ([#&#8203;1393](homeassistant-ai/ha-mcp#1393))
- Add Assist pipeline management tool
  ([#&#8203;1392](homeassistant-ai/ha-mcp#1392))
- Add knx to ha\_config\_set\_yaml allowlist
  ([#&#8203;1374](homeassistant-ai/ha-mcp#1374))
- Extend automation\_id parity to set/remove automation responses
  ([#&#8203;1343](homeassistant-ai/ha-mcp#1343))
- **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon)
  ([#&#8203;1361](homeassistant-ai/ha-mcp#1361))
- Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#&#8203;1148](homeassistant-ai/ha-mcp#1148))
  ([#&#8203;1328](homeassistant-ai/ha-mcp#1328))
- Return canonical script\_id from ha\_config\_get\_script ([#&#8203;1334](homeassistant-ai/ha-mcp#1334))
  ([#&#8203;1352](homeassistant-ai/ha-mcp#1352))
- Add automation\_id parity key to ha\_config\_get\_automation
  ([#&#8203;1329](homeassistant-ai/ha-mcp#1329))
- Reject empty/whitespace identifiers on registry-metadata writes (closes [#&#8203;1294](homeassistant-ai/ha-mcp#1294))
  ([#&#8203;1312](homeassistant-ai/ha-mcp#1312))
- Add HA brand assets for custom integration
  ([#&#8203;1317](homeassistant-ai/ha-mcp#1317))
- Unify ha\_config\_set\_helper response shape (closes [#&#8203;1293](homeassistant-ai/ha-mcp#1293))
  ([#&#8203;1303](homeassistant-ai/ha-mcp#1303))
- Mirror create-side validation guards onto update path (closes [#&#8203;1292](homeassistant-ai/ha-mcp#1292))
  ([#&#8203;1304](homeassistant-ai/ha-mcp#1304))
- Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST
  ([#&#8203;1063](homeassistant-ai/ha-mcp#1063))

##### Changed

- **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions
  ([#&#8203;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
  ([#&#8203;1411](homeassistant-ai/ha-mcp#1411))
- Credit [@&#8203;tomwilkie](https://github.com/tomwilkie) and six other contributors in README
  ([#&#8203;1400](homeassistant-ai/ha-mcp#1400))
- **[#&#8203;1157](homeassistant-ai/ha-mcp#1157: Bump skills-vendor + auto-update via Renovate + native for: field + scrub eval\_template anti-patterns
  ([#&#8203;1383](homeassistant-ai/ha-mcp#1383))
- Extend Boy Scout weasel-phrase list with common variants; clarify semantic match
  ([#&#8203;1373](homeassistant-ai/ha-mcp#1373))
- Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate
  ([#&#8203;1359](homeassistant-ai/ha-mcp#1359))
- Categorize Issue Labels table and document 6 reverse-drift labels
  ([#&#8203;1335](homeassistant-ai/ha-mcp#1335))
- Strip stale L-refs from test\_identifier\_validation\_family docstrings
  ([#&#8203;1324](homeassistant-ai/ha-mcp#1324))
- Align label refs with live label set and fix triaged-removal trigger
  ([#&#8203;1316](homeassistant-ai/ha-mcp#1316))
- Surface tool-discovery / categorized search
  ([#&#8203;1123](homeassistant-ai/ha-mcp#1123))
- Fix two stale ha\_get\_skill\_guide references missed in [#&#8203;1289](homeassistant-ai/ha-mcp#1289)
  ([#&#8203;1305](homeassistant-ai/ha-mcp#1305))
- Clarify setup wizard placeholders need braces removed ([#&#8203;1284](homeassistant-ai/ha-mcp#1284))
  ([#&#8203;1286](homeassistant-ai/ha-mcp#1286))

##### Fixed

- Remove counter from ha\_reload\_core targets ([#&#8203;1453](homeassistant-ai/ha-mcp#1453))
  ([#&#8203;1456](homeassistant-ai/ha-mcp#1456))
- **backup**: Post-timeout match correctness + state-gate (closes [#&#8203;1433](homeassistant-ai/ha-mcp#1433))
  ([#&#8203;1435](homeassistant-ai/ha-mcp#1435))
- Sync addon settings UI with Supervisor options end-to-end
  ([#&#8203;1420](homeassistant-ai/ha-mcp#1420))
- **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#&#8203;1413](homeassistant-ai/ha-mcp#1413), [#&#8203;1416](homeassistant-ai/ha-mcp#1416))
  ([#&#8203;1418](homeassistant-ai/ha-mcp#1418))
- Error-shape consistency for non-entity not-found (closes [#&#8203;1297](homeassistant-ai/ha-mcp#1297))
  ([#&#8203;1397](homeassistant-ai/ha-mcp#1397))
- Guard against silent automation overwrite on id mismatch ([#&#8203;1404](homeassistant-ai/ha-mcp#1404))
  ([#&#8203;1405](homeassistant-ai/ha-mcp#1405))
- Cache YAML instance to prevent CPU spikes in bulk edits ([#&#8203;1370](homeassistant-ai/ha-mcp#1370))
  ([#&#8203;1371](homeassistant-ai/ha-mcp#1371))
- **client**: Route get\_error\_log via hassio proxy on external-HAOS clients
  ([#&#8203;1360](homeassistant-ai/ha-mcp#1360))
- Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND
  ([#&#8203;1345](homeassistant-ai/ha-mcp#1345))
- Detect HA addon installs as http transport, not stdio ([#&#8203;1322](homeassistant-ai/ha-mcp#1322))
  ([#&#8203;1327](homeassistant-ai/ha-mcp#1327))
- Actionable 403 suggestion when addon has unmapped container ports ([#&#8203;1319](homeassistant-ai/ha-mcp#1319))
  ([#&#8203;1325](homeassistant-ai/ha-mcp#1325))
- Filter dismissed repairs in overview and system\_health ([#&#8203;1307](homeassistant-ai/ha-mcp#1307))
  ([#&#8203;1309](homeassistant-ai/ha-mcp#1309))
- Exit on HA container death + daily reset before CI check
  ([#&#8203;1295](homeassistant-ai/ha-mcp#1295))
- Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#&#8203;1291](homeassistant-ai/ha-mcp#1291))
  ([#&#8203;1301](homeassistant-ai/ha-mcp#1301))
- Allow str.replace in python\_transform; hint at search mode on IndexError
  ([#&#8203;1287](homeassistant-ai/ha-mcp#1287))
- **array\_patch**: Tighten validation and surface silent failures
  ([#&#8203;1285](homeassistant-ai/ha-mcp#1285))
- HA Core proxy fallback for ha\_get\_logs(source=system\_service) on non-addon installs
  ([#&#8203;1283](homeassistant-ai/ha-mcp#1283))

##### Performance Improvements

- Tighten \_poll\_for\_automation\_entity first-poll cadence
  ([#&#8203;1384](homeassistant-ai/ha-mcp#1384))
- Parallelize ha\_get\_system\_health optional sections via asyncio.gather
  ([#&#8203;1336](homeassistant-ai/ha-mcp#1336))

##### Refactoring

- **service**: Compact ha\_call\_service result default ([#&#8203;1446](homeassistant-ai/ha-mcp#1446))
  ([#&#8203;1447](homeassistant-ai/ha-mcp#1447))
- Rename ha\_update\_device → ha\_set\_device
  ([#&#8203;1444](homeassistant-ai/ha-mcp#1444))
- Remove duplicate flat area/floor list tools (consolidation followup to [#&#8203;1016](homeassistant-ai/ha-mcp#1016))
  ([#&#8203;1429](homeassistant-ai/ha-mcp#1429))
- **complexity**: Migrate tools\_utility.py to class-based pattern
  ([#&#8203;1423](homeassistant-ai/ha-mcp#1423))
- **complexity**: Reduce C901 violations in tools/ — batch 4
  ([#&#8203;1408](homeassistant-ai/ha-mcp#1408))
- Route \_poll\_for\_automation\_entity through WS event waiter (closes [#&#8203;1395](homeassistant-ai/ha-mcp#1395))
  ([#&#8203;1406](homeassistant-ai/ha-mcp#1406))
- **yaml**: Use threading.local subclass for cached instance
  ([#&#8203;1396](homeassistant-ai/ha-mcp#1396))
- Align dashboards 404 shape with sibling config tools
  ([#&#8203;1386](homeassistant-ai/ha-mcp#1386))
- Complete singular warning → warnings list migration repo-wide (closes [#&#8203;1332](homeassistant-ai/ha-mcp#1332))
  ([#&#8203;1341](homeassistant-ai/ha-mcp#1341))
- Complete warnings-list migration for lifecycle-write tools
  ([#&#8203;1340](homeassistant-ai/ha-mcp#1340))
- Drop redundant identifier echo key from ha\_config\_get\_automation
  ([#&#8203;1354](homeassistant-ai/ha-mcp#1354))
- Drop logger.error in config-tool except blocks ([#&#8203;1302](homeassistant-ai/ha-mcp#1302))
  ([#&#8203;1353](homeassistant-ai/ha-mcp#1353))
- Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#&#8203;1313](homeassistant-ai/ha-mcp#1313))
  ([#&#8203;1321](homeassistant-ai/ha-mcp#1321))
- Migrate tools\_config\_scenes inline empty-id guards to shared helper
  ([#&#8203;1320](homeassistant-ai/ha-mcp#1320))
- Remove ha\_get\_helper\_schema (closes [#&#8203;1186](homeassistant-ai/ha-mcp#1186))
  ([#&#8203;1315](homeassistant-ai/ha-mcp#1315))
- Consolidate skill tools; fix stable submodule packaging
  ([#&#8203;1289](homeassistant-ai/ha-mcp#1289))
- Align tools\_config\_automations.py error-handling with sibling pattern ([#&#8203;1290](homeassistant-ai/ha-mcp#1290))
  ([#&#8203;1298](homeassistant-ai/ha-mcp#1298))

***

<details>
<summary>Internal Changes</summary>

##### Fixed

- **ci**: Install libguestfs in HAOS publish workflow
  ([#&#8203;1358](homeassistant-ai/ha-mcp#1358))

##### Build System

- **deps**: Bump esbuild from 0.24.2 to 0.25.0 in /tests/js
  ([#&#8203;1427](homeassistant-ai/ha-mcp#1427))
- **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site
  ([#&#8203;1282](homeassistant-ai/ha-mcp#1282))
- **deps**: Bump astro from 6.1.6 to 6.1.10 in /site
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;1376](homeassistant-ai/ha-mcp#1376))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3
  ([#&#8203;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
  ([#&#8203;1437](homeassistant-ai/ha-mcp#1437))
- Share qcow2 cache + GHCR fallback between HAOS lanes
  ([#&#8203;1407](homeassistant-ai/ha-mcp#1407))
- Add ruff format --check on changed Python files
  ([#&#8203;1387](homeassistant-ai/ha-mcp#1387))
- Exempt assigned issues from stale bot
  ([#&#8203;1368](homeassistant-ai/ha-mcp#1368))
- **deps**: Bump the github-actions group with 3 updates
  ([#&#8203;1362](homeassistant-ai/ha-mcp#1362))

##### Refactoring

- Consolidate lovelace/dashboards/list through shared helper
  ([#&#8203;1344](homeassistant-ai/ha-mcp#1344))

##### Testing

- **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime
  ([#&#8203;1443](homeassistant-ai/ha-mcp#1443))
- **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep
  ([#&#8203;1430](homeassistant-ai/ha-mcp#1430))
- **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot
  ([#&#8203;1428](homeassistant-ai/ha-mcp#1428))
- JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script>
  ([#&#8203;1425](homeassistant-ai/ha-mcp#1425))
- **hacs**: Retry TestMcpToolsInstallation on flake
  ([#&#8203;1426](homeassistant-ai/ha-mcp#1426))
- **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#&#8203;1414](homeassistant-ai/ha-mcp#1414))
  ([#&#8203;1419](homeassistant-ai/ha-mcp#1419))
- **e2e**: Assert backend dispatch matches workflow env on every lane
  ([#&#8203;1409](homeassistant-ai/ha-mcp#1409))
- Escape ideographic space and format file ([#&#8203;1237](homeassistant-ai/ha-mcp#1237))
  ([#&#8203;1410](homeassistant-ai/ha-mcp#1410))
- **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#&#8203;1389](homeassistant-ai/ha-mcp#1389))
  ([#&#8203;1398](homeassistant-ai/ha-mcp#1398))
- **e2e**: Wait for addon state=started in haos proxy header test
  ([#&#8203;1402](homeassistant-ai/ha-mcp#1402))
- Pin remaining \_classify\_by\_message branches
  ([#&#8203;1385](homeassistant-ai/ha-mcp#1385))
- **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#&#8203;1350](homeassistant-ai/ha-mcp#1350))
  ([#&#8203;1379](homeassistant-ai/ha-mcp#1379))
- **haos-e2e**: Close out [#&#8203;1349](homeassistant-ai/ha-mcp#1349) — lifecycle, integrations, supervisor\_mock migration, no more skips
  ([#&#8203;1375](homeassistant-ai/ha-mcp#1375))
- **e2e**: Consolidate readiness gates onto /api/core/state (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1372](homeassistant-ai/ha-mcp#1372))
- **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1369](homeassistant-ai/ha-mcp#1369))
- Scaffold HAOS E2E tier image-build pipeline (refs [#&#8203;1281](homeassistant-ai/ha-mcp#1281))
  ([#&#8203;1326](homeassistant-ai/ha-mcp#1326))
- **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1346](homeassistant-ai/ha-mcp#1346))
- **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1308](homeassistant-ai/ha-mcp#1308))
- **e2e**: Unify dict-error message extraction across e2e tests (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1311](homeassistant-ai/ha-mcp#1311))
- **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;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
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Jun 8, 2026
…➔ 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 [#&#8203;1434](homeassistant-ai/ha-mcp#1434))
  ([#&#8203;1436](homeassistant-ai/ha-mcp#1436))
- Tool Security Policies — per-tool approval gating ([#&#8203;966](homeassistant-ai/ha-mcp#966))
  ([#&#8203;1421](homeassistant-ai/ha-mcp#1421))
- Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target
  ([#&#8203;1424](homeassistant-ai/ha-mcp#1424))
- Auto-backup edited entities before write/destructive tool calls (closes [#&#8203;1288](homeassistant-ai/ha-mcp#1288))
  ([#&#8203;1403](homeassistant-ai/ha-mcp#1403))
- Persistent settings UI for stdio mode
  ([#&#8203;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 ([#&#8203;1199](homeassistant-ai/ha-mcp#1199))
  ([#&#8203;1225](homeassistant-ai/ha-mcp#1225))
- Route entity-registration wait through WS events (closes [#&#8203;1152](homeassistant-ai/ha-mcp#1152))
  ([#&#8203;1382](homeassistant-ai/ha-mcp#1382))
- Add config subentry support
  ([#&#8203;1393](homeassistant-ai/ha-mcp#1393))
- Add Assist pipeline management tool
  ([#&#8203;1392](homeassistant-ai/ha-mcp#1392))
- Add knx to ha\_config\_set\_yaml allowlist
  ([#&#8203;1374](homeassistant-ai/ha-mcp#1374))
- Extend automation\_id parity to set/remove automation responses
  ([#&#8203;1343](homeassistant-ai/ha-mcp#1343))
- **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon)
  ([#&#8203;1361](homeassistant-ai/ha-mcp#1361))
- Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#&#8203;1148](homeassistant-ai/ha-mcp#1148))
  ([#&#8203;1328](homeassistant-ai/ha-mcp#1328))
- Return canonical script\_id from ha\_config\_get\_script ([#&#8203;1334](homeassistant-ai/ha-mcp#1334))
  ([#&#8203;1352](homeassistant-ai/ha-mcp#1352))
- Add automation\_id parity key to ha\_config\_get\_automation
  ([#&#8203;1329](homeassistant-ai/ha-mcp#1329))
- Reject empty/whitespace identifiers on registry-metadata writes (closes [#&#8203;1294](homeassistant-ai/ha-mcp#1294))
  ([#&#8203;1312](homeassistant-ai/ha-mcp#1312))
- Add HA brand assets for custom integration
  ([#&#8203;1317](homeassistant-ai/ha-mcp#1317))
- Unify ha\_config\_set\_helper response shape (closes [#&#8203;1293](homeassistant-ai/ha-mcp#1293))
  ([#&#8203;1303](homeassistant-ai/ha-mcp#1303))
- Mirror create-side validation guards onto update path (closes [#&#8203;1292](homeassistant-ai/ha-mcp#1292))
  ([#&#8203;1304](homeassistant-ai/ha-mcp#1304))
- Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST
  ([#&#8203;1063](homeassistant-ai/ha-mcp#1063))

##### Changed

- **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions
  ([#&#8203;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
  ([#&#8203;1411](homeassistant-ai/ha-mcp#1411))
- Credit [@&#8203;tomwilkie](https://github.com/tomwilkie) and six other contributors in README
  ([#&#8203;1400](homeassistant-ai/ha-mcp#1400))
- **[#&#8203;1157](homeassistant-ai/ha-mcp#1157: Bump skills-vendor + auto-update via Renovate + native for: field + scrub eval\_template anti-patterns
  ([#&#8203;1383](homeassistant-ai/ha-mcp#1383))
- Extend Boy Scout weasel-phrase list with common variants; clarify semantic match
  ([#&#8203;1373](homeassistant-ai/ha-mcp#1373))
- Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate
  ([#&#8203;1359](homeassistant-ai/ha-mcp#1359))
- Categorize Issue Labels table and document 6 reverse-drift labels
  ([#&#8203;1335](homeassistant-ai/ha-mcp#1335))
- Strip stale L-refs from test\_identifier\_validation\_family docstrings
  ([#&#8203;1324](homeassistant-ai/ha-mcp#1324))
- Align label refs with live label set and fix triaged-removal trigger
  ([#&#8203;1316](homeassistant-ai/ha-mcp#1316))
- Surface tool-discovery / categorized search
  ([#&#8203;1123](homeassistant-ai/ha-mcp#1123))
- Fix two stale ha\_get\_skill\_guide references missed in [#&#8203;1289](homeassistant-ai/ha-mcp#1289)
  ([#&#8203;1305](homeassistant-ai/ha-mcp#1305))
- Clarify setup wizard placeholders need braces removed ([#&#8203;1284](homeassistant-ai/ha-mcp#1284))
  ([#&#8203;1286](homeassistant-ai/ha-mcp#1286))

##### Fixed

- Remove counter from ha\_reload\_core targets ([#&#8203;1453](homeassistant-ai/ha-mcp#1453))
  ([#&#8203;1456](homeassistant-ai/ha-mcp#1456))
- **backup**: Post-timeout match correctness + state-gate (closes [#&#8203;1433](homeassistant-ai/ha-mcp#1433))
  ([#&#8203;1435](homeassistant-ai/ha-mcp#1435))
- Sync addon settings UI with Supervisor options end-to-end
  ([#&#8203;1420](homeassistant-ai/ha-mcp#1420))
- **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#&#8203;1413](homeassistant-ai/ha-mcp#1413), [#&#8203;1416](homeassistant-ai/ha-mcp#1416))
  ([#&#8203;1418](homeassistant-ai/ha-mcp#1418))
- Error-shape consistency for non-entity not-found (closes [#&#8203;1297](homeassistant-ai/ha-mcp#1297))
  ([#&#8203;1397](homeassistant-ai/ha-mcp#1397))
- Guard against silent automation overwrite on id mismatch ([#&#8203;1404](homeassistant-ai/ha-mcp#1404))
  ([#&#8203;1405](homeassistant-ai/ha-mcp#1405))
- Cache YAML instance to prevent CPU spikes in bulk edits ([#&#8203;1370](homeassistant-ai/ha-mcp#1370))
  ([#&#8203;1371](homeassistant-ai/ha-mcp#1371))
- **client**: Route get\_error\_log via hassio proxy on external-HAOS clients
  ([#&#8203;1360](homeassistant-ai/ha-mcp#1360))
- Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND
  ([#&#8203;1345](homeassistant-ai/ha-mcp#1345))
- Detect HA addon installs as http transport, not stdio ([#&#8203;1322](homeassistant-ai/ha-mcp#1322))
  ([#&#8203;1327](homeassistant-ai/ha-mcp#1327))
- Actionable 403 suggestion when addon has unmapped container ports ([#&#8203;1319](homeassistant-ai/ha-mcp#1319))
  ([#&#8203;1325](homeassistant-ai/ha-mcp#1325))
- Filter dismissed repairs in overview and system\_health ([#&#8203;1307](homeassistant-ai/ha-mcp#1307))
  ([#&#8203;1309](homeassistant-ai/ha-mcp#1309))
- Exit on HA container death + daily reset before CI check
  ([#&#8203;1295](homeassistant-ai/ha-mcp#1295))
- Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#&#8203;1291](homeassistant-ai/ha-mcp#1291))
  ([#&#8203;1301](homeassistant-ai/ha-mcp#1301))
- Allow str.replace in python\_transform; hint at search mode on IndexError
  ([#&#8203;1287](homeassistant-ai/ha-mcp#1287))
- **array\_patch**: Tighten validation and surface silent failures
  ([#&#8203;1285](homeassistant-ai/ha-mcp#1285))
- HA Core proxy fallback for ha\_get\_logs(source=system\_service) on non-addon installs
  ([#&#8203;1283](homeassistant-ai/ha-mcp#1283))

##### Performance Improvements

- Tighten \_poll\_for\_automation\_entity first-poll cadence
  ([#&#8203;1384](homeassistant-ai/ha-mcp#1384))
- Parallelize ha\_get\_system\_health optional sections via asyncio.gather
  ([#&#8203;1336](homeassistant-ai/ha-mcp#1336))

##### Refactoring

- **service**: Compact ha\_call\_service result default ([#&#8203;1446](homeassistant-ai/ha-mcp#1446))
  ([#&#8203;1447](homeassistant-ai/ha-mcp#1447))
- Rename ha\_update\_device → ha\_set\_device
  ([#&#8203;1444](homeassistant-ai/ha-mcp#1444))
- Remove duplicate flat area/floor list tools (consolidation followup to [#&#8203;1016](homeassistant-ai/ha-mcp#1016))
  ([#&#8203;1429](homeassistant-ai/ha-mcp#1429))
- **complexity**: Migrate tools\_utility.py to class-based pattern
  ([#&#8203;1423](homeassistant-ai/ha-mcp#1423))
- **complexity**: Reduce C901 violations in tools/ — batch 4
  ([#&#8203;1408](homeassistant-ai/ha-mcp#1408))
- Route \_poll\_for\_automation\_entity through WS event waiter (closes [#&#8203;1395](homeassistant-ai/ha-mcp#1395))
  ([#&#8203;1406](homeassistant-ai/ha-mcp#1406))
- **yaml**: Use threading.local subclass for cached instance
  ([#&#8203;1396](homeassistant-ai/ha-mcp#1396))
- Align dashboards 404 shape with sibling config tools
  ([#&#8203;1386](homeassistant-ai/ha-mcp#1386))
- Complete singular warning → warnings list migration repo-wide (closes [#&#8203;1332](homeassistant-ai/ha-mcp#1332))
  ([#&#8203;1341](homeassistant-ai/ha-mcp#1341))
- Complete warnings-list migration for lifecycle-write tools
  ([#&#8203;1340](homeassistant-ai/ha-mcp#1340))
- Drop redundant identifier echo key from ha\_config\_get\_automation
  ([#&#8203;1354](homeassistant-ai/ha-mcp#1354))
- Drop logger.error in config-tool except blocks ([#&#8203;1302](homeassistant-ai/ha-mcp#1302))
  ([#&#8203;1353](homeassistant-ai/ha-mcp#1353))
- Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#&#8203;1313](homeassistant-ai/ha-mcp#1313))
  ([#&#8203;1321](homeassistant-ai/ha-mcp#1321))
- Migrate tools\_config\_scenes inline empty-id guards to shared helper
  ([#&#8203;1320](homeassistant-ai/ha-mcp#1320))
- Remove ha\_get\_helper\_schema (closes [#&#8203;1186](homeassistant-ai/ha-mcp#1186))
  ([#&#8203;1315](homeassistant-ai/ha-mcp#1315))
- Consolidate skill tools; fix stable submodule packaging
  ([#&#8203;1289](homeassistant-ai/ha-mcp#1289))
- Align tools\_config\_automations.py error-handling with sibling pattern ([#&#8203;1290](homeassistant-ai/ha-mcp#1290))
  ([#&#8203;1298](homeassistant-ai/ha-mcp#1298))

***

<details>
<summary>Internal Changes</summary>

##### Fixed

- **ci**: Install libguestfs in HAOS publish workflow
  ([#&#8203;1358](homeassistant-ai/ha-mcp#1358))

##### Build System

- **deps**: Bump esbuild from 0.24.2 to 0.25.0 in /tests/js
  ([#&#8203;1427](homeassistant-ai/ha-mcp#1427))
- **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site
  ([#&#8203;1282](homeassistant-ai/ha-mcp#1282))
- **deps**: Bump astro from 6.1.6 to 6.1.10 in /site
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;1376](homeassistant-ai/ha-mcp#1376))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3
  ([#&#8203;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
  ([#&#8203;1437](homeassistant-ai/ha-mcp#1437))
- Share qcow2 cache + GHCR fallback between HAOS lanes
  ([#&#8203;1407](homeassistant-ai/ha-mcp#1407))
- Add ruff format --check on changed Python files
  ([#&#8203;1387](homeassistant-ai/ha-mcp#1387))
- Exempt assigned issues from stale bot
  ([#&#8203;1368](homeassistant-ai/ha-mcp#1368))
- **deps**: Bump the github-actions group with 3 updates
  ([#&#8203;1362](homeassistant-ai/ha-mcp#1362))

##### Refactoring

- Consolidate lovelace/dashboards/list through shared helper
  ([#&#8203;1344](homeassistant-ai/ha-mcp#1344))

##### Testing

- **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime
  ([#&#8203;1443](homeassistant-ai/ha-mcp#1443))
- **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep
  ([#&#8203;1430](homeassistant-ai/ha-mcp#1430))
- **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot
  ([#&#8203;1428](homeassistant-ai/ha-mcp#1428))
- JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script>
  ([#&#8203;1425](homeassistant-ai/ha-mcp#1425))
- **hacs**: Retry TestMcpToolsInstallation on flake
  ([#&#8203;1426](homeassistant-ai/ha-mcp#1426))
- **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#&#8203;1414](homeassistant-ai/ha-mcp#1414))
  ([#&#8203;1419](homeassistant-ai/ha-mcp#1419))
- **e2e**: Assert backend dispatch matches workflow env on every lane
  ([#&#8203;1409](homeassistant-ai/ha-mcp#1409))
- Escape ideographic space and format file ([#&#8203;1237](homeassistant-ai/ha-mcp#1237))
  ([#&#8203;1410](homeassistant-ai/ha-mcp#1410))
- **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#&#8203;1389](homeassistant-ai/ha-mcp#1389))
  ([#&#8203;1398](homeassistant-ai/ha-mcp#1398))
- **e2e**: Wait for addon state=started in haos proxy header test
  ([#&#8203;1402](homeassistant-ai/ha-mcp#1402))
- Pin remaining \_classify\_by\_message branches
  ([#&#8203;1385](homeassistant-ai/ha-mcp#1385))
- **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#&#8203;1350](homeassistant-ai/ha-mcp#1350))
  ([#&#8203;1379](homeassistant-ai/ha-mcp#1379))
- **haos-e2e**: Close out [#&#8203;1349](homeassistant-ai/ha-mcp#1349) — lifecycle, integrations, supervisor\_mock migration, no more skips
  ([#&#8203;1375](homeassistant-ai/ha-mcp#1375))
- **e2e**: Consolidate readiness gates onto /api/core/state (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1372](homeassistant-ai/ha-mcp#1372))
- **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1369](homeassistant-ai/ha-mcp#1369))
- Scaffold HAOS E2E tier image-build pipeline (refs [#&#8203;1281](homeassistant-ai/ha-mcp#1281))
  ([#&#8203;1326](homeassistant-ai/ha-mcp#1326))
- **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1346](homeassistant-ai/ha-mcp#1346))
- **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1308](homeassistant-ai/ha-mcp#1308))
- **e2e**: Unify dict-error message extraction across e2e tests (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;1311](homeassistant-ai/ha-mcp#1311))
- **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#&#8203;366](homeassistant-ai/ha-mcp#366))
  ([#&#8203;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
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Jun 10, 2026
…➔ 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 [#&#8203;1567](https://github.com/homeassistant-ai/ha-mcp/issues/1567))
  ([#&#8203;1568](https://github.com/homeassistant-ai/ha-mcp/pull/1568))
- Expose all user-tunable env vars in the settings UI (add-on parity)
  ([#&#8203;1554](https://github.com/homeassistant-ai/ha-mcp/pull/1554))
- Warn when default MCP\_SECRET\_PATH is bound non-loopback
  ([#&#8203;1472](https://github.com/homeassistant-ai/ha-mcp/pull/1472))
- **search**: Consolidate ha\_search\_entities + ha\_deep\_search into ha\_search
  ([#&#8203;1529](https://github.com/homeassistant-ai/ha-mcp/pull/1529))
- **addon**: Install the MCP Server add-on from the ha\_mcp\_tools integration
  ([#&#8203;1528](https://github.com/homeassistant-ai/ha-mcp/pull/1528))
- Add opt-in dashboard screenshot mode
  ([#&#8203;1510](https://github.com/homeassistant-ai/ha-mcp/pull/1510))
- Add Linux support for install & docs
  ([#&#8203;1096](https://github.com/homeassistant-ai/ha-mcp/pull/1096))
- Surface the web settings page for non-add-on installs ([#&#8203;1458](https://github.com/homeassistant-ai/ha-mcp/issues/1458))
  ([#&#8203;1511](https://github.com/homeassistant-ai/ha-mcp/pull/1511))
- Convert Pydantic arg-validation errors to actionable ToolErrors
  ([#&#8203;1491](https://github.com/homeassistant-ai/ha-mcp/pull/1491))
- Per-key toggles for automation/script/scene in packages/\*.yaml
  ([#&#8203;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 ([#&#8203;1182](https://github.com/homeassistant-ai/ha-mcp/issues/1182))
  ([#&#8203;1448](https://github.com/homeassistant-ai/ha-mcp/pull/1448))
- Detect last\_changed/last\_updated duration math and suggest for: field ([#&#8203;1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157))
  ([#&#8203;1264](https://github.com/homeassistant-ai/ha-mcp/pull/1264))
- Advanced settings panel + nested beta master toggle ([#&#8203;1164](https://github.com/homeassistant-ai/ha-mcp/issues/1164))
  ([#&#8203;1431](https://github.com/homeassistant-ai/ha-mcp/pull/1431))
- Allow automation/script/scene yaml\_path in packages/\*.yaml only
  ([#&#8203;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)
  ([#&#8203;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
  ([#&#8203;1481](https://github.com/homeassistant-ai/ha-mcp/pull/1481))
- **security**: Note that security-advisory disposition is API-blind (UI-only)
  ([#&#8203;1561](https://github.com/homeassistant-ai/ha-mcp/pull/1561))
- **tools**: Sharpen ha\_eval\_template usage routing for compute-from-state queries
  ([#&#8203;1550](https://github.com/homeassistant-ai/ha-mcp/pull/1550))
- Differentiate ha-mcp from Home Assistant's built-in MCP Server
  ([#&#8203;1542](https://github.com/homeassistant-ai/ha-mcp/pull/1542))
- Update advanced mode notes
  ([#&#8203;1533](https://github.com/homeassistant-ai/ha-mcp/pull/1533))
- **[#&#8203;1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157)**: Scripts native-for: guidance + fix numeric\_state-condition for: overclaim
  ([#&#8203;1480](https://github.com/homeassistant-ai/ha-mcp/pull/1480))
- Clarify add-on vs uvx; add Codex + HTTP-native client setup
  ([#&#8203;1478](https://github.com/homeassistant-ai/ha-mcp/pull/1478))
- **security**: Explicit threat model for trusted clients, LAN, sandbox, and OAuth tokens
  ([#&#8203;1463](https://github.com/homeassistant-ai/ha-mcp/pull/1463))
- Clarify telemetry is a planned future feature, not implemented
  ([#&#8203;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 [#&#8203;1540](https://github.com/homeassistant-ai/ha-mcp/issues/1540))
  ([#&#8203;1566](https://github.com/homeassistant-ai/ha-mcp/pull/1566))
- **energy**: Accept "water" energy source in ha\_manage\_energy\_prefs
  ([#&#8203;1553](https://github.com/homeassistant-ai/ha-mcp/pull/1553))
- **tools**: Use action: not service: in automation docstring examples
  ([#&#8203;1539](https://github.com/homeassistant-ai/ha-mcp/pull/1539))
- **security**: Narrow GHSA-mc92-ww4q-6fg4 to the masker and log redaction
  ([#&#8203;1512](https://github.com/homeassistant-ai/ha-mcp/pull/1512))
- **addon**: Restrict settings UI root routes to HA ingress
  ([#&#8203;1508](https://github.com/homeassistant-ai/ha-mcp/pull/1508))
- Add name attributes to generated settings-UI form controls (a11y)
  ([#&#8203;1497](https://github.com/homeassistant-ai/ha-mcp/pull/1497))
- Add-on-aware code-mode locked note + suppress settings-UI favicon 404
  ([#&#8203;1494](https://github.com/homeassistant-ai/ha-mcp/pull/1494))
- Surface the real reason a WebSocket connection failed
  ([#&#8203;1495](https://github.com/homeassistant-ai/ha-mcp/pull/1495))
- Remove str from ha\_bulk\_control.operations schema + fix wrong-reason test
  ([#&#8203;1492](https://github.com/homeassistant-ai/ha-mcp/pull/1492))
- Remove str from bool/int param schemas across all tools
  ([#&#8203;1490](https://github.com/homeassistant-ai/ha-mcp/pull/1490))
- **addon**: Expose non-beta tool options on the stable add-on
  ([#&#8203;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
  ([#&#8203;1486](https://github.com/homeassistant-ai/ha-mcp/pull/1486))
- Refine last\_changed/last\_updated duration-math detector ([#&#8203;1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157))
  ([#&#8203;1483](https://github.com/homeassistant-ai/ha-mcp/pull/1483))
- Remove str from config param schema on service and entity tools
  ([#&#8203;1487](https://github.com/homeassistant-ai/ha-mcp/pull/1487))
- Surface flow-helper config to agents reading UI-created templates
  ([#&#8203;1474](https://github.com/homeassistant-ai/ha-mcp/pull/1474))
- Remove str from config param schema on set tools
  ([#&#8203;1485](https://github.com/homeassistant-ai/ha-mcp/pull/1485))
- Route malformed ha\_mcp\_tools version to a distinct reinstall error
  ([#&#8203;1484](https://github.com/homeassistant-ai/ha-mcp/pull/1484))
- Persist DCR client registrations and HMAC secret across restarts ([#&#8203;1261](https://github.com/homeassistant-ai/ha-mcp/issues/1261))
  ([#&#8203;1265](https://github.com/homeassistant-ai/ha-mcp/pull/1265))
- Stop dev builds from publishing the :latest Docker tag
  ([#&#8203;1477](https://github.com/homeassistant-ai/ha-mcp/pull/1477))
- Subscribe to HACS dispatch signal instead of 10x1s blind poll
  ([#&#8203;1455](https://github.com/homeassistant-ai/ha-mcp/pull/1455))
- Reject python\_transform while loops
  ([#&#8203;1462](https://github.com/homeassistant-ai/ha-mcp/pull/1462))

##### Performance Improvements

- Fast-fail HACS not-found lookups + batch-verify deep-search E2E fixtures ([#&#8203;1515](https://github.com/homeassistant-ai/ha-mcp/issues/1515))
  ([#&#8203;1552](https://github.com/homeassistant-ai/ha-mcp/pull/1552))

##### Refactoring

- Add display title to ha\_get\_skill\_guide tool
  ([#&#8203;1543](https://github.com/homeassistant-ai/ha-mcp/pull/1543))
- Fold ha\_check\_config into ha\_get\_system\_health include="config\_check"
  ([#&#8203;1516](https://github.com/homeassistant-ai/ha-mcp/pull/1516))
- **c901**: Smart\_search.py below C901 threshold
  ([#&#8203;1507](https://github.com/homeassistant-ai/ha-mcp/pull/1507))
- **hacs**: Consolidate HACS tools into ha\_get\_hacs + ha\_manage\_hacs ([#&#8203;1045](https://github.com/homeassistant-ai/ha-mcp/issues/1045))
  ([#&#8203;1502](https://github.com/homeassistant-ai/ha-mcp/pull/1502))
- **c901**: Tools\_config\_helpers.py below C901 threshold
  ([#&#8203;1498](https://github.com/homeassistant-ai/ha-mcp/pull/1498))
- **complexity**: Reduce C901 in tools\_addons.py via class-based pattern
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;1571](https://github.com/homeassistant-ai/ha-mcp/pull/1571))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.19
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;1565](https://github.com/homeassistant-ai/ha-mcp/pull/1565))
- Make sync-tool-docs push resilient to concurrent master advances
  ([#&#8203;1564](https://github.com/homeassistant-ai/ha-mcp/pull/1564))
- Fix stale token-cap comment and harden triage budget tests ([#&#8203;1514](https://github.com/homeassistant-ai/ha-mcp/issues/1514))
  ([#&#8203;1560](https://github.com/homeassistant-ai/ha-mcp/pull/1560))
- **deps**: Bump the github-actions group with 2 updates
  ([#&#8203;1556](https://github.com/homeassistant-ai/ha-mcp/pull/1556))
- Budget triage prompt dynamically under the GitHub Models cap ([#&#8203;1514](https://github.com/homeassistant-ai/ha-mcp/issues/1514))
  ([#&#8203;1522](https://github.com/homeassistant-ai/ha-mcp/pull/1522))
- Reduce Docker Hub pulls in performance-tests workflow
  ([#&#8203;1549](https://github.com/homeassistant-ai/ha-mcp/pull/1549))
- Add JavaScript to the CodeQL code-quality gate
  ([#&#8203;1548](https://github.com/homeassistant-ai/ha-mcp/pull/1548))
- Add CodeQL code-quality CI gate and clear all code-quality findings
  ([#&#8203;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)
  ([#&#8203;1496](https://github.com/homeassistant-ai/ha-mcp/pull/1496))
- Issue bot v2 — GitHub Models triage, needs-info auto-close, duplicate detection
  ([#&#8203;1442](https://github.com/homeassistant-ai/ha-mcp/pull/1442))

##### Refactoring

- Extract settings-UI JavaScript and CSS to separate files
  ([#&#8203;1505](https://github.com/homeassistant-ai/ha-mcp/pull/1505))
- Collapse settings-UI route registration into one table
  ([#&#8203;1504](https://github.com/homeassistant-ai/ha-mcp/pull/1504))

##### Testing

- **oauth**: Add HTTP smoke tests for OAuth metadata-discovery endpoints
  ([#&#8203;1562](https://github.com/homeassistant-ai/ha-mcp/pull/1562))
- **uat**: Relabel c01 as a mode-discrimination probe (taxonomy consistency)
  ([#&#8203;1563](https://github.com/homeassistant-ai/ha-mcp/pull/1563))
- **uat**: Rework c01 routing probe to ha\_search registry-listing mode after [#&#8203;1529](https://github.com/homeassistant-ai/ha-mcp/issues/1529)
  ([#&#8203;1559](https://github.com/homeassistant-ai/ha-mcp/pull/1559))
- **uat**: Add response\_contains\_any check and always log agent responses
  ([#&#8203;1537](https://github.com/homeassistant-ai/ha-mcp/pull/1537))
- **uat**: Treat request timeout as per-story failure, not suite abort
  ([#&#8203;1536](https://github.com/homeassistant-ai/ha-mcp/pull/1536))
- **uat**: Harden BAT story runner against agent crashes
  ([#&#8203;1535](https://github.com/homeassistant-ai/ha-mcp/pull/1535))
- **uat**: Log model and quantization in BAT story results
  ([#&#8203;1525](https://github.com/homeassistant-ai/ha-mcp/pull/1525))
- Capture reasoning tokens and detect inert --no-think in BAT openai agent
  ([#&#8203;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 [#&#8203;1434](https://github.com/homeassistant-ai/ha-mcp/issues/1434))
  ([#&#8203;1436](https://github.com/homeassistant-ai/ha-mcp/pull/1436))
- Tool Security Policies — per-tool approval gating ([#&#8203;966](https://github.com/homeassistant-ai/ha-mcp/issues/966))
  ([#&#8203;1421](https://github.com/homeassistant-ai/ha-mcp/pull/1421))
- Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target
  ([#&#8203;1424](https://github.com/homeassistant-ai/ha-mcp/pull/1424))
- Auto-backup edited entities before write/destructive tool calls (closes [#&#8203;1288](https://github.com/homeassistant-ai/ha-mcp/issues/1288))
  ([#&#8203;1403](https://github.com/homeassistant-ai/ha-mcp/pull/1403))
- Persistent settings UI for stdio mode
  ([#&#8203;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 ([#&#8203;1199](https://github.com/homeassistant-ai/ha-mcp/issues/1199))
  ([#&#8203;1225](https://github.com/homeassistant-ai/ha-mcp/pull/1225))
- Route entity-registration wait through WS events (closes [#&#8203;1152](https://github.com/homeassistant-ai/ha-mcp/issues/1152))
  ([#&#8203;1382](https://github.com/homeassistant-ai/ha-mcp/pull/1382))
- Add config subentry support
  ([#&#8203;1393](https://github.com/homeassistant-ai/ha-mcp/pull/1393))
- Add Assist pipeline management tool
  ([#&#8203;1392](https://github.com/homeassistant-ai/ha-mcp/pull/1392))
- Add knx to ha\_config\_set\_yaml allowlist
  ([#&#8203;1374](https://github.com/homeassistant-ai/ha-mcp/pull/1374))
- Extend automation\_id parity to set/remove automation responses
  ([#&#8203;1343](https://github.com/homeassistant-ai/ha-mcp/pull/1343))
- **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon)
  ([#&#8203;1361](https://github.com/homeassistant-ai/ha-mcp/pull/1361))
- Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#&#8203;1148](https://github.com/homeassistant-ai/ha-mcp/issues/1148))
  ([#&#8203;1328](https://github.com/homeassistant-ai/ha-mcp/pull/1328))
- Return canonical script\_id from ha\_config\_get\_script ([#&#8203;1334](https://github.com/homeassistant-ai/ha-mcp/issues/1334))
  ([#&#8203;1352](https://github.com/homeassistant-ai/ha-mcp/pull/1352))
- Add automation\_id parity key to ha\_config\_get\_automation
  ([#&#8203;1329](https://github.com/homeassistant-ai/ha-mcp/pull/1329))
- Reject empty/whitespace identifiers on registry-metadata writes (closes [#&#8203;1294](https://github.com/homeassistant-ai/ha-mcp/issues/1294))
  ([#&#8203;1312](https://github.com/homeassistant-ai/ha-mcp/pull/1312))
- Add HA brand assets for custom integration
  ([#&#8203;1317](https://github.com/homeassistant-ai/ha-mcp/pull/1317))
- Unify ha\_config\_set\_helper response shape (closes [#&#8203;1293](https://github.com/homeassistant-ai/ha-mcp/issues/1293))
  ([#&#8203;1303](https://github.com/homeassistant-ai/ha-mcp/pull/1303))
- Mirror create-side validation guards onto update path (closes [#&#8203;1292](https://github.com/homeassistant-ai/ha-mcp/issues/1292))
  ([#&#8203;1304](https://github.com/homeassistant-ai/ha-mcp/pull/1304))
- Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST
  ([#&#8203;1063](https://github.com/homeassistant-ai/ha-mcp/pull/1063))

##### Changed

- **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions
  ([#&#8203;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
  ([#&#8203;1411](https://github.com/homeassistant-ai/ha-mcp/pull/1411))
- Credit [@&#8203;tomwilkie](https://github.com/tomwilkie) and six other contributors in README
  ([#&#8203;1400](https://github.com/homeassistant-ai/ha-mcp/pull/1400))
- **[#&#8203;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
  ([#&#8203;1383](https://github.com/homeassistant-ai/ha-mcp/pull/1383))
- Extend Boy Scout weasel-phrase list with common variants; clarify semantic match
  ([#&#8203;1373](https://github.com/homeassistant-ai/ha-mcp/pull/1373))
- Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate
  ([#&#8203;1359](https://github.com/homeassistant-ai/ha-mcp/pull/1359))
- Categorize Issue Labels table and document 6 reverse-drift labels
  ([#&#8203;1335](https://github.com/homeassistant-ai/ha-mcp/pull/1335))
- Strip stale L-refs from test\_identifier\_validation\_family docstrings
  ([#&#8203;1324](https://github.com/homeassistant-ai/ha-mcp/pull/1324))
- Align label refs with live label set and fix triaged-removal trigger
  ([#&#8203;1316](https://github.com/homeassistant-ai/ha-mcp/pull/1316))
- Surface tool-discovery / categorized search
  ([#&#8203;1123](https://github.com/homeassistant-ai/ha-mcp/pull/1123))
- Fix two stale ha\_get\_skill\_guide references missed in [#&#8203;1289](https://github.com/homeassistant-ai/ha-mcp/issues/1289)
  ([#&#8203;1305](https://github.com/homeassistant-ai/ha-mcp/pull/1305))
- Clarify setup wizard placeholders need braces removed ([#&#8203;1284](https://github.com/homeassistant-ai/ha-mcp/issues/1284))
  ([#&#8203;1286](https://github.com/homeassistant-ai/ha-mcp/pull/1286))

##### Fixed

- Remove counter from ha\_reload\_core targets ([#&#8203;1453](https://github.com/homeassistant-ai/ha-mcp/issues/1453))
  ([#&#8203;1456](https://github.com/homeassistant-ai/ha-mcp/pull/1456))
- **backup**: Post-timeout match correctness + state-gate (closes [#&#8203;1433](https://github.com/homeassistant-ai/ha-mcp/issues/1433))
  ([#&#8203;1435](https://github.com/homeassistant-ai/ha-mcp/pull/1435))
- Sync addon settings UI with Supervisor options end-to-end
  ([#&#8203;1420](https://github.com/homeassistant-ai/ha-mcp/pull/1420))
- **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#&#8203;1413](https://github.com/homeassistant-ai/ha-mcp/issues/1413), [#&#8203;1416](https://github.com/homeassistant-ai/ha-mcp/issues/1416))
  ([#&#8203;1418](https://github.com/homeassistant-ai/ha-mcp/pull/1418))
- Error-shape consistency for non-entity not-found (closes [#&#8203;1297](https://github.com/homeassistant-ai/ha-mcp/issues/1297))
  ([#&#8203;1397](https://github.com/homeassistant-ai/ha-mcp/pull/1397))
- Guard against silent automation overwrite on id mismatch ([#&#8203;1404](https://github.com/homeassistant-ai/ha-mcp/issues/1404))
  ([#&#8203;1405](https://github.com/homeassistant-ai/ha-mcp/pull/1405))
- Cache YAML instance to prevent CPU spikes in bulk edits ([#&#8203;1370](https://github.com/homeassistant-ai/ha-mcp/issues/1370))
  ([#&#8203;1371](https://github.com/homeassistant-ai/ha-mcp/pull/1371))
- **client**: Route get\_error\_log via hassio proxy on external-HAOS clients
  ([#&#8203;1360](https://github.com/homeassistant-ai/ha-mcp/pull/1360))
- Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND
  ([#&#8203;1345](https://github.com/homeassistant-ai/ha-mcp/pull/1345))
- Detect HA addon installs as http transport, not stdio ([#&#8203;1322](https://github.com/homeassistant-ai/ha-mcp/issues/1322))
  ([#&#8203;1327](https://github.com/homeassistant-ai/ha-mcp/pull/1327))
- Actionable 403 suggestion when addon has unmapped container ports ([#&#8203;1319](https://github.com/homeassistant-ai/ha-mcp/issues/1319))
  ([#&#8203;1325](https://github.com/homeassistant-ai/ha-mcp/pull/1325))
- Filter dismissed repairs in overview and system\_health ([#&#8203;1307](https://github.com/homeassistant-ai/ha-mcp/issues/1307))
  ([#&#8203;1309](https://github.com/homeassistant-ai/ha-mcp/pull/1309))
- Exit on HA container death + daily reset before CI check
  ([#&#8203;1295](https://github.com/homeassistant-ai/ha-mcp/pull/1295))
- Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#&#8203;1291](https://github.com/homeassistant-ai/ha-mcp/issues/1291))
  ([#&#8203;1301](https://github.com/homeassistant-ai/ha-mcp/pull/1301))
- Allow str.replace in python\_transform; hint at search mode on IndexError
  ([#&#8203;1287](https://github.com/homeassistant-ai/ha-mcp/pull/1287))
- **array\_patch**: Tighten validation and surface silent failures
  ([#&#8203;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
  ([#&#8203;1283](https://github.com/homeassistant-ai/ha-mcp/pull/1283))

##### Performance Improvements

- Tighten \_poll\_for\_automation\_entity first-poll cadence
  ([#&#8203;1384](https://github.com/homeassistant-ai/ha-mcp/pull/1384))
- Parallelize ha\_get\_system\_health optional sections via asyncio.gather
  ([#&#8203;1336](https://github.com/homeassistant-ai/ha-mcp/pull/1336))

##### Refactoring

- **service**: Compact ha\_call\_service result default ([#&#8203;1446](https://github.com/homeassistant-ai/ha-mcp/issues/1446))
  ([#&#8203;1447](https://github.com/homeassistant-ai/ha-mcp/pull/1447))
- Rename ha\_update\_device → ha\_set\_device
  ([#&#8203;1444](https://github.com/homeassistant-ai/ha-mcp/pull/1444))
- Remove duplicate flat area/floor list tools (consolidation followup to [#&#8203;1016](https://github.com/homeassistant-ai/ha-mcp/issues/1016))
  ([#&#8203;1429](https://github.com/homeassistant-ai/ha-mcp/pull/1429))
- **complexity**: Migrate tools\_utility.py to class-based pattern
  ([#&#8203;1423](https://github.com/homeassistant-ai/ha-mcp/pull/1423))
- **complexity**: Reduce C901 violations in tools/ — batch 4
  ([#&#8203;1408](https://github.com/homeassistant-ai/ha-mcp/pull/1408))
- Route \_poll\_for\_automation\_entity through WS event waiter (closes [#&#8203;1395](https://github.com/homeassistant-ai/ha-mcp/issues/1395))
  ([#&#8203;1406](https://github.com/homeassistant-ai/ha-mcp/pull/1406))
- **yaml**: Use threading.local subclass for cached instance
  ([#&#8203;1396](https://github.com/homeassistant-ai/ha-mcp/pull/1396))
- Align dashboards 404 shape with sibling config tools
  ([#&#8203;1386](https://github.com/homeassistant-ai/ha-mcp/pull/1386))
- Complete singular warning → warnings list migration repo-wide (closes [#&#8203;1332](https://github.com/homeassistant-ai/ha-mcp/issues/1332))
  ([#&#8203;1341](https://github.com/homeassistant-ai/ha-mcp/pull/1341))
- Complete warnings-list migration for lifecycle-write tools
  ([#&#8203;1340](https://github.com/homeassistant-ai/ha-mcp/pull/1340))
- Drop redundant identifier echo key from ha\_config\_get\_automation
  ([#&#8203;1354](https://github.com/homeassistant-ai/ha-mcp/pull/1354))
- Drop logger.error in config-tool except blocks ([#&#8203;1302](https://github.com/homeassistant-ai/ha-mcp/issues/1302))
  ([#&#8203;1353](https://github.com/homeassistant-ai/ha-mcp/pull/1353))
- Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#&#8203;1313](https://github.com/homeassistant-ai/ha-mcp/issues/1313))
  ([#&#8203;1321](https://github.com/homeassistant-ai/ha-mcp/pull/1321))
- Migrate tools\_config\_scenes inline empty-id guards to shared helper
  ([#&#8203;1320](https://github.com/homeassistant-ai/ha-mcp/pull/1320))
- Remove ha\_get\_helper\_schema (closes [#&#8203;1186](https://github.com/homeassistant-ai/ha-mcp/issues/1186))
  ([#&#8203;1315](https://github.com/homeassistant-ai/ha-mcp/pull/1315))
- Consolidate skill tools; fix stable submodule packaging
  ([#&#8203;1289](https://github.com/homeassistant-ai/ha-mcp/pull/1289))
- Align tools\_config\_automations.py error-handling with sibling pattern ([#&#8203;1290](https://github.com/homeassistant-ai/ha-mcp/issues/1290))
  ([#&#8203;1298](https://github.com/homeassistant-ai/ha-mcp/pull/1298))

***

<details>
<summary>Internal Changes</summary>

##### Fixed

- **ci**: Install libguestfs in HAOS publish workflow
  ([#&#8203;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
  ([#&#8203;1427](https://github.com/homeassistant-ai/ha-mcp/pull/1427))
- **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site
  ([#&#8203;1282](https://github.com/homeassistant-ai/ha-mcp/pull/1282))
- **deps**: Bump astro from 6.1.6 to 6.1.10 in /site
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;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
  ([#&#8203;1376](https://github.com/homeassistant-ai/ha-mcp/pull/1376))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3
  ([#&#8203;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
  ([#&#8203;1437](https://github.com/homeassistant-ai/ha-mcp/pull/1437))
- Share qcow2 cache + GHCR fallback between HAOS lanes
  ([#&#8203;1407](https://github.com/homeassistant-ai/ha-mcp/pull/1407))
- Add ruff format --check on changed Python files
  ([#&#8203;1387](https://github.com/homeassistant-ai/ha-mcp/pull/1387))
- Exempt assigned issues from stale bot
  ([#&#8203;1368](https://github.com/homeassistant-ai/ha-mcp/pull/1368))
- **deps**: Bump the github-actions group with 3 updates
  ([#&#8203;1362](https://github.com/homeassistant-ai/ha-mcp/pull/1362))

##### Refactoring

- Consolidate lovelace/dashboards/list through shared helper
  ([#&#8203;1344](https://github.com/homeassistant-ai/ha-mcp/pull/1344))

##### Testing

- **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime
  ([#&#8203;1443](https://github.com/homeassistant-ai/ha-mcp/pull/1443))
- **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep
  ([#&#8203;1430](https://github.com/homeassistant-ai/ha-mcp/pull/1430))
- **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot
  ([#&#8203;1428](https://github.com/homeassistant-ai/ha-mcp/pull/1428))
- JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script>
  ([#&#8203;1425](https://github.com/homeassistant-ai/ha-mcp/pull/1425))
- **hacs**: Retry TestMcpToolsInstallation on flake
  ([#&#8203;1426](https://github.com/homeassistant-ai/ha-mcp/pull/1426))
- **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#&#8203;1414](https://github.com/homeassistant-ai/ha-mcp/issues/1414))
  ([#&#8203;1419](https://github.com/homeassistant-ai/ha-mcp/pull/1419))
- **e2e**: Assert backend dispatch matches workflow env on every lane
  ([#&#8203;1409](https://github.com/homeassistant-ai/ha-mcp/pull/1409))
- Escape ideographic space and format file ([#&#8203;1237](https://github.com/homeassistant-ai/ha-mcp/issues/1237))
  ([#&#8203;1410](https://github.com/homeassistant-ai/ha-mcp/pull/1410))
- **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#&#8203;1389](https://github.com/homeassistant-ai/ha-mcp/issues/1389))
  ([#&#8203;1398](https://github.com/homeassistant-ai/ha-mcp/pull/1398))
- **e2e**: Wait for addon state=started in haos proxy header test
  ([#&#8203;1402](https://github.com/homeassistant-ai/ha-mcp/pull/1402))
- Pin remaining \_classify\_by\_message branches
  ([#&#8203;1385](https://github.com/homeassistant-ai/ha-mcp/pull/1385))
- **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#&#8203;1350](https://github.com/homeassistant-ai/ha-mcp/issues/1350))
  ([#&#8203;1379](https://github.com/homeassistant-ai/ha-mcp/pull/1379))
- **haos-e2e**: Close out [#&#8203;1349](https://github.com/homeassistant-ai/ha-mcp/issues/1349) — lifecycle, integrations, supervisor\_mock migration, no more skips
  ([#&#8203;1375](https://github.com/homeassistant-ai/ha-mcp/pull/1375))
- **e2e**: Consolidate readiness gates onto /api/core/state (refs [#&#8203;366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
  ([#&#8203;1372](https://github.com/homeassistant-ai/ha-mcp/pull/1372))
- **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#&#8203;366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
  ([#&#8203;1369](https://github.com/homeassistant-ai/ha-mcp/pull/1369))
- Scaffold HAOS E2E tier image-build pipeline (refs [#&#8203;1281](https://github.com/homeassistant-ai/ha-mcp/issues/1281))
  ([#&#8203;1326](https://github.com/homeassistant-ai/ha-mcp/pull/1326))
- **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#&#8203;366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
  ([#&#8203;1346](https://github.com/homeassistant-ai/ha-mcp/pull/1346))
- **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#&#8203;366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
  ([#&#8203;1308](https://github.com/homeassistant-ai/ha-mcp/pull/1308))
- **e2e**: Unify dict-error message extraction across e2e tests (refs [#&#8203;366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
  ([#&#8203;1311](https://github.com/homeassistant-ai/ha-mcp/pull/1311))
- **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#&#8203;366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
  ([#&#8203;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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add ha_get_home_topology — single read-only call returning floor/area hierarchy

2 participants