You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tools added to src/ha_mcp/tools/ between biweekly stable releases appear in homeassistant-addon/DOCS.md (and README.md and site/src/data/tools.json) on the next push to master, not on the next stable release. Because HA Supervisor refreshes addon-store metadata directly from the GitHub repository at its normal interval, stable add-on users see tools listed in their "Documentation" tab that don't yet exist in the runtime image they have installed. Calling those tools returns a not-found error from the running MCP server.
Concrete current example
The last stable release was v7.2.0 on 2026-04-01 (4b0be35e chore(addon): publish version 7.2.0). PR #876 merged on 2026-04-05 (commit 34a83b4b), four days after the cut, adding ha_remove_entity. As of today, on upstream/master:
homeassistant-addon/DOCS.md line 379 lists ha_remove_entity (regenerated by sync-tool-docs.yml post-merge).
ghcr.io/homeassistant-ai/ha-mcp-addon-{arch}:7.2.0, the image installed on every stable HAOS user, contains the pre-feat: add ha_remove_entity tool (closes #874) #876src/ snapshot — ha_remove_entity is not registered at runtime.
Net effect on a stable user's machine: ha_remove_entity is documented in the add-on's Documentation tab but absent from the live tool list and uncallable. Same pattern applies to every tool-only PR that lands in the gap between releases.
Mechanism
Two refresh cycles run on completely different schedules:
Source
Refresh cadence
Workflow
Add-on metadata (config.yaml, DOCS.md, README.md, translations/) read by HA Supervisor from the repo URL
Minutes after every push to master (Supervisor's normal store refresh)
sync-tool-docs.yml regenerates homeassistant-addon/DOCS.md via extract_tools.py whenever src/ha_mcp/tools/ changes
extract_tools.py reads the currentsrc/ tree at every invocation and writes the result to homeassistant-addon/DOCS.md unconditionally. There is no concept of "shipped vs upcoming" in the script today.
How should it be fixed?
Teach extract_tools.py to compare the current src/ha_mcp/tools/ tree against the last stable git tag (git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude '*dev*') and mark any tool present now but absent at that tag as upcoming. Render the marker inline in generate_docs_section and generate_readme_table, plus a one-line explanatory note above the tool list when at least one upcoming tool exists. The upcoming flag is computed dynamically — when semver-release.yml creates the next v7.x.x tag, the comparison baseline moves forward automatically and previously-flagged tools stop being marked. No release-time script needed, no PR-author action needed.
Sketch of the change
New helpers in extract_tools.py:
_last_stable_tag() — runs git describe, returns tag or None
_tool_names_at(tag) — runs git ls-tree + git show + AST-parses each tool file at that tag, returns the set of tool names
extract_tools() populates t["upcoming"] on each tool dict
generate_docs_section and generate_readme_table append a *(coming next release)* marker when upcoming is true (and beta is not also set, so the markers don't double-up)
CI: sync-tool-docs.yml and pr.yml need fetch-depth: 0 + fetch-tags: true on their actions/checkout steps so git describe can find tags
Tests in tests/src/unit/ for the new behavior
Total ballpark: ~60-80 lines of Python in extract_tools.py, two one-line CI workflow tweaks, plus tests.
Edge cases handled by the design
No stable tag exists yet (fresh repo): _last_stable_tag() returns None, no tool gets flagged, script falls back to current behavior.
Shallow CI checkout: addressed by the fetch-depth: 0 + fetch-tags: true workflow change. Without it, every tool would be marked upcoming, which would be visibly wrong on master and caught immediately.
git unavailable in the run environment: subprocess.CalledProcessError/FileNotFoundError caught, fall back to no marking.
Tool renamed between releases: it'd appear as both removed (old name) and upcoming (new name). Acceptable — rare event, and the docs accurately reflect the rename.
Additional context
Discovered while planning PR #942's beta-toggle work for ha_config_set_yaml. PR #942 will introduce a separate static beta tag mechanism for tools that are intentionally dev-channel-only behind a feature flag (different problem, different lifecycle: beta tools may stay beta indefinitely; upcoming tools auto-clear at the next release). The two mechanisms are designed to compose — a tool can be both beta and upcoming, in which case the beta marker takes precedence to avoid label noise. This issue covers the upcoming half only.
Where is the issue?
Tool documentation (
homeassistant-addon/DOCS.md,README.md,site/src/data/tools.json)What's wrong or unclear?
Tools added to
src/ha_mcp/tools/between biweekly stable releases appear inhomeassistant-addon/DOCS.md(andREADME.mdandsite/src/data/tools.json) on the next push to master, not on the next stable release. Because HA Supervisor refreshes addon-store metadata directly from the GitHub repository at its normal interval, stable add-on users see tools listed in their "Documentation" tab that don't yet exist in the runtime image they have installed. Calling those tools returns a not-found error from the running MCP server.Concrete current example
The last stable release was
v7.2.0on 2026-04-01 (4b0be35e chore(addon): publish version 7.2.0). PR #876 merged on 2026-04-05 (commit34a83b4b), four days after the cut, addingha_remove_entity. As of today, onupstream/master:homeassistant-addon/DOCS.mdline 379 listsha_remove_entity(regenerated bysync-tool-docs.ymlpost-merge).ghcr.io/homeassistant-ai/ha-mcp-addon-{arch}:7.2.0, the image installed on every stable HAOS user, contains the pre-feat: add ha_remove_entity tool (closes #874) #876src/snapshot —ha_remove_entityis not registered at runtime.Net effect on a stable user's machine:
ha_remove_entityis documented in the add-on's Documentation tab but absent from the live tool list and uncallable. Same pattern applies to every tool-only PR that lands in the gap between releases.Mechanism
Two refresh cycles run on completely different schedules:
config.yaml,DOCS.md,README.md,translations/) read by HA Supervisor from the repo URLmaster(Supervisor's normal store refresh)sync-tool-docs.ymlregenerateshomeassistant-addon/DOCS.mdviaextract_tools.pywheneversrc/ha_mcp/tools/changesghcr.io/.../ha-mcp-addon-{arch}:<version>)addon-publish.yml, called fromsemver-release.ymlextract_tools.pyreads the currentsrc/tree at every invocation and writes the result tohomeassistant-addon/DOCS.mdunconditionally. There is no concept of "shipped vs upcoming" in the script today.How should it be fixed?
Teach
extract_tools.pyto compare the currentsrc/ha_mcp/tools/tree against the last stable git tag (git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude '*dev*') and mark any tool present now but absent at that tag asupcoming. Render the marker inline ingenerate_docs_sectionandgenerate_readme_table, plus a one-line explanatory note above the tool list when at least one upcoming tool exists. Theupcomingflag is computed dynamically — whensemver-release.ymlcreates the nextv7.x.xtag, the comparison baseline moves forward automatically and previously-flagged tools stop being marked. No release-time script needed, no PR-author action needed.Sketch of the change
extract_tools.py:_last_stable_tag()— runsgit describe, returns tag orNone_tool_names_at(tag)— runsgit ls-tree+git show+ AST-parses each tool file at that tag, returns the set of tool namesextract_tools()populatest["upcoming"]on each tool dictgenerate_docs_sectionandgenerate_readme_tableappend a*(coming next release)*marker whenupcomingis true (andbetais not also set, so the markers don't double-up)sync-tool-docs.ymlandpr.ymlneedfetch-depth: 0+fetch-tags: trueon theiractions/checkoutsteps sogit describecan find tagstests/src/unit/for the new behaviorTotal ballpark: ~60-80 lines of Python in
extract_tools.py, two one-line CI workflow tweaks, plus tests.Edge cases handled by the design
_last_stable_tag()returnsNone, no tool gets flagged, script falls back to current behavior.fetch-depth: 0+fetch-tags: trueworkflow change. Without it, every tool would be markedupcoming, which would be visibly wrong on master and caught immediately.gitunavailable in the run environment:subprocess.CalledProcessError/FileNotFoundErrorcaught, fall back to no marking.Additional context
Discovered while planning PR #942's beta-toggle work for
ha_config_set_yaml. PR #942 will introduce a separate staticbetatag mechanism for tools that are intentionally dev-channel-only behind a feature flag (different problem, different lifecycle: beta tools may stay beta indefinitely; upcoming tools auto-clear at the next release). The two mechanisms are designed to compose — a tool can be bothbetaandupcoming, in which case thebetamarker takes precedence to avoid label noise. This issue covers theupcominghalf only.