ci: budget issue-triage prompt under the GitHub Models token cap (#1514) - #1522
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses issue #1514 by implementing a robust token-budgeting strategy for the issue-triage workflow. By proactively trimming prompt components—starting with duplicate candidates and tool lists before truncating the issue body—the system avoids exceeding the GitHub Models input token limit. Additionally, it introduces a fallback mechanism to handle 413 errors gracefully, ensuring that the triage process remains resilient even when encountering unexpectedly large inputs. Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. 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
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new Node.js script, scripts/verify_triage_prompt_budget.mjs, designed to verify that the issue-triage prompt-budgeting algorithm keeps the assembled prompt under the input token limit. The review feedback identifies a potential TypeError in the fitToBudget function if parameters like issueBody, toolSection, or duplicateSection are omitted or passed as null/undefined, and suggests defaulting them to empty strings to ensure robustness.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Ready for review. All checks green; the one Gemini nit (null-safe section args in the verify harness) is fixed in d005f84 and the thread resolved. Quick summary of choices:
The end-to-end path still can't run in CI without a checkout in this workflow, so the harness mirrors the trim logic rather than importing it. If you'd rather have it truly shared, I can add a checkout + move the assembly into an importable module as a follow-up - your call. |
Patch76
left a comment
There was a problem hiding this comment.
This fixes the right root cause for #1514 — the fixed overhead (framing + BM25 candidates + tool list) was already at the cap before the body, and trimming in priority order (duplicates → tool list → body-to-floor) keeps the actual issue text longest. Input handling stays on the process.env path and the 413 retry is a sensible net.
Two optional, non-blocking notes:
The body-floor branch doesn't re-assert the budget. After issueBody is clamped to BODY_FLOOR, the prompt isn't re-checked against TOKEN_BUDGET. Today that can't breach the cap — the fixed framing is a small fraction of the budget, so framing + floor is far under 8000 — so it only matters if the static framing later grows several-fold, where the prompt would ship over-cap and lean entirely on the 413 retry (a mid-content substring, not a clean trim). A one-line core.warning when the post-floor estimate is still over budget would make the 413 path's "this should not fire" comment self-enforcing.
The harness's floor assertion doesn't exercise the floor. In verify_triage_prompt_budget.mjs, check #2 runs with a small staticText, so the body lands at the overflow-derived length (~21000 chars), not the 2000-char floor — >= BODY_FLOOR passes without driving the body to the Math.max clamp. A case with a large staticText would actually test that path. Since the harness isn't run in CI, the "keep the two in sync" note is also manual-only.
Neither blocks — the change solves #1514 as-is. Both are optional hardening on the triage-process workflow, so @kingpanther13, your call whether either is worth folding in here or leaving for a follow-up.
kingpanther13
left a comment
There was a problem hiding this comment.
Thanks for this — the diagnosis is spot-on and the emphasis is right: proactive budgeting as the primary fix with the 413 catch as a backstop, rather than relying on retry alone. The const→let + assemble() closure refactor is correct, the change is security-clean (no new triggers, permissions, or secrets; issue content stays prompt data), and shipping a verification harness for a checkout-less CI step is genuinely appreciated. I ran node scripts/verify_triage_prompt_budget.mjs and it passes as described.
Two things I'd like to see addressed before merge. Both are small and both directly strengthen the guarantee this PR is making.
1. The budgeter never trims changelog, so the "under the cap" guarantee has a gap.
The trim block drops duplicateSection → toolSection → truncates issueBody to a floor, but changelog (the "Recent Release Context" section, issue-triage.yml:635) is left untouched. changelog is a variable input — up to ~20 unreleased commit subjects plus 3x head -50 of CHANGELOG.md (issue-triage.yml:519-532) — which can plausibly reach ~15-21k+ chars for verbose semantic-release entries. Once it does, the assembled prompt stays over the 7000-token target even after every other section is trimmed to the floor, and falls through to the 413 path: the exact failure this PR fixes, just at a higher input threshold.
The harness doesn't catch this because its worst case uses a fixed x(7000) stand-in for static framing and doesn't model changelog at all, so a green run doesn't actually exercise the real worst case.
Suggestion: add changelog as a fourth, lower-priority trim target (truncate to a floor, after duplicates/tools and before or alongside the body), and add a changelogText term to the harness so the worst-case assertion reflects the real untrimmable load.
2. The verification harness isn't wired into CI.
scripts/verify_triage_prompt_budget.mjs is referenced nowhere except the comment in the workflow, so nothing runs it on PRs and nothing enforces that the two copies stay in sync (TOKEN_BUDGET, BODY_FLOOR, drop order). Since it's a deliberate copy of logic that can't be imported (checkout-less workflow), that drift is the precise risk it exists to guard against. The repo already runs Node test harnesses in CI (pr.yml installs node; tests/js/harness.mjs; subprocess wrappers under tests/src/unit/), so this fits an existing pattern. A one-line node scripts/verify_triage_prompt_budget.mjs step (or a small pytest subprocess wrapper) would close it. Optional extra guard: have the harness read the constants and drop-order out of the workflow file and assert they match.
Non-blocking suggestions:
- After all trims, if the prompt is still over budget (the body floor clamped it), only the routine info line is logged. A
core.warningnaming the 413 backstop would make that path visible instead of silent (same root cause as #1). - Two harness assertions are currently vacuous: "body never trimmed below floor" passes without the floor ever binding (the huge-body case lands at ~21k chars, far above the 2k floor), and "duplicates dropped first" never forces the tool drop, so it doesn't actually prove ordering. Adding a case that clamps the body to exactly
BODY_FLOOR, and one that forces both drops while asserting the body survives intact, would make them test what they claim. The "worst case" case also resolves at ~5750 tokens with the body untouched, so the label is a little optimistic. prompt.substring(0, 24000)in the 413 retry is a bare constant decoupled from the cap — a one-line comment (~6000 tokens at chars/4, under the 8000 cap) would document the relationship.
None of the 413 backstop concerns are silent failures — a double-413 or a truncated-prompt garbage response degrades to the existing triage-failed path via continue-on-error and the guarded JSON.parse, which is correct behavior.
|
Thanks @Patch76, folded both in (d005f84 was the Gemini nit; this is the new commit):
Both are workflow-only hardening, no behavior change for normal-sized issues. Left the shared-module refactor (checkout + import) as a possible follow-up rather than folding it in here. |
|
Thanks for the thorough review @kingpanther13 — both blockers addressed in 468b85c. 1. changelog is now a trim target. You're right that it was the hole in the guarantee — 2. Harness wired into CI. Added On the non-blocking notes: the body-floor Local: harness 8/8, |
|
Re-reviewed at 468b85c — both blockers are resolved, and I verified them rather than eyeballing:
One thing left before this can go green: Ruff Lint is failing. Optional, your call: the drift guard checks the constants but not the trim drop-order, so a reorder in one file but not the other would slip through. Not blocking. |
|
I finally got around to overhauling my PR-review setup, and going back over this PR with it turned up two more gaps worth flagging before the budgeting fix lands — both about the prompt's full input surface and fallback, not just the three sections the trim loop touches.
The 413 backstop can trade a 413 for a malformed-response failure. On a 413 the retry sends |
|
Fixed in 6adfc7c — the ruff blocker plus both gaps Patch76 flagged. @kingpanther13 — Ruff Lint: ran @Patch76 — both gaps:
Local: harness 10/10, |
|
Re-reviewed at 6adfc7c. The code itself is in good shape and I verified it rather than eyeballing: harness 10/10, The blocker now is outside the PR's own logic: master picked up
Since Happy to re-review once it's rebased and CI is green. (One tiny nit for whenever you next touch it: the author-trim |
|
Thanks for digging into the conflict @kingpanther13 — you're right that 6f47c92 landed the same target while this was iterating, and I'd rather not rebase into a redundant PR. @julienld — your fix already gets the immediate 413 by tightening the static caps (tool list out, body 16000→5000, candidates 3×600). Before I rebase this on top, worth deciding whether the dynamic approach here still earns its place. What it adds beyond the static caps:
If you'd like the dynamic budgeting on top, I'll rebase: drop all the tool-list logic (gone in your commit), and — since the budgeter trims dynamically — the 5000-char body cap can likely go back up. If you'd rather keep it simple and static, I'm happy to close this as superseded; no attachment. Your call as author of the competing fix. (And thanks for the nit re: the author-trim log only showing the original length — I'll fix it to |
|
@SealKan / @kingpanther13 : Sorry, I saw that the triage bot was still offline so I pushed some quick fixes. I will take a look this weekend. Thanks. |
|
@SealKan — please go ahead and rebase, we want the dynamic approach. A couple of context updates since your last message:
For the rebase:
Thanks for the thorough iteration on this — the |
…eassistant-ai#1514) The static caps in 6f47c92 unblocked the immediate 413s but leave the release context and author follow-up comments unbounded, so a token-dense issue can still exceed the 8000-token input cap. Layer dynamic budgeting on top of those caps: assemble() takes per-section overrides, and a trim loop drops the BM25 duplicate candidates, then truncates the release context, author comments, and body — each to a floor — until the estimated prompt fits TOKEN_BUDGET. Raise the now-safe caps back up (body 10K, BM25 4x1200). Add a minimalPrompt backstop wired into the Evaluate step's new 413 branch: on the (defensive) chance the estimate drifts and the model still 413s, retry once with framing + rubric + schema + a floored body rather than failing the step. This preserves the JSON output contract, which a head truncation would break by cutting the trailing schema. scripts/verify_triage_prompt_budget.mjs mirrors the trim algorithm (the workflow step runs without a checkout and cannot import it); tests/src/unit/test_triage_prompt_budget.py runs the harness in CI and fails on constant or trim-order drift between the two files.
6adfc7c to
fcbee18
Compare
|
Rebased onto master (past 6f47c92) and force-pushed — the PR is now a single focused commit layering dynamic budgeting on top of your static caps. What changed per your guidance:
Verification (local):
The drift guard now asserts the canonical order Thanks for the write access to ha-mcp-workflows-dev — happy to run an end-to-end |
kingpanther13
left a comment
There was a problem hiding this comment.
Approving. The rebase is clean (tool-list tier dropped, caps raised to body 10k / candidates 4×1200, changelog + authorSection bounded, minimalPrompt 413 backstop), CI is green, and I validated it end-to-end in the workflows-dev environment via workflow_dispatch:
- Normal and large (10k-char body) issues assemble to ~3.1k / ~5.5k tokens — no trimming, no 413, valid triage.
- A token-dense case (large author comment) drove the prompt over budget and the trim chain fired in order: BM25 candidates dropped → release context 4400→1500 → author comments 63841→11629 → landed at exactly ~7000 tokens, under the 8000 cap, no 413, valid structured result. The issue body was never touched, as intended.
One trivial leftover I'll clean up in a fast follow-up (not worth gating this on): the // gpt-4o-mini: 16K input token free-tier limit ... comment in the Evaluate step is the stale assumption #1514 names as root cause, and it now contradicts this PR's own 8000-cap budgeting. I'll also fold in two small test-hardening assertions (pin the harness's static-framing assumption; an author-floor boundary test). All non-blocking.
Thanks for the thorough iteration — the assemble() override + minimalPrompt backstop and the trim-order drift guard are great additions.
#1560) * ci: fix stale token-cap comment and harden triage budget tests (#1514) Follow-up to #1522. - issue-triage.yml: the Evaluate step still carried the pre-fix "gpt-4o-mini: 16K input token free-tier limit" comment -- the exact wrong assumption #1514 names as root cause, now contradicting the 8000-token cap budgeting added in #1522. Correct it. - verify_triage_prompt_budget.mjs: add an author-floor boundary check (mirrors the body-floor check 2b) so AUTHOR_FLOOR is pinned behaviourally, and clarify the header that 7000 is the self-imposed target under the 8000-token model cap. - test_triage_prompt_budget.py: assert the real assemble() framing stays within the harness's worst-case staticText stand-in, so silent framing growth is caught pre-merge instead of only at runtime via core.warning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: count any-quote string literals in triage framing guard Addresses Gemini review on #1560: the single-quote-only _LITERAL regex would silently under-count framing if a static string ever switched to double quotes or a backtick. Use a backreference pattern + finditer so each literal is counted once regardless of quote style (internal quotes of a different style are body, not a new literal). No change to the measured value today (4613 chars). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: make framing guard reorder-proof and pin the changelog floor From a pr-review-toolkit self-review of this PR: - test_triage_prompt_budget.py: the framing guard bound the harness staticText stand-in via first-match re.search. With the inflated x(40000)/x(30000) stand-ins now present (checks 1c/2b), a future reorder could silently relax it to 4613 <= 40000. Bind to min() of all stand-ins so it can only over-constrain, never silently pass. Also tighten the _assemble_framing_chars docstring (keywords is bounded upstream, not trimmed by the budgeter). - verify_triage_prompt_budget.mjs: add a changelog-floor exact-clamp check (3b) so CHANGELOG_FLOOR is pinned like BODY_FLOOR (2b) and AUTHOR_FLOOR (1c); previously it was only hit incidentally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…➔ 7.7.0) (#994)
This PR contains the following updates:
| Package | Update | Change |
|---|---|---|
| [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.5.0` → `7.7.0` |
---
### Release Notes
<details>
<summary>homeassistant-ai/ha-mcp (ghcr.io/homeassistant-ai/ha-mcp)</summary>
### [`v7.7.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v770-2026-06-10)
[Compare Source](https://github.com/homeassistant-ai/ha-mcp/compare/v7.6.0...v7.7.0)
##### Added
- User-configurable custom filesystem directories for the file tools (closes [#​1567](https://github.com/homeassistant-ai/ha-mcp/issues/1567))
([#​1568](https://github.com/homeassistant-ai/ha-mcp/pull/1568))
- Expose all user-tunable env vars in the settings UI (add-on parity)
([#​1554](https://github.com/homeassistant-ai/ha-mcp/pull/1554))
- Warn when default MCP\_SECRET\_PATH is bound non-loopback
([#​1472](https://github.com/homeassistant-ai/ha-mcp/pull/1472))
- **search**: Consolidate ha\_search\_entities + ha\_deep\_search into ha\_search
([#​1529](https://github.com/homeassistant-ai/ha-mcp/pull/1529))
- **addon**: Install the MCP Server add-on from the ha\_mcp\_tools integration
([#​1528](https://github.com/homeassistant-ai/ha-mcp/pull/1528))
- Add opt-in dashboard screenshot mode
([#​1510](https://github.com/homeassistant-ai/ha-mcp/pull/1510))
- Add Linux support for install & docs
([#​1096](https://github.com/homeassistant-ai/ha-mcp/pull/1096))
- Surface the web settings page for non-add-on installs ([#​1458](https://github.com/homeassistant-ai/ha-mcp/issues/1458))
([#​1511](https://github.com/homeassistant-ai/ha-mcp/pull/1511))
- Convert Pydantic arg-validation errors to actionable ToolErrors
([#​1491](https://github.com/homeassistant-ai/ha-mcp/pull/1491))
- Per-key toggles for automation/script/scene in packages/\*.yaml
([#​1476](https://github.com/homeassistant-ai/ha-mcp/pull/1476))
- Direct skills retrieval for write tools + improved best practice checker warnings with embedded skills responses ([#​1182](https://github.com/homeassistant-ai/ha-mcp/issues/1182))
([#​1448](https://github.com/homeassistant-ai/ha-mcp/pull/1448))
- Detect last\_changed/last\_updated duration math and suggest for: field ([#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157))
([#​1264](https://github.com/homeassistant-ai/ha-mcp/pull/1264))
- Advanced settings panel + nested beta master toggle ([#​1164](https://github.com/homeassistant-ai/ha-mcp/issues/1164))
([#​1431](https://github.com/homeassistant-ai/ha-mcp/pull/1431))
- Allow automation/script/scene yaml\_path in packages/\*.yaml only
([#​1452](https://github.com/homeassistant-ai/ha-mcp/pull/1452))
- Restrict ha\_mcp\_tools services to ha-mcp callers (caller token + ha\_call\_service refusal)
([#​1459](https://github.com/homeassistant-ai/ha-mcp/pull/1459))
##### Changed
- **security**: Soften vulnerability-response SLA to best-effort
([`a24e7da`](https://github.com/homeassistant-ai/ha-mcp/commit/a24e7da4787aad570ac2998a5732de06229fa160))
- Update contributors list \[contributors-updated]
([`7cc187f`](https://github.com/homeassistant-ai/ha-mcp/commit/7cc187f4de2f6eb58cafaa4fb21f8016cb180a61))
- Telemetry wording — follow HA analytics setting, not opt-in-only
([#​1481](https://github.com/homeassistant-ai/ha-mcp/pull/1481))
- **security**: Note that security-advisory disposition is API-blind (UI-only)
([#​1561](https://github.com/homeassistant-ai/ha-mcp/pull/1561))
- **tools**: Sharpen ha\_eval\_template usage routing for compute-from-state queries
([#​1550](https://github.com/homeassistant-ai/ha-mcp/pull/1550))
- Differentiate ha-mcp from Home Assistant's built-in MCP Server
([#​1542](https://github.com/homeassistant-ai/ha-mcp/pull/1542))
- Update advanced mode notes
([#​1533](https://github.com/homeassistant-ai/ha-mcp/pull/1533))
- **[#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157)**: Scripts native-for: guidance + fix numeric\_state-condition for: overclaim
([#​1480](https://github.com/homeassistant-ai/ha-mcp/pull/1480))
- Clarify add-on vs uvx; add Codex + HTTP-native client setup
([#​1478](https://github.com/homeassistant-ai/ha-mcp/pull/1478))
- **security**: Explicit threat model for trusted clients, LAN, sandbox, and OAuth tokens
([#​1463](https://github.com/homeassistant-ai/ha-mcp/pull/1463))
- Clarify telemetry is a planned future feature, not implemented
([#​1469](https://github.com/homeassistant-ai/ha-mcp/pull/1469))
##### Fixed
- **tools**: Bring HA API field names to 2026.6 — stale docstrings, automation plural canonicalization, fan speed (closes [#​1540](https://github.com/homeassistant-ai/ha-mcp/issues/1540))
([#​1566](https://github.com/homeassistant-ai/ha-mcp/pull/1566))
- **energy**: Accept "water" energy source in ha\_manage\_energy\_prefs
([#​1553](https://github.com/homeassistant-ai/ha-mcp/pull/1553))
- **tools**: Use action: not service: in automation docstring examples
([#​1539](https://github.com/homeassistant-ai/ha-mcp/pull/1539))
- **security**: Narrow GHSA-mc92-ww4q-6fg4 to the masker and log redaction
([#​1512](https://github.com/homeassistant-ai/ha-mcp/pull/1512))
- **addon**: Restrict settings UI root routes to HA ingress
([#​1508](https://github.com/homeassistant-ai/ha-mcp/pull/1508))
- Add name attributes to generated settings-UI form controls (a11y)
([#​1497](https://github.com/homeassistant-ai/ha-mcp/pull/1497))
- Add-on-aware code-mode locked note + suppress settings-UI favicon 404
([#​1494](https://github.com/homeassistant-ai/ha-mcp/pull/1494))
- Surface the real reason a WebSocket connection failed
([#​1495](https://github.com/homeassistant-ai/ha-mcp/pull/1495))
- Remove str from ha\_bulk\_control.operations schema + fix wrong-reason test
([#​1492](https://github.com/homeassistant-ai/ha-mcp/pull/1492))
- Remove str from bool/int param schemas across all tools
([#​1490](https://github.com/homeassistant-ai/ha-mcp/pull/1490))
- **addon**: Expose non-beta tool options on the stable add-on
([#​1488](https://github.com/homeassistant-ai/ha-mcp/pull/1488))
- **addon**: Enable ingress so the stable add-on shows the Open Web UI / Settings UI
([#​1486](https://github.com/homeassistant-ai/ha-mcp/pull/1486))
- Refine last\_changed/last\_updated duration-math detector ([#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157))
([#​1483](https://github.com/homeassistant-ai/ha-mcp/pull/1483))
- Remove str from config param schema on service and entity tools
([#​1487](https://github.com/homeassistant-ai/ha-mcp/pull/1487))
- Surface flow-helper config to agents reading UI-created templates
([#​1474](https://github.com/homeassistant-ai/ha-mcp/pull/1474))
- Remove str from config param schema on set tools
([#​1485](https://github.com/homeassistant-ai/ha-mcp/pull/1485))
- Route malformed ha\_mcp\_tools version to a distinct reinstall error
([#​1484](https://github.com/homeassistant-ai/ha-mcp/pull/1484))
- Persist DCR client registrations and HMAC secret across restarts ([#​1261](https://github.com/homeassistant-ai/ha-mcp/issues/1261))
([#​1265](https://github.com/homeassistant-ai/ha-mcp/pull/1265))
- Stop dev builds from publishing the :latest Docker tag
([#​1477](https://github.com/homeassistant-ai/ha-mcp/pull/1477))
- Subscribe to HACS dispatch signal instead of 10x1s blind poll
([#​1455](https://github.com/homeassistant-ai/ha-mcp/pull/1455))
- Reject python\_transform while loops
([#​1462](https://github.com/homeassistant-ai/ha-mcp/pull/1462))
##### Performance Improvements
- Fast-fail HACS not-found lookups + batch-verify deep-search E2E fixtures ([#​1515](https://github.com/homeassistant-ai/ha-mcp/issues/1515))
([#​1552](https://github.com/homeassistant-ai/ha-mcp/pull/1552))
##### Refactoring
- Add display title to ha\_get\_skill\_guide tool
([#​1543](https://github.com/homeassistant-ai/ha-mcp/pull/1543))
- Fold ha\_check\_config into ha\_get\_system\_health include="config\_check"
([#​1516](https://github.com/homeassistant-ai/ha-mcp/pull/1516))
- **c901**: Smart\_search.py below C901 threshold
([#​1507](https://github.com/homeassistant-ai/ha-mcp/pull/1507))
- **hacs**: Consolidate HACS tools into ha\_get\_hacs + ha\_manage\_hacs ([#​1045](https://github.com/homeassistant-ai/ha-mcp/issues/1045))
([#​1502](https://github.com/homeassistant-ai/ha-mcp/pull/1502))
- **c901**: Tools\_config\_helpers.py below C901 threshold
([#​1498](https://github.com/homeassistant-ai/ha-mcp/pull/1498))
- **complexity**: Reduce C901 in tools\_addons.py via class-based pattern
([#​1432](https://github.com/homeassistant-ai/ha-mcp/pull/1432))
***
<details>
<summary>Internal Changes</summary>
##### Changed
- Trim AGENTS.md below 40k + improve subdirectory CLAUDE.md files
([#​1499](https://github.com/homeassistant-ai/ha-mcp/pull/1499))
##### Chores
- **addon**: Publish dev addon version 7.6.0.dev415 \[skip ci]
([`2c0148b`](https://github.com/homeassistant-ai/ha-mcp/commit/2c0148ba512a02b5299edbb4086c38410777a295))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.6.1
([#​1571](https://github.com/homeassistant-ai/ha-mcp/pull/1571))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.19
([#​1570](https://github.com/homeassistant-ai/ha-mcp/pull/1570))
- **addon**: Publish dev addon version 7.6.0.dev414 \[skip ci]
([`0bf9e39`](https://github.com/homeassistant-ai/ha-mcp/commit/0bf9e39947e8bf87d18bae23877d6b0d955dd35f))
- Sync tool docs after merge \[skip ci]
([`8f5e037`](https://github.com/homeassistant-ai/ha-mcp/commit/8f5e037b89296fd483888d158d8f72f4b1b7dfa8))
- **addon**: Publish dev addon version 7.6.0.dev413 \[skip ci]
([`6729327`](https://github.com/homeassistant-ai/ha-mcp/commit/6729327de8c0747f5cc7bb639859f95bbe1f0cfc))
- Sync tool docs after merge \[skip ci]
([`4341e95`](https://github.com/homeassistant-ai/ha-mcp/commit/4341e9574b3270c67bc016676f854f585fec816f))
- **addon**: Publish dev addon version 7.6.0.dev412 \[skip ci]
([`148f506`](https://github.com/homeassistant-ai/ha-mcp/commit/148f506a98c8f89292616a3a05dd0c9156516439))
- **addon**: Publish dev addon version 7.6.0.dev411 \[skip ci]
([`287fe55`](https://github.com/homeassistant-ai/ha-mcp/commit/287fe5503917e551f2dcb363cd28250237ed880c))
- Sync tool docs after merge \[skip ci]
([`b642b8e`](https://github.com/homeassistant-ai/ha-mcp/commit/b642b8eba67d8015d8fe5a1c1f88c9dd72ffc45f))
- **addon**: Publish dev addon version 7.6.0.dev410 \[skip ci]
([`29e34dd`](https://github.com/homeassistant-ai/ha-mcp/commit/29e34dd6eb517399de3c0a6a886e45ecf4749923))
- **addon**: Publish dev addon version 7.6.0.dev409 \[skip ci]
([`dec16a1`](https://github.com/homeassistant-ai/ha-mcp/commit/dec16a12d2ac3341908b130e9ea79f950d02466b))
- Sync tool docs after merge \[skip ci]
([`dd72535`](https://github.com/homeassistant-ai/ha-mcp/commit/dd725357f5d48a00959aaa7eceb4bad67a7ba202))
- **addon**: Publish dev addon version 7.6.0.dev408 \[skip ci]
([`c3c89f1`](https://github.com/homeassistant-ai/ha-mcp/commit/c3c89f1a758b6086b59ff21f9044597da103fa25))
- **addon**: Publish dev addon version 7.6.0.dev407 \[skip ci]
([`94195ee`](https://github.com/homeassistant-ai/ha-mcp/commit/94195ee4c8dbd0d8eec13d7c3d7ee392e5b7240f))
- **addon**: Publish dev addon version 7.6.0.dev406 \[skip ci]
([`f439424`](https://github.com/homeassistant-ai/ha-mcp/commit/f4394240dd1170f9d978e3c4a5011bab12f17f54))
- Sync tool docs after merge \[skip ci]
([`7464277`](https://github.com/homeassistant-ai/ha-mcp/commit/746427745d3debccea57c844278d1ba834d7ebfb))
- **addon**: Publish dev addon version 7.6.0.dev405 \[skip ci]
([`146eb07`](https://github.com/homeassistant-ai/ha-mcp/commit/146eb073a6f260ed0b0653cdb71346e9d29deae7))
- **addon**: Publish dev addon version 7.6.0.dev404 \[skip ci]
([`6a707bb`](https://github.com/homeassistant-ai/ha-mcp/commit/6a707bba576b987f8c3395adca3d59f7dd8a1050))
- Sync tool docs after merge \[skip ci]
([`85f3935`](https://github.com/homeassistant-ai/ha-mcp/commit/85f3935f80d9677f791b3098b201ec9c27e643be))
- **addon**: Publish dev addon version 7.6.0.dev403 \[skip ci]
([`be1fa1d`](https://github.com/homeassistant-ai/ha-mcp/commit/be1fa1dd2693170cbe3c037e7a88cf02f1847dcf))
- Sync tool docs after merge \[skip ci]
([`d9adbd2`](https://github.com/homeassistant-ai/ha-mcp/commit/d9adbd2c27750c9bc8faa55470d24564c48b3dbf))
- **addon**: Publish dev addon version 7.6.0.dev402 \[skip ci]
([`41ad7ca`](https://github.com/homeassistant-ai/ha-mcp/commit/41ad7caf1e0d982dd9e7bda3420ba3ca577cf765))
- **addon**: Publish dev addon version 7.6.0.dev401 \[skip ci]
([`8205034`](https://github.com/homeassistant-ai/ha-mcp/commit/820503485386f13dc66a0da3d304739e1f03dafd))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.18
([#​1523](https://github.com/homeassistant-ai/ha-mcp/pull/1523))
- **addon**: Publish dev addon version 7.6.0.dev400 \[skip ci]
([`532cdc4`](https://github.com/homeassistant-ai/ha-mcp/commit/532cdc440a8db053c524579f3e6b48b099c13c66))
- Sync tool docs after merge \[skip ci]
([`e2c08ff`](https://github.com/homeassistant-ai/ha-mcp/commit/e2c08ff797ffabf7b39bfc4b22b498b1c02ce1fa))
- **addon**: Publish dev addon version 7.6.0.dev399 \[skip ci]
([`9501348`](https://github.com/homeassistant-ai/ha-mcp/commit/95013488ea99761535ea9532285839bcd0ec8e3b))
- Sync tool docs after merge \[skip ci]
([`e70a050`](https://github.com/homeassistant-ai/ha-mcp/commit/e70a050efcb6edeb65d51dabd5307a192a22e66c))
- **addon**: Publish dev addon version 7.6.0.dev398 \[skip ci]
([`0b61424`](https://github.com/homeassistant-ai/ha-mcp/commit/0b61424ed823453dec27bb173d049f901eddc2d3))
- Sync tool docs after merge \[skip ci]
([`6df7987`](https://github.com/homeassistant-ai/ha-mcp/commit/6df79877669686a9fee3ec04979dff3960bc5e3f))
- **addon**: Publish dev addon version 7.6.0.dev397 \[skip ci]
([`c34915f`](https://github.com/homeassistant-ai/ha-mcp/commit/c34915f40cd82f83f0eb4af5c3a5655843608770))
- Sync tool docs after merge \[skip ci]
([`6f88e7e`](https://github.com/homeassistant-ai/ha-mcp/commit/6f88e7e0c8dcb7fee27792e0f87f6acd8aa892c4))
- **addon**: Publish dev addon version 7.6.0.dev396 \[skip ci]
([`1490e19`](https://github.com/homeassistant-ai/ha-mcp/commit/1490e190382454b17fc14cd362b17612a6af253f))
- Sync tool docs after merge \[skip ci]
([`ac2c7d0`](https://github.com/homeassistant-ai/ha-mcp/commit/ac2c7d038a90fb44466afa8f047378d7e8daed94))
- **addon**: Publish dev addon version 7.6.0.dev395 \[skip ci]
([`11e5ee8`](https://github.com/homeassistant-ai/ha-mcp/commit/11e5ee8f07f63f63b8cdf017397263c7602e80f6))
- **addon**: Publish dev addon version 7.6.0.dev394 \[skip ci]
([`5fc3e0f`](https://github.com/homeassistant-ai/ha-mcp/commit/5fc3e0f572bfd1bb367e65b3f4d78b96cb78fa91))
- Flag untrusted third-party content in HACS and add-on tool responses
([#​1509](https://github.com/homeassistant-ai/ha-mcp/pull/1509))
- **addon**: Publish dev addon version 7.6.0.dev393 \[skip ci]
([`9a37c28`](https://github.com/homeassistant-ai/ha-mcp/commit/9a37c28cfa0d1f3f652fe441ce2fe1d72a7360ab))
- **addon**: Publish dev addon version 7.6.0.dev392 \[skip ci]
([`4f737ac`](https://github.com/homeassistant-ai/ha-mcp/commit/4f737ac7c116e9afa046ab45b1230e2cdb5ae959))
- **addon**: Publish dev addon version 7.6.0.dev391 \[skip ci]
([`fd5d3f2`](https://github.com/homeassistant-ai/ha-mcp/commit/fd5d3f2d4ce87baa4cfcc85a173bb0cc9d132a35))
- **addon**: Publish dev addon version 7.6.0.dev390 \[skip ci]
([`28dedf4`](https://github.com/homeassistant-ai/ha-mcp/commit/28dedf43f3cd094b1c40fb50e535166cc8c33388))
- **addon**: Publish dev addon version 7.6.0.dev389 \[skip ci]
([`9443446`](https://github.com/homeassistant-ai/ha-mcp/commit/9443446fdd607a75d8db5fdad009130b188267d6))
- Sync tool docs after merge \[skip ci]
([`94fcbeb`](https://github.com/homeassistant-ai/ha-mcp/commit/94fcbeb14bd9cfa3bef274182f95e4562a379971))
- **addon**: Publish dev addon version 7.6.0.dev388 \[skip ci]
([`ccc1816`](https://github.com/homeassistant-ai/ha-mcp/commit/ccc18162eec520950c58cc8eabb2aac04ac57ab3))
- Drop dead entity\_cache attr + ruff-format fuzzy\_search.py
([#​1503](https://github.com/homeassistant-ai/ha-mcp/pull/1503))
- **addon**: Publish dev addon version 7.6.0.dev387 \[skip ci]
([`057c108`](https://github.com/homeassistant-ai/ha-mcp/commit/057c108b2958959bfee34225899b47b5c989a119))
- **addon**: Publish dev addon version 7.6.0.dev386 \[skip ci]
([`66f4ac6`](https://github.com/homeassistant-ai/ha-mcp/commit/66f4ac6a37d85412b895962afef1b03707400e56))
- **addon**: Publish dev addon version 7.6.0.dev385 \[skip ci]
([`f331f11`](https://github.com/homeassistant-ai/ha-mcp/commit/f331f1150f525a18bf5bd2e27007b46a07a3492c))
- **addon**: Publish dev addon version 7.6.0.dev384 \[skip ci]
([`17c319e`](https://github.com/homeassistant-ai/ha-mcp/commit/17c319e68ba4b4d4e6acd84deb57c588aafcb48b))
- Sync tool docs after merge \[skip ci]
([`f36cbb7`](https://github.com/homeassistant-ai/ha-mcp/commit/f36cbb7e620839b16808b37b61dbc7602557b409))
- **addon**: Publish dev addon version 7.6.0.dev383 \[skip ci]
([`782ba3b`](https://github.com/homeassistant-ai/ha-mcp/commit/782ba3b2bbcfe50564c5524d6a2c018a4c9c9ba6))
- **addon**: Publish dev addon version 7.6.0.dev382 \[skip ci]
([`b647ab6`](https://github.com/homeassistant-ai/ha-mcp/commit/b647ab6eea76a030c7e3c46f72d732ff339398fe))
- **addon**: Publish dev addon version 7.6.0.dev381 \[skip ci]
([`e999c24`](https://github.com/homeassistant-ai/ha-mcp/commit/e999c242553a60561ca06dbefe3177c627bb9e2d))
- Sync tool docs after merge \[skip ci]
([`50d76b0`](https://github.com/homeassistant-ai/ha-mcp/commit/50d76b04a0691c565fafaabc76fd4bd3cf321953))
- **addon**: Publish dev addon version 7.6.0.dev380 \[skip ci]
([`ebdc69b`](https://github.com/homeassistant-ai/ha-mcp/commit/ebdc69bde929fd3342234149956af0710b9f260a))
- Sync tool docs after merge \[skip ci]
([`1f03967`](https://github.com/homeassistant-ai/ha-mcp/commit/1f03967160156cbffdfc9fc7deb5ed9a2b25f2ba))
- **addon**: Publish dev addon version 7.6.0.dev379 \[skip ci]
([`7cabb2e`](https://github.com/homeassistant-ai/ha-mcp/commit/7cabb2ec342561dbc74251f7697e3c4df0a8fcb3))
- **addon**: Publish dev addon version 7.6.0.dev378 \[skip ci]
([`7b631c7`](https://github.com/homeassistant-ai/ha-mcp/commit/7b631c75e0e4163ee13906b90ddad7a1b744e402))
- **addon**: Publish dev addon version 7.6.0.dev377 \[skip ci]
([`ea7b614`](https://github.com/homeassistant-ai/ha-mcp/commit/ea7b614615606a8fc05a0a18cb9cafa2f0a42c0d))
- **addon**: Publish dev addon version 7.6.0.dev376 \[skip ci]
([`fd33ecd`](https://github.com/homeassistant-ai/ha-mcp/commit/fd33ecd4d260f5fc2ab4f229c90b1a4514c5ccde))
- Sync tool docs after merge \[skip ci]
([`ba8fae3`](https://github.com/homeassistant-ai/ha-mcp/commit/ba8fae3cc4f451dc65022756a86cce5275f6e35f))
- **addon**: Publish dev addon version 7.6.0.dev375 \[skip ci]
([`afcd0d8`](https://github.com/homeassistant-ai/ha-mcp/commit/afcd0d8e061e1cba65fd119727fc64ed77f1818d))
- Sync tool docs after merge \[skip ci]
([`f9b55ad`](https://github.com/homeassistant-ai/ha-mcp/commit/f9b55ad59c6f03d6a98c3d3f6dd52ba9ff7c8a7a))
- **addon**: Publish dev addon version 7.6.0.dev374 \[skip ci]
([`eecdf8b`](https://github.com/homeassistant-ai/ha-mcp/commit/eecdf8b058ba932ba94cfb292ebf2331a54d2def))
- Sync tool docs after merge \[skip ci]
([`ef16a8a`](https://github.com/homeassistant-ai/ha-mcp/commit/ef16a8a197c76e51a49ae6ac69eecb15d202a194))
- **addon**: Publish dev addon version 7.6.0.dev373 \[skip ci]
([`9a93703`](https://github.com/homeassistant-ai/ha-mcp/commit/9a9370362fe5573ac71cd6e90353877faccce8a6))
- **addon**: Publish dev addon version 7.6.0.dev372 \[skip ci]
([`7352ce8`](https://github.com/homeassistant-ai/ha-mcp/commit/7352ce88ef59feef74c29ab47f6991cc2ac132a8))
- **addon**: Publish dev addon version 7.6.0.dev371 \[skip ci]
([`d7601f5`](https://github.com/homeassistant-ai/ha-mcp/commit/d7601f5796308e1c42a01dbce9861460027a93c4))
- Sync tool docs after merge \[skip ci]
([`d0a4482`](https://github.com/homeassistant-ai/ha-mcp/commit/d0a448276306a08f8a52c4645f1b9c5aeaafd68e))
- **addon**: Publish dev addon version 7.6.0.dev370 \[skip ci]
([`f83c32c`](https://github.com/homeassistant-ai/ha-mcp/commit/f83c32c747ddaeccffb040bc28d3e08d7507ded4))
- **addon**: Publish dev addon version 7.6.0.dev369 \[skip ci]
([`ea16661`](https://github.com/homeassistant-ai/ha-mcp/commit/ea16661f1d144feada93aee119b625f968f990cb))
- **addon**: Publish dev addon version 7.6.0.dev368 \[skip ci]
([`af49ea5`](https://github.com/homeassistant-ai/ha-mcp/commit/af49ea5aff5c9f54914943cc2f8a67ebeea2fdee))
- **addon**: Publish dev addon version 7.6.0.dev367 \[skip ci]
([`7dd5f4c`](https://github.com/homeassistant-ai/ha-mcp/commit/7dd5f4cd0237ef4d80a454efe4dfc0801f18fdbd))
- **addon**: Publish dev addon version 7.6.0.dev366 \[skip ci]
([`6273b7e`](https://github.com/homeassistant-ai/ha-mcp/commit/6273b7ec8695706948eefe8e617cac39363940ce))
- Sync tool docs after merge \[skip ci]
([`4e3fd5f`](https://github.com/homeassistant-ai/ha-mcp/commit/4e3fd5f331ce5fefa8e0e5560da411de17f2a8db))
- **addon**: Publish dev addon version 7.6.0.dev365 \[skip ci]
([`f3bf17b`](https://github.com/homeassistant-ai/ha-mcp/commit/f3bf17be132ebc67005c33a3c8fde85025d56809))
- Sync tool docs after merge \[skip ci]
([`5307b60`](https://github.com/homeassistant-ai/ha-mcp/commit/5307b608879154fccf67bc1894f61e97f26719c6))
- **addon**: Publish dev addon version 7.6.0.dev364 \[skip ci]
([`76ec1ae`](https://github.com/homeassistant-ai/ha-mcp/commit/76ec1aefab8e904abf620bf1c1130e5f5d0c4bd9))
- Sync tool docs after merge \[skip ci]
([`be864b5`](https://github.com/homeassistant-ai/ha-mcp/commit/be864b5d685f167334487d4fe83324afbb4999ca))
- **addon**: Publish dev addon version 7.6.0.dev363 \[skip ci]
([`da10c75`](https://github.com/homeassistant-ai/ha-mcp/commit/da10c75a248dcc19442e4db6f34f325683cb0a71))
- **addon**: Publish dev addon version 7.6.0.dev362 \[skip ci]
([`69f4527`](https://github.com/homeassistant-ai/ha-mcp/commit/69f45279707d18c724bd702ced46111b26cd000c))
- **addon**: Publish version 7.6.0 \[skip ci]
([`086d75d`](https://github.com/homeassistant-ai/ha-mcp/commit/086d75d72dd7d1c735413d96ef2fd38ae57b90ca))
##### Continuous Integration
- Vendor Puppet add-on as a pinned submodule + retry transient add-on builds
([#​1565](https://github.com/homeassistant-ai/ha-mcp/pull/1565))
- Make sync-tool-docs push resilient to concurrent master advances
([#​1564](https://github.com/homeassistant-ai/ha-mcp/pull/1564))
- Fix stale token-cap comment and harden triage budget tests ([#​1514](https://github.com/homeassistant-ai/ha-mcp/issues/1514))
([#​1560](https://github.com/homeassistant-ai/ha-mcp/pull/1560))
- **deps**: Bump the github-actions group with 2 updates
([#​1556](https://github.com/homeassistant-ai/ha-mcp/pull/1556))
- Budget triage prompt dynamically under the GitHub Models cap ([#​1514](https://github.com/homeassistant-ai/ha-mcp/issues/1514))
([#​1522](https://github.com/homeassistant-ai/ha-mcp/pull/1522))
- Reduce Docker Hub pulls in performance-tests workflow
([#​1549](https://github.com/homeassistant-ai/ha-mcp/pull/1549))
- Add JavaScript to the CodeQL code-quality gate
([#​1548](https://github.com/homeassistant-ai/ha-mcp/pull/1548))
- Add CodeQL code-quality CI gate and clear all code-quality findings
([#​1526](https://github.com/homeassistant-ai/ha-mcp/pull/1526))
- Drop tool list from evaluate prompt + tighten caps to fit 8K token limit
([`6f47c92`](https://github.com/homeassistant-ai/ha-mcp/commit/6f47c92507ef0d854153632107c0c702812f0c3c))
- Remove broken maintainer check (GITHUB\_TOKEN lacks read:org)
([`010ec58`](https://github.com/homeassistant-ai/ha-mcp/commit/010ec58d1f3b6d46b20aa83c3caee373dd826694))
- Switch evaluate step to gpt-4o-mini (16K token free tier vs 8K on gpt-4.1)
([#​1496](https://github.com/homeassistant-ai/ha-mcp/pull/1496))
- Issue bot v2 — GitHub Models triage, needs-info auto-close, duplicate detection
([#​1442](https://github.com/homeassistant-ai/ha-mcp/pull/1442))
##### Refactoring
- Extract settings-UI JavaScript and CSS to separate files
([#​1505](https://github.com/homeassistant-ai/ha-mcp/pull/1505))
- Collapse settings-UI route registration into one table
([#​1504](https://github.com/homeassistant-ai/ha-mcp/pull/1504))
##### Testing
- **oauth**: Add HTTP smoke tests for OAuth metadata-discovery endpoints
([#​1562](https://github.com/homeassistant-ai/ha-mcp/pull/1562))
- **uat**: Relabel c01 as a mode-discrimination probe (taxonomy consistency)
([#​1563](https://github.com/homeassistant-ai/ha-mcp/pull/1563))
- **uat**: Rework c01 routing probe to ha\_search registry-listing mode after [#​1529](https://github.com/homeassistant-ai/ha-mcp/issues/1529)
([#​1559](https://github.com/homeassistant-ai/ha-mcp/pull/1559))
- **uat**: Add response\_contains\_any check and always log agent responses
([#​1537](https://github.com/homeassistant-ai/ha-mcp/pull/1537))
- **uat**: Treat request timeout as per-story failure, not suite abort
([#​1536](https://github.com/homeassistant-ai/ha-mcp/pull/1536))
- **uat**: Harden BAT story runner against agent crashes
([#​1535](https://github.com/homeassistant-ai/ha-mcp/pull/1535))
- **uat**: Log model and quantization in BAT story results
([#​1525](https://github.com/homeassistant-ai/ha-mcp/pull/1525))
- Capture reasoning tokens and detect inert --no-think in BAT openai agent
([#​1524](https://github.com/homeassistant-ai/ha-mcp/pull/1524))
</details>
### [`v7.6.0`](https://github.com/homeassistant-ai/ha-mcp/blob/HEAD/CHANGELOG.md#v760-2026-05-27)
[Compare Source](https://github.com/homeassistant-ai/ha-mcp/compare/v7.5.0...v7.6.0)
##### Added
- Make HTTP bind host configurable via MCP\_HOST (closes [#​1434](https://github.com/homeassistant-ai/ha-mcp/issues/1434))
([#​1436](https://github.com/homeassistant-ai/ha-mcp/pull/1436))
- Tool Security Policies — per-tool approval gating ([#​966](https://github.com/homeassistant-ai/ha-mcp/issues/966))
([#​1421](https://github.com/homeassistant-ai/ha-mcp/pull/1421))
- Rename ha\_delete\_helpers\_integrations → ha\_remove\_helpers\_integrations + raise on missing target
([#​1424](https://github.com/homeassistant-ai/ha-mcp/pull/1424))
- Auto-backup edited entities before write/destructive tool calls (closes [#​1288](https://github.com/homeassistant-ai/ha-mcp/issues/1288))
([#​1403](https://github.com/homeassistant-ai/ha-mcp/pull/1403))
- Persistent settings UI for stdio mode
([#​1381](https://github.com/homeassistant-ai/ha-mcp/pull/1381))
- Add fields= projection to ha\_search\_entities, ha\_get\_overview, ha\_get\_state, ha\_get\_history, ha\_config\_list\_areas, ha\_list\_services ([#​1199](https://github.com/homeassistant-ai/ha-mcp/issues/1199))
([#​1225](https://github.com/homeassistant-ai/ha-mcp/pull/1225))
- Route entity-registration wait through WS events (closes [#​1152](https://github.com/homeassistant-ai/ha-mcp/issues/1152))
([#​1382](https://github.com/homeassistant-ai/ha-mcp/pull/1382))
- Add config subentry support
([#​1393](https://github.com/homeassistant-ai/ha-mcp/pull/1393))
- Add Assist pipeline management tool
([#​1392](https://github.com/homeassistant-ai/ha-mcp/pull/1392))
- Add knx to ha\_config\_set\_yaml allowlist
([#​1374](https://github.com/homeassistant-ai/ha-mcp/pull/1374))
- Extend automation\_id parity to set/remove automation responses
([#​1343](https://github.com/homeassistant-ai/ha-mcp/pull/1343))
- **haos-e2e**: Add parallel inaddon test tier (ha-mcp runs inside HAOS addon)
([#​1361](https://github.com/homeassistant-ai/ha-mcp/pull/1361))
- Expose integration diagnostics via ha\_get\_integration and ha\_get\_system\_health (closes [#​1148](https://github.com/homeassistant-ai/ha-mcp/issues/1148))
([#​1328](https://github.com/homeassistant-ai/ha-mcp/pull/1328))
- Return canonical script\_id from ha\_config\_get\_script ([#​1334](https://github.com/homeassistant-ai/ha-mcp/issues/1334))
([#​1352](https://github.com/homeassistant-ai/ha-mcp/pull/1352))
- Add automation\_id parity key to ha\_config\_get\_automation
([#​1329](https://github.com/homeassistant-ai/ha-mcp/pull/1329))
- Reject empty/whitespace identifiers on registry-metadata writes (closes [#​1294](https://github.com/homeassistant-ai/ha-mcp/issues/1294))
([#​1312](https://github.com/homeassistant-ai/ha-mcp/pull/1312))
- Add HA brand assets for custom integration
([#​1317](https://github.com/homeassistant-ai/ha-mcp/pull/1317))
- Unify ha\_config\_set\_helper response shape (closes [#​1293](https://github.com/homeassistant-ai/ha-mcp/issues/1293))
([#​1303](https://github.com/homeassistant-ai/ha-mcp/pull/1303))
- Mirror create-side validation guards onto update path (closes [#​1292](https://github.com/homeassistant-ai/ha-mcp/issues/1292))
([#​1304](https://github.com/homeassistant-ai/ha-mcp/pull/1304))
- Add array\_patch mode to ha\_manage\_addon for atomic GET-modify-POST
([#​1063](https://github.com/homeassistant-ai/ha-mcp/pull/1063))
##### Changed
- **agents**: Drop ha\_backup\_create + ha\_backup\_restore from accepted exceptions
([#​1445](https://github.com/homeassistant-ai/ha-mcp/pull/1445))
- Update contributors list \[contributors-updated]
([`c7665a6`](https://github.com/homeassistant-ai/ha-mcp/commit/c7665a6f5a08737d8fcbebbbe6afdc88ec5c4901))
- **overview**: Enumerate dismissed\_repair\_count in fields= description + static drift test
([#​1411](https://github.com/homeassistant-ai/ha-mcp/pull/1411))
- Credit [@​tomwilkie](https://github.com/tomwilkie) and six other contributors in README
([#​1400](https://github.com/homeassistant-ai/ha-mcp/pull/1400))
- **[#​1157](https://github.com/homeassistant-ai/ha-mcp/issues/1157)**: Bump skills-vendor + auto-update via Renovate + native for: field + scrub eval\_template anti-patterns
([#​1383](https://github.com/homeassistant-ai/ha-mcp/pull/1383))
- Extend Boy Scout weasel-phrase list with common variants; clarify semantic match
([#​1373](https://github.com/homeassistant-ai/ha-mcp/pull/1373))
- Merge Boy Scout Rule + Handling Discovered Improvements; tighten deferral gate
([#​1359](https://github.com/homeassistant-ai/ha-mcp/pull/1359))
- Categorize Issue Labels table and document 6 reverse-drift labels
([#​1335](https://github.com/homeassistant-ai/ha-mcp/pull/1335))
- Strip stale L-refs from test\_identifier\_validation\_family docstrings
([#​1324](https://github.com/homeassistant-ai/ha-mcp/pull/1324))
- Align label refs with live label set and fix triaged-removal trigger
([#​1316](https://github.com/homeassistant-ai/ha-mcp/pull/1316))
- Surface tool-discovery / categorized search
([#​1123](https://github.com/homeassistant-ai/ha-mcp/pull/1123))
- Fix two stale ha\_get\_skill\_guide references missed in [#​1289](https://github.com/homeassistant-ai/ha-mcp/issues/1289)
([#​1305](https://github.com/homeassistant-ai/ha-mcp/pull/1305))
- Clarify setup wizard placeholders need braces removed ([#​1284](https://github.com/homeassistant-ai/ha-mcp/issues/1284))
([#​1286](https://github.com/homeassistant-ai/ha-mcp/pull/1286))
##### Fixed
- Remove counter from ha\_reload\_core targets ([#​1453](https://github.com/homeassistant-ai/ha-mcp/issues/1453))
([#​1456](https://github.com/homeassistant-ai/ha-mcp/pull/1456))
- **backup**: Post-timeout match correctness + state-gate (closes [#​1433](https://github.com/homeassistant-ai/ha-mcp/issues/1433))
([#​1435](https://github.com/homeassistant-ai/ha-mcp/pull/1435))
- Sync addon settings UI with Supervisor options end-to-end
([#​1420](https://github.com/homeassistant-ai/ha-mcp/pull/1420))
- **calendar**: Switch ha\_config\_remove\_calendar\_event to WebSocket (closes [#​1413](https://github.com/homeassistant-ai/ha-mcp/issues/1413), [#​1416](https://github.com/homeassistant-ai/ha-mcp/issues/1416))
([#​1418](https://github.com/homeassistant-ai/ha-mcp/pull/1418))
- Error-shape consistency for non-entity not-found (closes [#​1297](https://github.com/homeassistant-ai/ha-mcp/issues/1297))
([#​1397](https://github.com/homeassistant-ai/ha-mcp/pull/1397))
- Guard against silent automation overwrite on id mismatch ([#​1404](https://github.com/homeassistant-ai/ha-mcp/issues/1404))
([#​1405](https://github.com/homeassistant-ai/ha-mcp/pull/1405))
- Cache YAML instance to prevent CPU spikes in bulk edits ([#​1370](https://github.com/homeassistant-ai/ha-mcp/issues/1370))
([#​1371](https://github.com/homeassistant-ai/ha-mcp/pull/1371))
- **client**: Route get\_error\_log via hassio proxy on external-HAOS clients
([#​1360](https://github.com/homeassistant-ai/ha-mcp/pull/1360))
- Classify dashboard 404s ("unknown config specified") as RESOURCE\_NOT\_FOUND
([#​1345](https://github.com/homeassistant-ai/ha-mcp/pull/1345))
- Detect HA addon installs as http transport, not stdio ([#​1322](https://github.com/homeassistant-ai/ha-mcp/issues/1322))
([#​1327](https://github.com/homeassistant-ai/ha-mcp/pull/1327))
- Actionable 403 suggestion when addon has unmapped container ports ([#​1319](https://github.com/homeassistant-ai/ha-mcp/issues/1319))
([#​1325](https://github.com/homeassistant-ai/ha-mcp/pull/1325))
- Filter dismissed repairs in overview and system\_health ([#​1307](https://github.com/homeassistant-ai/ha-mcp/issues/1307))
([#​1309](https://github.com/homeassistant-ai/ha-mcp/pull/1309))
- Exit on HA container death + daily reset before CI check
([#​1295](https://github.com/homeassistant-ai/ha-mcp/pull/1295))
- Align ha\_config\_set\_dashboard with sibling re-fetch-after-save pattern ([#​1291](https://github.com/homeassistant-ai/ha-mcp/issues/1291))
([#​1301](https://github.com/homeassistant-ai/ha-mcp/pull/1301))
- Allow str.replace in python\_transform; hint at search mode on IndexError
([#​1287](https://github.com/homeassistant-ai/ha-mcp/pull/1287))
- **array\_patch**: Tighten validation and surface silent failures
([#​1285](https://github.com/homeassistant-ai/ha-mcp/pull/1285))
- HA Core proxy fallback for ha\_get\_logs(source=system\_service) on non-addon installs
([#​1283](https://github.com/homeassistant-ai/ha-mcp/pull/1283))
##### Performance Improvements
- Tighten \_poll\_for\_automation\_entity first-poll cadence
([#​1384](https://github.com/homeassistant-ai/ha-mcp/pull/1384))
- Parallelize ha\_get\_system\_health optional sections via asyncio.gather
([#​1336](https://github.com/homeassistant-ai/ha-mcp/pull/1336))
##### Refactoring
- **service**: Compact ha\_call\_service result default ([#​1446](https://github.com/homeassistant-ai/ha-mcp/issues/1446))
([#​1447](https://github.com/homeassistant-ai/ha-mcp/pull/1447))
- Rename ha\_update\_device → ha\_set\_device
([#​1444](https://github.com/homeassistant-ai/ha-mcp/pull/1444))
- Remove duplicate flat area/floor list tools (consolidation followup to [#​1016](https://github.com/homeassistant-ai/ha-mcp/issues/1016))
([#​1429](https://github.com/homeassistant-ai/ha-mcp/pull/1429))
- **complexity**: Migrate tools\_utility.py to class-based pattern
([#​1423](https://github.com/homeassistant-ai/ha-mcp/pull/1423))
- **complexity**: Reduce C901 violations in tools/ — batch 4
([#​1408](https://github.com/homeassistant-ai/ha-mcp/pull/1408))
- Route \_poll\_for\_automation\_entity through WS event waiter (closes [#​1395](https://github.com/homeassistant-ai/ha-mcp/issues/1395))
([#​1406](https://github.com/homeassistant-ai/ha-mcp/pull/1406))
- **yaml**: Use threading.local subclass for cached instance
([#​1396](https://github.com/homeassistant-ai/ha-mcp/pull/1396))
- Align dashboards 404 shape with sibling config tools
([#​1386](https://github.com/homeassistant-ai/ha-mcp/pull/1386))
- Complete singular warning → warnings list migration repo-wide (closes [#​1332](https://github.com/homeassistant-ai/ha-mcp/issues/1332))
([#​1341](https://github.com/homeassistant-ai/ha-mcp/pull/1341))
- Complete warnings-list migration for lifecycle-write tools
([#​1340](https://github.com/homeassistant-ai/ha-mcp/pull/1340))
- Drop redundant identifier echo key from ha\_config\_get\_automation
([#​1354](https://github.com/homeassistant-ai/ha-mcp/pull/1354))
- Drop logger.error in config-tool except blocks ([#​1302](https://github.com/homeassistant-ai/ha-mcp/issues/1302))
([#​1353](https://github.com/homeassistant-ai/ha-mcp/pull/1353))
- Extend validate\_identifier\_not\_empty to automations/scripts/dashboards CRUD (closes [#​1313](https://github.com/homeassistant-ai/ha-mcp/issues/1313))
([#​1321](https://github.com/homeassistant-ai/ha-mcp/pull/1321))
- Migrate tools\_config\_scenes inline empty-id guards to shared helper
([#​1320](https://github.com/homeassistant-ai/ha-mcp/pull/1320))
- Remove ha\_get\_helper\_schema (closes [#​1186](https://github.com/homeassistant-ai/ha-mcp/issues/1186))
([#​1315](https://github.com/homeassistant-ai/ha-mcp/pull/1315))
- Consolidate skill tools; fix stable submodule packaging
([#​1289](https://github.com/homeassistant-ai/ha-mcp/pull/1289))
- Align tools\_config\_automations.py error-handling with sibling pattern ([#​1290](https://github.com/homeassistant-ai/ha-mcp/issues/1290))
([#​1298](https://github.com/homeassistant-ai/ha-mcp/pull/1298))
***
<details>
<summary>Internal Changes</summary>
##### Fixed
- **ci**: Install libguestfs in HAOS publish workflow
([#​1358](https://github.com/homeassistant-ai/ha-mcp/pull/1358))
##### Build System
- **deps**: Bump esbuild from 0.24.2 to 0.25.0 in /tests/js
([#​1427](https://github.com/homeassistant-ai/ha-mcp/pull/1427))
- **deps**: Bump devalue from 5.6.4 to 5.8.1 in /site
([#​1282](https://github.com/homeassistant-ai/ha-mcp/pull/1282))
- **deps**: Bump astro from 6.1.6 to 6.1.10 in /site
([#​1274](https://github.com/homeassistant-ai/ha-mcp/pull/1274))
##### Chores
- **addon**: Publish dev addon version 7.5.0.dev360 \[skip ci]
([`ad7aed1`](https://github.com/homeassistant-ai/ha-mcp/commit/ad7aed13d6843967e2a259ae46fec2bbc6abc896))
- Sync tool docs after merge \[skip ci]
([`9c4984f`](https://github.com/homeassistant-ai/ha-mcp/commit/9c4984fc44d30c15a96372fbc1b401fbd679dc8f))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.4
([#​1450](https://github.com/homeassistant-ai/ha-mcp/pull/1450))
- **addon**: Publish dev addon version 7.5.0.dev359 \[skip ci]
([`b82d4ee`](https://github.com/homeassistant-ai/ha-mcp/commit/b82d4eea85792b620368d4859e99c143f9fbfadf))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.16
([#​1449](https://github.com/homeassistant-ai/ha-mcp/pull/1449))
- **addon**: Publish dev addon version 7.5.0.dev358 \[skip ci]
([`53fba6d`](https://github.com/homeassistant-ai/ha-mcp/commit/53fba6da76ce8c78a0de035883233a36762601bc))
- Sync tool docs after merge \[skip ci]
([`dc7750d`](https://github.com/homeassistant-ai/ha-mcp/commit/dc7750de16b60f70e40e6e5c8908d9e84e544683))
- **addon**: Publish dev addon version 7.5.0.dev357 \[skip ci]
([`fd150c9`](https://github.com/homeassistant-ai/ha-mcp/commit/fd150c9b9c4bdb9026e67eae340226c36b270d94))
- **addon**: Publish dev addon version 7.5.0.dev356 \[skip ci]
([`5fa1463`](https://github.com/homeassistant-ai/ha-mcp/commit/5fa14630229ba0d6b97d9328768e247bf9c20af4))
- **addon**: Publish dev addon version 7.5.0.dev355 \[skip ci]
([`174ac5d`](https://github.com/homeassistant-ai/ha-mcp/commit/174ac5dca7667702cd664420c50e0101366e6c3a))
- **addon**: Publish dev addon version 7.5.0.dev354 \[skip ci]
([`4f93989`](https://github.com/homeassistant-ai/ha-mcp/commit/4f939892dea2d1951541b1a557c51e957f6751c0))
- **addon**: Publish dev addon version 7.5.0.dev353 \[skip ci]
([`53f282f`](https://github.com/homeassistant-ai/ha-mcp/commit/53f282f19ee736637106f5baececa3939393778e))
- **addon**: Publish dev addon version 7.5.0.dev352 \[skip ci]
([`4911d46`](https://github.com/homeassistant-ai/ha-mcp/commit/4911d4682c4a865a93a8e821bc86bd26cef0ed5a))
- Sync tool docs after merge \[skip ci]
([`8a79837`](https://github.com/homeassistant-ai/ha-mcp/commit/8a798373a7b2f1adb94b93e65d626ab582c7bd5d))
- **addon**: Publish dev addon version 7.5.0.dev351 \[skip ci]
([`13afa9d`](https://github.com/homeassistant-ai/ha-mcp/commit/13afa9df026dd27332277140c34f7d41d0229efd))
- **addon**: Publish dev addon version 7.5.0.dev350 \[skip ci]
([`e93d680`](https://github.com/homeassistant-ai/ha-mcp/commit/e93d6806025c6d7fd2ef94c509a607c4ac85c8e0))
- **addon**: Publish dev addon version 7.5.0.dev349 \[skip ci]
([`1631ad1`](https://github.com/homeassistant-ai/ha-mcp/commit/1631ad10bdada4487d7b54049e92df6ddb29439a))
- **addon**: Publish dev addon version 7.5.0.dev348 \[skip ci]
([`18a8aef`](https://github.com/homeassistant-ai/ha-mcp/commit/18a8aef50675c1a881b279666e0af1b093679850))
- Sync tool docs after merge \[skip ci]
([`9e0493d`](https://github.com/homeassistant-ai/ha-mcp/commit/9e0493d248e23a8042841e90847662926395a448))
- **addon**: Publish dev addon version 7.5.0.dev347 \[skip ci]
([`e2067e4`](https://github.com/homeassistant-ai/ha-mcp/commit/e2067e446b127097e61d07516ae0e742ae2de6c8))
- Sync tool docs after merge \[skip ci]
([`7bdb3d4`](https://github.com/homeassistant-ai/ha-mcp/commit/7bdb3d402b60900a1012b8269e52b7cbeb400f84))
- **addon**: Publish dev addon version 7.5.0.dev346 \[skip ci]
([`c2d4dd7`](https://github.com/homeassistant-ai/ha-mcp/commit/c2d4dd7091653a618326f665fd34b5458d26c8f6))
- Sync tool docs after merge \[skip ci]
([`393b354`](https://github.com/homeassistant-ai/ha-mcp/commit/393b354e8a8e1280029eee9521971c693526970a))
- **addon**: Publish dev addon version 7.5.0.dev345 \[skip ci]
([`42ede8b`](https://github.com/homeassistant-ai/ha-mcp/commit/42ede8b0e6066faf3ed6f6920629a8d94d77f69a))
- **addon**: Publish dev addon version 7.5.0.dev344 \[skip ci]
([`e6cc7a1`](https://github.com/homeassistant-ai/ha-mcp/commit/e6cc7a1b8ed252f1aaa2b8c964e56c97a27b94c2))
- Sync tool docs after merge \[skip ci]
([`fb35f30`](https://github.com/homeassistant-ai/ha-mcp/commit/fb35f305cbf7de6807c29bd3ada9da2f028ff730))
- **addon**: Publish dev addon version 7.5.0.dev343 \[skip ci]
([`401b7b4`](https://github.com/homeassistant-ai/ha-mcp/commit/401b7b4d707dbb3c56a3afecad9e9d22ecbc7d1e))
- **addon**: Publish dev addon version 7.5.0.dev342 \[skip ci]
([`0679371`](https://github.com/homeassistant-ai/ha-mcp/commit/06793710b04a985ed0d66861266b9b79494e4111))
- Sync tool docs after merge \[skip ci]
([`f6796ec`](https://github.com/homeassistant-ai/ha-mcp/commit/f6796ec19b4596455ff54b58746bd3e075d5d280))
- **addon**: Publish dev addon version 7.5.0.dev341 \[skip ci]
([`3654478`](https://github.com/homeassistant-ai/ha-mcp/commit/3654478f80428d15671e49162acecea19d67f672))
- **addon**: Publish dev addon version 7.5.0.dev340 \[skip ci]
([`64f00b6`](https://github.com/homeassistant-ai/ha-mcp/commit/64f00b658846cad0e0714f37d221fb65327015cf))
- **addon**: Publish dev addon version 7.5.0.dev339 \[skip ci]
([`d6e8873`](https://github.com/homeassistant-ai/ha-mcp/commit/d6e88731556464deb768524dc24c90fd0a622a96))
- Sync tool docs after merge \[skip ci]
([`7525e93`](https://github.com/homeassistant-ai/ha-mcp/commit/7525e930a872871fed78f9b1461aea8e78eb5ad7))
- **addon**: Publish dev addon version 7.5.0.dev338 \[skip ci]
([`288ca4a`](https://github.com/homeassistant-ai/ha-mcp/commit/288ca4abd00b2b366cbaf671c1ace3398cc8f2fd))
- **addon**: Publish dev addon version 7.5.0.dev337 \[skip ci]
([`f539ae5`](https://github.com/homeassistant-ai/ha-mcp/commit/f539ae5aa881853d831e6952ff3af8bc85eb8b2a))
- **addon**: Publish dev addon version 7.5.0.dev336 \[skip ci]
([`5568a86`](https://github.com/homeassistant-ai/ha-mcp/commit/5568a861002cfb909e29368bd4e93ef0bd2e4c03))
- **addon**: Publish dev addon version 7.5.0.dev335 \[skip ci]
([`e069405`](https://github.com/homeassistant-ai/ha-mcp/commit/e0694054bd8627f6464379c34c1e3eec5b080a44))
- **addon**: Publish dev addon version 7.5.0.dev334 \[skip ci]
([`f7be6ea`](https://github.com/homeassistant-ai/ha-mcp/commit/f7be6ead486a32840a935a1e5ec78a34f8003c0d))
- **addon**: Publish dev addon version 7.5.0.dev333 \[skip ci]
([`cb480ea`](https://github.com/homeassistant-ai/ha-mcp/commit/cb480eae4d855345c19a6465351e0bdef2bdf5c3))
- Sync tool docs after merge \[skip ci]
([`9a5bc3c`](https://github.com/homeassistant-ai/ha-mcp/commit/9a5bc3c61372159bb936d7b929166924343dc76f))
- **addon**: Publish dev addon version 7.5.0.dev332 \[skip ci]
([`e0e59ee`](https://github.com/homeassistant-ai/ha-mcp/commit/e0e59ee08072bb4aac51e90928fab2d68f6156ce))
- Sync tool docs after merge \[skip ci]
([`499ebf0`](https://github.com/homeassistant-ai/ha-mcp/commit/499ebf0c9d4c4ec3784dd72782fe301cd9c19d60))
- **addon**: Publish dev addon version 7.5.0.dev331 \[skip ci]
([`3e0ce92`](https://github.com/homeassistant-ai/ha-mcp/commit/3e0ce92e11777a8fd9c86153e4c248007b8edae9))
- **addon**: Publish dev addon version 7.5.0.dev330 \[skip ci]
([`e48d056`](https://github.com/homeassistant-ai/ha-mcp/commit/e48d056ab356e11f8b2952b6c675307d1e76a895))
- **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.15
([#​1376](https://github.com/homeassistant-ai/ha-mcp/pull/1376))
- **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.5.3
([#​1377](https://github.com/homeassistant-ai/ha-mcp/pull/1377))
- **addon**: Publish dev addon version 7.5.0.dev329 \[skip ci]
([`c523c50`](https://github.com/homeassistant-ai/ha-mcp/commit/c523c502c5c6f282905620d3db489e9c69ec2472))
- Sync tool docs after merge \[skip ci]
([`5b7a8aa`](https://github.com/homeassistant-ai/ha-mcp/commit/5b7a8aa0794359a90d7b89a9cc61d73d8cf038d2))
- **addon**: Publish dev addon version 7.5.0.dev328 \[skip ci]
([`6c42fba`](https://github.com/homeassistant-ai/ha-mcp/commit/6c42fba92d4786d7498f738c53dfe50c899d0890))
- **addon**: Publish dev addon version 7.5.0.dev327 \[skip ci]
([`aecd025`](https://github.com/homeassistant-ai/ha-mcp/commit/aecd025eeea3d1edcd9466db3720cb17de71b90a))
- **addon**: Publish dev addon version 7.5.0.dev326 \[skip ci]
([`399c17c`](https://github.com/homeassistant-ai/ha-mcp/commit/399c17c36602a7767491df6e317186cb6291f3e4))
- **addon**: Publish dev addon version 7.5.0.dev325 \[skip ci]
([`b580b45`](https://github.com/homeassistant-ai/ha-mcp/commit/b580b452e9007deb33acc49098238988aa768603))
- Sync tool docs after merge \[skip ci]
([`8567c3a`](https://github.com/homeassistant-ai/ha-mcp/commit/8567c3a6e66e7bebbbad8e96b94058f8456deb14))
- **addon**: Publish dev addon version 7.5.0.dev324 \[skip ci]
([`a65579d`](https://github.com/homeassistant-ai/ha-mcp/commit/a65579d0b6e4a8bb7f8c1ed97fd432cd770c47a4))
- **addon**: Publish dev addon version 7.5.0.dev323 \[skip ci]
([`c7667ba`](https://github.com/homeassistant-ai/ha-mcp/commit/c7667ba66538f1ba8a06b7616fb15896bf021744))
- **addon**: Publish dev addon version 7.5.0.dev322 \[skip ci]
([`44d15a8`](https://github.com/homeassistant-ai/ha-mcp/commit/44d15a89cbacc2c38ab39868b380414507a6708b))
- **addon**: Publish dev addon version 7.5.0.dev321 \[skip ci]
([`8739f6c`](https://github.com/homeassistant-ai/ha-mcp/commit/8739f6c09121c88a596470df293ac8e7e0f1050a))
- **addon**: Publish dev addon version 7.5.0.dev320 \[skip ci]
([`02b6e47`](https://github.com/homeassistant-ai/ha-mcp/commit/02b6e47f8eb6c778f709d7adca115638c2fe98a2))
- Sync tool docs after merge \[skip ci]
([`ab68c9a`](https://github.com/homeassistant-ai/ha-mcp/commit/ab68c9a9aa94ac6861af7b59997ec679f1849503))
- **addon**: Publish dev addon version 7.5.0.dev319 \[skip ci]
([`4472904`](https://github.com/homeassistant-ai/ha-mcp/commit/44729040c11af0bd97189080c1ec59995fc563b4))
- **addon**: Publish dev addon version 7.5.0.dev318 \[skip ci]
([`e030dbc`](https://github.com/homeassistant-ai/ha-mcp/commit/e030dbcc99e002751834274b1d53da161ab27759))
- **addon**: Publish dev addon version 7.5.0.dev317 \[skip ci]
([`d87855c`](https://github.com/homeassistant-ai/ha-mcp/commit/d87855cf07cef9d9d7babf0bbec74d228149327d))
- Sync tool docs after merge \[skip ci]
([`a72a4e8`](https://github.com/homeassistant-ai/ha-mcp/commit/a72a4e8c0de99a8516f3820545642c37a31c17e5))
- **addon**: Publish dev addon version 7.5.0.dev316 \[skip ci]
([`bd9397f`](https://github.com/homeassistant-ai/ha-mcp/commit/bd9397f3a088a24a14af66a97afcf1c97904ef61))
- **addon**: Publish dev addon version 7.5.0.dev315 \[skip ci]
([`264bfc2`](https://github.com/homeassistant-ai/ha-mcp/commit/264bfc2fcb5ef6fe3ee6f9e073b69e0469eeafdd))
- **addon**: Publish dev addon version 7.5.0.dev314 \[skip ci]
([`df62881`](https://github.com/homeassistant-ai/ha-mcp/commit/df6288194cdde8b625132f19b0dd3edb2142a2b3))
- **addon**: Publish dev addon version 7.5.0.dev313 \[skip ci]
([`f6c47ca`](https://github.com/homeassistant-ai/ha-mcp/commit/f6c47caa21b0d82799b2be9330f97aa5494aa3c8))
- **addon**: Publish dev addon version 7.5.0.dev312 \[skip ci]
([`2bb7a74`](https://github.com/homeassistant-ai/ha-mcp/commit/2bb7a74f06e0652a729a735b08fc7cdc20a034f6))
- Sync tool docs after merge \[skip ci]
([`137e279`](https://github.com/homeassistant-ai/ha-mcp/commit/137e27943b1b704fe1d3e3a5b525b4d82bce33eb))
- **addon**: Publish dev addon version 7.5.0.dev311 \[skip ci]
([`28324ea`](https://github.com/homeassistant-ai/ha-mcp/commit/28324ea4a92fbf61f5ee40c561286c466af2309a))
- Sync tool docs after merge \[skip ci]
([`9a753d4`](https://github.com/homeassistant-ai/ha-mcp/commit/9a753d49abb4ccd84e874451dbcc563260f9e19d))
- **addon**: Publish dev addon version 7.5.0.dev310 \[skip ci]
([`f893b2e`](https://github.com/homeassistant-ai/ha-mcp/commit/f893b2ebf91967d0e2548f9205a15bfe0e7d86c2))
- **addon**: Publish dev addon version 7.5.0.dev309 \[skip ci]
([`8cbdb7b`](https://github.com/homeassistant-ai/ha-mcp/commit/8cbdb7bf318707fed1a0b3e8cb9922e6c170521e))
- **addon**: Publish dev addon version 7.5.0.dev308 \[skip ci]
([`2d18016`](https://github.com/homeassistant-ai/ha-mcp/commit/2d18016de8eb26a18cfb471e7b5f755f1309bd36))
- **addon**: Publish dev addon version 7.5.0.dev307 \[skip ci]
([`3fc3b28`](https://github.com/homeassistant-ai/ha-mcp/commit/3fc3b28881f237df02da8b65467fba9a7d693009))
- Sync tool docs after merge \[skip ci]
([`9e6cff8`](https://github.com/homeassistant-ai/ha-mcp/commit/9e6cff8f641bcd8122e94fc8be9c30aa18456e80))
- **addon**: Publish dev addon version 7.5.0.dev306 \[skip ci]
([`8bdd0fc`](https://github.com/homeassistant-ai/ha-mcp/commit/8bdd0fca9c107f45e4c3719e7616984b68876a9e))
- **addon**: Publish dev addon version 7.5.0.dev305 \[skip ci]
([`83535b9`](https://github.com/homeassistant-ai/ha-mcp/commit/83535b99e190fb56b7ce227334331ebf2affb3e1))
- **addon**: Publish dev addon version 7.5.0.dev304 \[skip ci]
([`1435b3a`](https://github.com/homeassistant-ai/ha-mcp/commit/1435b3a24d73503e189b83f8ea5aaeea20d9ebf3))
- **addon**: Publish dev addon version 7.5.0.dev303 \[skip ci]
([`e2da659`](https://github.com/homeassistant-ai/ha-mcp/commit/e2da6591d6ad2def0b48a9be750cb8a41f40524d))
- Sync tool docs after merge \[skip ci]
([`23789fa`](https://github.com/homeassistant-ai/ha-mcp/commit/23789fa978591b7d3966894082a2683ca6a6ae3b))
- **addon**: Publish dev addon version 7.5.0.dev302 \[skip ci]
([`6c8e574`](https://github.com/homeassistant-ai/ha-mcp/commit/6c8e574e7e3d8d78b3a2e48f6a70531d7a95eed8))
- Sync tool docs after merge \[skip ci]
([`d2329cb`](https://github.com/homeassistant-ai/ha-mcp/commit/d2329cbff39891d209317528fd7b42759c3414a8))
- **addon**: Publish dev addon version 7.5.0.dev301 \[skip ci]
([`bb538f7`](https://github.com/homeassistant-ai/ha-mcp/commit/bb538f70d2fc57072f09cfc6202e9d3dc1a2d257))
- Sync tool docs after merge \[skip ci]
([`f70f0e1`](https://github.com/homeassistant-ai/ha-mcp/commit/f70f0e14222b29a8923e706f113d1fafb4a5c23e))
- **addon**: Publish version 7.5.0 \[skip ci]
([`9c5eb37`](https://github.com/homeassistant-ai/ha-mcp/commit/9c5eb37779236ef19366a2a59a667d3916458e5a))
##### Continuous Integration
- **deps**: Bump actions/upload-artifact in the github-actions group
([#​1437](https://github.com/homeassistant-ai/ha-mcp/pull/1437))
- Share qcow2 cache + GHCR fallback between HAOS lanes
([#​1407](https://github.com/homeassistant-ai/ha-mcp/pull/1407))
- Add ruff format --check on changed Python files
([#​1387](https://github.com/homeassistant-ai/ha-mcp/pull/1387))
- Exempt assigned issues from stale bot
([#​1368](https://github.com/homeassistant-ai/ha-mcp/pull/1368))
- **deps**: Bump the github-actions group with 3 updates
([#​1362](https://github.com/homeassistant-ai/ha-mcp/pull/1362))
##### Refactoring
- Consolidate lovelace/dashboards/list through shared helper
([#​1344](https://github.com/homeassistant-ai/ha-mcp/pull/1344))
##### Testing
- **haos-e2e**: Bake + install webhook-proxy addon and exercise its runtime
([#​1443](https://github.com/homeassistant-ai/ha-mcp/pull/1443))
- **config-subentry**: Mark forecast\_solar e2e as known flaky + relative-import sweep
([#​1430](https://github.com/homeassistant-ai/ha-mcp/pull/1430))
- **haos-e2e**: Trim cache-save race, compress GHCR qcow2, eval boot snapshot
([#​1428](https://github.com/homeassistant-ai/ha-mcp/pull/1428))
- JSDOM behaviour harness + auto-discovery parse coverage for every rendered <script>
([#​1425](https://github.com/homeassistant-ai/ha-mcp/pull/1425))
- **hacs**: Retry TestMcpToolsInstallation on flake
([#​1426](https://github.com/homeassistant-ai/ha-mcp/pull/1426))
- **e2e**: Drop redundant lifecycle roundtrips, keep only Matter Server ([#​1414](https://github.com/homeassistant-ai/ha-mcp/issues/1414))
([#​1419](https://github.com/homeassistant-ai/ha-mcp/pull/1419))
- **e2e**: Assert backend dispatch matches workflow env on every lane
([#​1409](https://github.com/homeassistant-ai/ha-mcp/pull/1409))
- Escape ideographic space and format file ([#​1237](https://github.com/homeassistant-ai/ha-mcp/issues/1237))
([#​1410](https://github.com/homeassistant-ai/ha-mcp/pull/1410))
- **e2e**: Measure \_POLL\_CADENCE p50/p99 to validate or retune (closes [#​1389](https://github.com/homeassistant-ai/ha-mcp/issues/1389))
([#​1398](https://github.com/homeassistant-ai/ha-mcp/pull/1398))
- **e2e**: Wait for addon state=started in haos proxy header test
([#​1402](https://github.com/homeassistant-ai/ha-mcp/pull/1402))
- Pin remaining \_classify\_by\_message branches
([#​1385](https://github.com/homeassistant-ai/ha-mcp/pull/1385))
- **haos-e2e**: Slim addon set + real-addon ha\_manage\_addon coverage (closes [#​1350](https://github.com/homeassistant-ai/ha-mcp/issues/1350))
([#​1379](https://github.com/homeassistant-ai/ha-mcp/pull/1379))
- **haos-e2e**: Close out [#​1349](https://github.com/homeassistant-ai/ha-mcp/issues/1349) — lifecycle, integrations, supervisor\_mock migration, no more skips
([#​1375](https://github.com/homeassistant-ai/ha-mcp/pull/1375))
- **e2e**: Consolidate readiness gates onto /api/core/state (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1372](https://github.com/homeassistant-ai/ha-mcp/pull/1372))
- **e2e**: Tighten 5 readiness-gate budgets with 2-63x headroom (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1369](https://github.com/homeassistant-ai/ha-mcp/pull/1369))
- Scaffold HAOS E2E tier image-build pipeline (refs [#​1281](https://github.com/homeassistant-ai/ha-mcp/issues/1281))
([#​1326](https://github.com/homeassistant-ai/ha-mcp/pull/1326))
- **e2e**: Instrument HA\_MCP\_TOOLS\_WAIT readiness gate (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1346](https://github.com/homeassistant-ai/ha-mcp/pull/1346))
- **e2e**: Centralize wait\_for\_entity\_registration helper (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1308](https://github.com/homeassistant-ai/ha-mcp/pull/1308))
- **e2e**: Unify dict-error message extraction across e2e tests (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1311](https://github.com/homeassistant-ai/ha-mcp/pull/1311))
- **e2e**: Surface readiness-gate elapsed times in CI logs (refs [#​366](https://github.com/homeassistant-ai/ha-mcp/issues/366))
([#​1310](https://github.com/homeassistant-ai/ha-mcp/pull/1310))
</details>
</details>
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->
Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/994
…➔ 7.7.0) (#243) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/homeassistant-ai/ha-mcp](https://github.com/homeassistant-ai/ha-mcp) | minor | `7.6.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](homeassistant-ai/ha-mcp@v7.6.0...v7.7.0) ##### Added - User-configurable custom filesystem directories for the file tools (closes [#​1567](homeassistant-ai/ha-mcp#1567)) ([#​1568](homeassistant-ai/ha-mcp#1568)) - Expose all user-tunable env vars in the settings UI (add-on parity) ([#​1554](homeassistant-ai/ha-mcp#1554)) - Warn when default MCP\_SECRET\_PATH is bound non-loopback ([#​1472](homeassistant-ai/ha-mcp#1472)) - **search**: Consolidate ha\_search\_entities + ha\_deep\_search into ha\_search ([#​1529](homeassistant-ai/ha-mcp#1529)) - **addon**: Install the MCP Server add-on from the ha\_mcp\_tools integration ([#​1528](homeassistant-ai/ha-mcp#1528)) - Add opt-in dashboard screenshot mode ([#​1510](homeassistant-ai/ha-mcp#1510)) - Add Linux support for install & docs ([#​1096](homeassistant-ai/ha-mcp#1096)) - Surface the web settings page for non-add-on installs ([#​1458](homeassistant-ai/ha-mcp#1458)) ([#​1511](homeassistant-ai/ha-mcp#1511)) - Convert Pydantic arg-validation errors to actionable ToolErrors ([#​1491](homeassistant-ai/ha-mcp#1491)) - Per-key toggles for automation/script/scene in packages/\*.yaml ([#​1476](homeassistant-ai/ha-mcp#1476)) - Direct skills retrieval for write tools + improved best practice checker warnings with embedded skills responses ([#​1182](homeassistant-ai/ha-mcp#1182)) ([#​1448](homeassistant-ai/ha-mcp#1448)) - Detect last\_changed/last\_updated duration math and suggest for: field ([#​1157](homeassistant-ai/ha-mcp#1157)) ([#​1264](homeassistant-ai/ha-mcp#1264)) - Advanced settings panel + nested beta master toggle ([#​1164](homeassistant-ai/ha-mcp#1164)) ([#​1431](homeassistant-ai/ha-mcp#1431)) - Allow automation/script/scene yaml\_path in packages/\*.yaml only ([#​1452](homeassistant-ai/ha-mcp#1452)) - Restrict ha\_mcp\_tools services to ha-mcp callers (caller token + ha\_call\_service refusal) ([#​1459](homeassistant-ai/ha-mcp#1459)) ##### Changed - **security**: Soften vulnerability-response SLA to best-effort ([`a24e7da`](homeassistant-ai/ha-mcp@a24e7da)) - Update contributors list \[contributors-updated] ([`7cc187f`](homeassistant-ai/ha-mcp@7cc187f)) - Telemetry wording — follow HA analytics setting, not opt-in-only ([#​1481](homeassistant-ai/ha-mcp#1481)) - **security**: Note that security-advisory disposition is API-blind (UI-only) ([#​1561](homeassistant-ai/ha-mcp#1561)) - **tools**: Sharpen ha\_eval\_template usage routing for compute-from-state queries ([#​1550](homeassistant-ai/ha-mcp#1550)) - Differentiate ha-mcp from Home Assistant's built-in MCP Server ([#​1542](homeassistant-ai/ha-mcp#1542)) - Update advanced mode notes ([#​1533](homeassistant-ai/ha-mcp#1533)) - **[#​1157](homeassistant-ai/ha-mcp#1157: Scripts native-for: guidance + fix numeric\_state-condition for: overclaim ([#​1480](homeassistant-ai/ha-mcp#1480)) - Clarify add-on vs uvx; add Codex + HTTP-native client setup ([#​1478](homeassistant-ai/ha-mcp#1478)) - **security**: Explicit threat model for trusted clients, LAN, sandbox, and OAuth tokens ([#​1463](homeassistant-ai/ha-mcp#1463)) - Clarify telemetry is a planned future feature, not implemented ([#​1469](homeassistant-ai/ha-mcp#1469)) ##### Fixed - **tools**: Bring HA API field names to 2026.6 — stale docstrings, automation plural canonicalization, fan speed (closes [#​1540](homeassistant-ai/ha-mcp#1540)) ([#​1566](homeassistant-ai/ha-mcp#1566)) - **energy**: Accept "water" energy source in ha\_manage\_energy\_prefs ([#​1553](homeassistant-ai/ha-mcp#1553)) - **tools**: Use action: not service: in automation docstring examples ([#​1539](homeassistant-ai/ha-mcp#1539)) - **security**: Narrow GHSA-mc92-ww4q-6fg4 to the masker and log redaction ([#​1512](homeassistant-ai/ha-mcp#1512)) - **addon**: Restrict settings UI root routes to HA ingress ([#​1508](homeassistant-ai/ha-mcp#1508)) - Add name attributes to generated settings-UI form controls (a11y) ([#​1497](homeassistant-ai/ha-mcp#1497)) - Add-on-aware code-mode locked note + suppress settings-UI favicon 404 ([#​1494](homeassistant-ai/ha-mcp#1494)) - Surface the real reason a WebSocket connection failed ([#​1495](homeassistant-ai/ha-mcp#1495)) - Remove str from ha\_bulk\_control.operations schema + fix wrong-reason test ([#​1492](homeassistant-ai/ha-mcp#1492)) - Remove str from bool/int param schemas across all tools ([#​1490](homeassistant-ai/ha-mcp#1490)) - **addon**: Expose non-beta tool options on the stable add-on ([#​1488](homeassistant-ai/ha-mcp#1488)) - **addon**: Enable ingress so the stable add-on shows the Open Web UI / Settings UI ([#​1486](homeassistant-ai/ha-mcp#1486)) - Refine last\_changed/last\_updated duration-math detector ([#​1157](homeassistant-ai/ha-mcp#1157)) ([#​1483](homeassistant-ai/ha-mcp#1483)) - Remove str from config param schema on service and entity tools ([#​1487](homeassistant-ai/ha-mcp#1487)) - Surface flow-helper config to agents reading UI-created templates ([#​1474](homeassistant-ai/ha-mcp#1474)) - Remove str from config param schema on set tools ([#​1485](homeassistant-ai/ha-mcp#1485)) - Route malformed ha\_mcp\_tools version to a distinct reinstall error ([#​1484](homeassistant-ai/ha-mcp#1484)) - Persist DCR client registrations and HMAC secret across restarts ([#​1261](homeassistant-ai/ha-mcp#1261)) ([#​1265](homeassistant-ai/ha-mcp#1265)) - Stop dev builds from publishing the :latest Docker tag ([#​1477](homeassistant-ai/ha-mcp#1477)) - Subscribe to HACS dispatch signal instead of 10x1s blind poll ([#​1455](homeassistant-ai/ha-mcp#1455)) - Reject python\_transform while loops ([#​1462](homeassistant-ai/ha-mcp#1462)) ##### Performance Improvements - Fast-fail HACS not-found lookups + batch-verify deep-search E2E fixtures ([#​1515](homeassistant-ai/ha-mcp#1515)) ([#​1552](homeassistant-ai/ha-mcp#1552)) ##### Refactoring - Add display title to ha\_get\_skill\_guide tool ([#​1543](homeassistant-ai/ha-mcp#1543)) - Fold ha\_check\_config into ha\_get\_system\_health include="config\_check" ([#​1516](homeassistant-ai/ha-mcp#1516)) - **c901**: Smart\_search.py below C901 threshold ([#​1507](homeassistant-ai/ha-mcp#1507)) - **hacs**: Consolidate HACS tools into ha\_get\_hacs + ha\_manage\_hacs ([#​1045](homeassistant-ai/ha-mcp#1045)) ([#​1502](homeassistant-ai/ha-mcp#1502)) - **c901**: Tools\_config\_helpers.py below C901 threshold ([#​1498](homeassistant-ai/ha-mcp#1498)) - **complexity**: Reduce C901 in tools\_addons.py via class-based pattern ([#​1432](homeassistant-ai/ha-mcp#1432)) *** <details> <summary>Internal Changes</summary> ##### Changed - Trim AGENTS.md below 40k + improve subdirectory CLAUDE.md files ([#​1499](homeassistant-ai/ha-mcp#1499)) ##### Chores - **addon**: Publish dev addon version 7.6.0.dev415 \[skip ci] ([`2c0148b`](homeassistant-ai/ha-mcp@2c0148b)) - **deps**: Update ghcr.io/home-assistant/home-assistant docker tag to v2026.6.1 ([#​1571](homeassistant-ai/ha-mcp#1571)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.19 ([#​1570](homeassistant-ai/ha-mcp#1570)) - **addon**: Publish dev addon version 7.6.0.dev414 \[skip ci] ([`0bf9e39`](homeassistant-ai/ha-mcp@0bf9e39)) - Sync tool docs after merge \[skip ci] ([`8f5e037`](homeassistant-ai/ha-mcp@8f5e037)) - **addon**: Publish dev addon version 7.6.0.dev413 \[skip ci] ([`6729327`](homeassistant-ai/ha-mcp@6729327)) - Sync tool docs after merge \[skip ci] ([`4341e95`](homeassistant-ai/ha-mcp@4341e95)) - **addon**: Publish dev addon version 7.6.0.dev412 \[skip ci] ([`148f506`](homeassistant-ai/ha-mcp@148f506)) - **addon**: Publish dev addon version 7.6.0.dev411 \[skip ci] ([`287fe55`](homeassistant-ai/ha-mcp@287fe55)) - Sync tool docs after merge \[skip ci] ([`b642b8e`](homeassistant-ai/ha-mcp@b642b8e)) - **addon**: Publish dev addon version 7.6.0.dev410 \[skip ci] ([`29e34dd`](homeassistant-ai/ha-mcp@29e34dd)) - **addon**: Publish dev addon version 7.6.0.dev409 \[skip ci] ([`dec16a1`](homeassistant-ai/ha-mcp@dec16a1)) - Sync tool docs after merge \[skip ci] ([`dd72535`](homeassistant-ai/ha-mcp@dd72535)) - **addon**: Publish dev addon version 7.6.0.dev408 \[skip ci] ([`c3c89f1`](homeassistant-ai/ha-mcp@c3c89f1)) - **addon**: Publish dev addon version 7.6.0.dev407 \[skip ci] ([`94195ee`](homeassistant-ai/ha-mcp@94195ee)) - **addon**: Publish dev addon version 7.6.0.dev406 \[skip ci] ([`f439424`](homeassistant-ai/ha-mcp@f439424)) - Sync tool docs after merge \[skip ci] ([`7464277`](homeassistant-ai/ha-mcp@7464277)) - **addon**: Publish dev addon version 7.6.0.dev405 \[skip ci] ([`146eb07`](homeassistant-ai/ha-mcp@146eb07)) - **addon**: Publish dev addon version 7.6.0.dev404 \[skip ci] ([`6a707bb`](homeassistant-ai/ha-mcp@6a707bb)) - Sync tool docs after merge \[skip ci] ([`85f3935`](homeassistant-ai/ha-mcp@85f3935)) - **addon**: Publish dev addon version 7.6.0.dev403 \[skip ci] ([`be1fa1d`](homeassistant-ai/ha-mcp@be1fa1d)) - Sync tool docs after merge \[skip ci] ([`d9adbd2`](homeassistant-ai/ha-mcp@d9adbd2)) - **addon**: Publish dev addon version 7.6.0.dev402 \[skip ci] ([`41ad7ca`](homeassistant-ai/ha-mcp@41ad7ca)) - **addon**: Publish dev addon version 7.6.0.dev401 \[skip ci] ([`8205034`](homeassistant-ai/ha-mcp@8205034)) - **deps**: Update ghcr.io/astral-sh/uv docker tag to v0.11.18 ([#​1523](homeassistant-ai/ha-mcp#1523)) - **addon**: Publish dev addon version 7.6.0.dev400 \[skip ci] ([`532cdc4`](homeassistant-ai/ha-mcp@532cdc4)) - Sync tool docs after merge \[skip ci] ([`e2c08ff`](homeassistant-ai/ha-mcp@e2c08ff)) - **addon**: Publish dev addon version 7.6.0.dev399 \[skip ci] ([`9501348`](homeassistant-ai/ha-mcp@9501348)) - Sync tool docs after merge \[skip ci] ([`e70a050`](homeassistant-ai/ha-mcp@e70a050)) - **addon**: Publish dev addon version 7.6.0.dev398 \[skip ci] ([`0b61424`](homeassistant-ai/ha-mcp@0b61424)) - Sync tool docs after merge \[skip ci] ([`6df7987`](homeassistant-ai/ha-mcp@6df7987)) - **addon**: Publish dev addon version 7.6.0.dev397 \[skip ci] ([`c34915f`](homeassistant-ai/ha-mcp@c34915f)) - Sync tool docs after merge \[skip ci] ([`6f88e7e`](homeassistant-ai/ha-mcp@6f88e7e)) - **addon**: Publish dev addon version 7.6.0.dev396 \[skip ci] ([`1490e19`](homeassistant-ai/ha-mcp@1490e19)) - Sync tool docs after merge \[skip ci] ([`ac2c7d0`](homeassistant-ai/ha-mcp@ac2c7d0)) - **addon**: Publish dev addon version 7.6.0.dev395 \[skip ci] ([`11e5ee8`](homeassistant-ai/ha-mcp@11e5ee8)) - **addon**: Publish dev addon version 7.6.0.dev394 \[skip ci] ([`5fc3e0f`](homeassistant-ai/ha-mcp@5fc3e0f)) - Flag untrusted third-party content in HACS and add-on tool responses ([#​1509](homeassistant-ai/ha-mcp#1509)) - **addon**: Publish dev addon version 7.6.0.dev393 \[skip ci] ([`9a37c28`](homeassistant-ai/ha-mcp@9a37c28)) - **addon**: Publish dev addon version 7.6.0.dev392 \[skip ci] ([`4f737ac`](homeassistant-ai/ha-mcp@4f737ac)) - **addon**: Publish dev addon version 7.6.0.dev391 \[skip ci] ([`fd5d3f2`](homeassistant-ai/ha-mcp@fd5d3f2)) - **addon**: Publish dev addon version 7.6.0.dev390 \[skip ci] ([`28dedf4`](homeassistant-ai/ha-mcp@28dedf4)) - **addon**: Publish dev addon version 7.6.0.dev389 \[skip ci] ([`9443446`](homeassistant-ai/ha-mcp@9443446)) - Sync tool docs after merge \[skip ci] ([`94fcbeb`](homeassistant-ai/ha-mcp@94fcbeb)) - **addon**: Publish dev addon version 7.6.0.dev388 \[skip ci] ([`ccc1816`](homeassistant-ai/ha-mcp@ccc1816)) - Drop dead entity\_cache attr + ruff-format fuzzy\_search.py ([#​1503](homeassistant-ai/ha-mcp#1503)) - **addon**: Publish dev addon version 7.6.0.dev387 \[skip ci] ([`057c108`](homeassistant-ai/ha-mcp@057c108)) - **addon**: Publish dev addon version 7.6.0.dev386 \[skip ci] ([`66f4ac6`](homeassistant-ai/ha-mcp@66f4ac6)) - **addon**: Publish dev addon version 7.6.0.dev385 \[skip ci] ([`f331f11`](homeassistant-ai/ha-mcp@f331f11)) - **addon**: Publish dev addon version 7.6.0.dev384 \[skip ci] ([`17c319e`](homeassistant-ai/ha-mcp@17c319e)) - Sync tool docs after merge \[skip ci] ([`f36cbb7`](homeassistant-ai/ha-mcp@f36cbb7)) - **addon**: Publish dev addon version 7.6.0.dev383 \[skip ci] ([`782ba3b`](homeassistant-ai/ha-mcp@782ba3b)) - **addon**: Publish dev addon version 7.6.0.dev382 \[skip ci] ([`b647ab6`](homeassistant-ai/ha-mcp@b647ab6)) - **addon**: Publish dev addon version 7.6.0.dev381 \[skip ci] ([`e999c24`](homeassistant-ai/ha-mcp@e999c24)) - Sync tool docs after merge \[skip ci] ([`50d76b0`](homeassistant-ai/ha-mcp@50d76b0)) - **addon**: Publish dev addon version 7.6.0.dev380 \[skip ci] ([`ebdc69b`](homeassistant-ai/ha-mcp@ebdc69b)) - Sync tool docs after merge \[skip ci] ([`1f03967`](homeassistant-ai/ha-mcp@1f03967)) - **addon**: Publish dev addon version 7.6.0.dev379 \[skip ci] ([`7cabb2e`](homeassistant-ai/ha-mcp@7cabb2e)) - **addon**: Publish dev addon version 7.6.0.dev378 \[skip ci] ([`7b631c7`](homeassistant-ai/ha-mcp@7b631c7)) - **addon**: Publish dev addon version 7.6.0.dev377 \[skip ci] ([`ea7b614`](homeassistant-ai/ha-mcp@ea7b614)) - **addon**: Publish dev addon version 7.6.0.dev376 \[skip ci] ([`fd33ecd`](homeassistant-ai/ha-mcp@fd33ecd)) - Sync tool docs after merge \[skip ci] ([`ba8fae3`](homeassistant-ai/ha-mcp@ba8fae3)) - **addon**: Publish dev addon version 7.6.0.dev375 \[skip ci] ([`afcd0d8`](homeassistant-ai/ha-mcp@afcd0d8)) - Sync tool docs after merge \[skip ci] ([`f9b55ad`](homeassistant-ai/ha-mcp@f9b55ad)) - **addon**: Publish dev addon version 7.6.0.dev374 \[skip ci] ([`eecdf8b`](homeassistant-ai/ha-mcp@eecdf8b)) - Sync tool docs after merge \[skip ci] ([`ef16a8a`](homeassistant-ai/ha-mcp@ef16a8a)) - **addon**: Publish dev addon version 7.6.0.dev373 \[skip ci] ([`9a93703`](homeassistant-ai/ha-mcp@9a93703)) - **addon**: Publish dev addon version 7.6.0.dev372 \[skip ci] ([`7352ce8`](homeassistant-ai/ha-mcp@7352ce8)) - **addon**: Publish dev addon version 7.6.0.dev371 \[skip ci] ([`d7601f5`](homeassistant-ai/ha-mcp@d7601f5)) - Sync tool docs after merge \[skip ci] ([`d0a4482`](homeassistant-ai/ha-mcp@d0a4482)) - **addon**: Publish dev addon version 7.6.0.dev370 \[skip ci] ([`f83c32c`](homeassistant-ai/ha-mcp@f83c32c)) - **addon**: Publish dev addon version 7.6.0.dev369 \[skip ci] ([`ea16661`](homeassistant-ai/ha-mcp@ea16661)) - **addon**: Publish dev addon version 7.6.0.dev368 \[skip ci] ([`af49ea5`](homeassistant-ai/ha-mcp@af49ea5)) - **addon**: Publish dev addon version 7.6.0.dev367 \[skip ci] ([`7dd5f4c`](homeassistant-ai/ha-mcp@7dd5f4c)) - **addon**: Publish dev addon version 7.6.0.dev366 \[skip ci] ([`6273b7e`](homeassistant-ai/ha-mcp@6273b7e)) - Sync tool docs after merge \[skip ci] ([`4e3fd5f`](homeassistant-ai/ha-mcp@4e3fd5f)) - **addon**: Publish dev addon version 7.6.0.dev365 \[skip ci] ([`f3bf17b`](homeassistant-ai/ha-mcp@f3bf17b)) - Sync tool docs after merge \[skip ci] ([`5307b60`](homeassistant-ai/ha-mcp@5307b60)) - **addon**: Publish dev addon version 7.6.0.dev364 \[skip ci] ([`76ec1ae`](homeassistant-ai/ha-mcp@76ec1ae)) - Sync tool docs after merge \[skip ci] ([`be864b5`](homeassistant-ai/ha-mcp@be864b5)) - **addon**: Publish dev addon version 7.6.0.dev363 \[skip ci] ([`da10c75`](homeassistant-ai/ha-mcp@da10c75)) - **addon**: Publish dev addon version 7.6.0.dev362 \[skip ci] ([`69f4527`](homeassistant-ai/ha-mcp@69f4527)) - **addon**: Publish version 7.6.0 \[skip ci] ([`086d75d`](homeassistant-ai/ha-mcp@086d75d)) ##### Continuous Integration - Vendor Puppet add-on as a pinned submodule + retry transient add-on builds ([#​1565](homeassistant-ai/ha-mcp#1565)) - Make sync-tool-docs push resilient to concurrent master advances ([#​1564](homeassistant-ai/ha-mcp#1564)) - Fix stale token-cap comment and harden triage budget tests ([#​1514](homeassistant-ai/ha-mcp#1514)) ([#​1560](homeassistant-ai/ha-mcp#1560)) - **deps**: Bump the github-actions group with 2 updates ([#​1556](homeassistant-ai/ha-mcp#1556)) - Budget triage prompt dynamically under the GitHub Models cap ([#​1514](homeassistant-ai/ha-mcp#1514)) ([#​1522](homeassistant-ai/ha-mcp#1522)) - Reduce Docker Hub pulls in performance-tests workflow ([#​1549](homeassistant-ai/ha-mcp#1549)) - Add JavaScript to the CodeQL code-quality gate ([#​1548](homeassistant-ai/ha-mcp#1548)) - Add CodeQL code-quality CI gate and clear all code-quality findings ([#​1526](homeassistant-ai/ha-mcp#1526)) - Drop tool list from evaluate prompt + tighten caps to fit 8K token limit ([`6f47c92`](homeassistant-ai/ha-mcp@6f47c92)) - Remove broken maintainer check (GITHUB\_TOKEN lacks read:org) ([`010ec58`](homeassistant-ai/ha-mcp@010ec58)) - Switch evaluate step to gpt-4o-mini (16K token free tier vs 8K on gpt-4.1) ([#​1496](homeassistant-ai/ha-mcp#1496)) - Issue bot v2 — GitHub Models triage, needs-info auto-close, duplicate detection ([#​1442](homeassistant-ai/ha-mcp#1442)) ##### Refactoring - Extract settings-UI JavaScript and CSS to separate files ([#​1505](homeassistant-ai/ha-mcp#1505)) - Collapse settings-UI route registration into one table ([#​1504](homeassistant-ai/ha-mcp#1504)) ##### Testing - **oauth**: Add HTTP smoke tests for OAuth metadata-discovery endpoints ([#​1562](homeassistant-ai/ha-mcp#1562)) - **uat**: Relabel c01 as a mode-discrimination probe (taxonomy consistency) ([#​1563](homeassistant-ai/ha-mcp#1563)) - **uat**: Rework c01 routing probe to ha\_search registry-listing mode after [#​1529](homeassistant-ai/ha-mcp#1529) ([#​1559](homeassistant-ai/ha-mcp#1559)) - **uat**: Add response\_contains\_any check and always log agent responses ([#​1537](homeassistant-ai/ha-mcp#1537)) - **uat**: Treat request timeout as per-story failure, not suite abort ([#​1536](homeassistant-ai/ha-mcp#1536)) - **uat**: Harden BAT story runner against agent crashes ([#​1535](homeassistant-ai/ha-mcp#1535)) - **uat**: Log model and quantization in BAT story results ([#​1525](homeassistant-ai/ha-mcp#1525)) - Capture reasoning tokens and detect inert --no-think in BAT openai agent ([#​1524](homeassistant-ai/ha-mcp#1524)) </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:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTQuNiIsInVwZGF0ZWRJblZlciI6IjQzLjIxNC42IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/243
Fixes #1514.
Problem
build_promptassembles up to 6 BM25 candidates (3500 chars each) + the ~92-tool list + a 16000-char body + static framing. Per the issue, the non-body portion alone can reach or exceed the GitHub Models 8000-token input cap, soEvaluategets an HTTP 413 on essentially every issue. 413 was unhandled (only 429 and>= 500were), so it broke straight tosetFailed, leaving the issue with atriage-failedlabel. The gpt-4o fallback shares the same cap, so it would 413 too.Fix
build_prompt— proactive budgeting (primary fix). After assembly, enforce a conservative token budget (chars/4 estimate, target 7000 to leave margin under the 8000 cap for the 800-token response). Trim in priority order so the actual issue text survives longest: drop BM25 duplicate candidates first, then the tool list, then truncate the body down to a 2000-char floor. The assembled token estimate is logged.Evaluate— 413 backstop. Catch 413 specifically and retry once with a truncated prompt instead of breaking tosetFailed. With the budgeting above this should not fire; it guards against estimate drift on token-dense bodies (logs/JSON).Testing
This runs in CI against GitHub Models with no checkout, so the assembly can't import a shared module and can't be exercised in a normal unit test. I added
scripts/verify_triage_prompt_budget.mjs, which mirrors the trim algorithm and asserts worst-case inputs (16000-char body + full tool list + 6 max BM25 candidates) stay under budget, the body is never trimmed below its floor, duplicates are dropped first, and small inputs are left untouched. Runs clean withnode scripts/verify_triage_prompt_budget.mjs.As you noted, the end-to-end path can only really be confirmed by merging and opening a fresh test issue. The harness keeps the budgeting logic itself checkable; happy to wire it into CI (or refactor the assembly into a checked-out, importable module) as a follow-up if you'd prefer that over the mirrored copy.