Skip to content

Commit bcd51b1

Browse files
authored
Merge branch 'homeassistant-ai:master' into master
2 parents 62b9e95 + 6ffbd6a commit bcd51b1

28 files changed

Lines changed: 3314 additions & 55 deletions

.env.example

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ LOG_LEVEL=INFO
3232
# top-level keys in configuration.yaml and packages/*.yaml.
3333
# ENABLE_YAML_CONFIG_EDITING=false
3434

35+
# Tool visibility seed values (comma-separated tool names). On first start
36+
# these are written to tool_config.json; after that the web settings UI at
37+
# http://<server>/settings is the source of truth. See DOCS.md for details.
38+
# DISABLED_TOOLS=
39+
# PINNED_TOOLS=
40+
41+
# Max results from ha_search_tools (2-10, default 5).
42+
# TOOL_SEARCH_MAX_RESULTS=5
43+
3544
# Optional: MCP Server Configuration
3645
MCP_SERVER_NAME=ha-mcp
37-
# MCP_SERVER_VERSION defaults to the package version (e.g. 6.7.2)
46+
# MCP_SERVER_VERSION defaults to the package version (e.g. 6.7.2)

.github/workflows/hotfix-release.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,22 @@ jobs:
2828
issues: write
2929

3030
steps:
31-
- name: Checkout hotfix branch commit
31+
- name: Checkout merged hotfix on master
3232
uses: actions/checkout@v6
3333
with:
34-
# Checkout the original hotfix commit, not the merge commit
35-
ref: ${{ github.event.pull_request.head.sha }}
34+
# Check out the merge commit so the workspace matches master's history;
35+
# then attach to a local master branch below. python-semantic-release
36+
# matches the active branch against [tool.semantic_release].branch
37+
# in pyproject.toml — a detached HEAD checkout (e.g., of head.sha)
38+
# fails silently with "Detached HEAD state cannot match any release
39+
# groups; no release will be made", which is what broke PR #1090.
40+
ref: ${{ github.event.pull_request.merge_commit_sha }}
3641
fetch-depth: 0
3742
token: ${{ secrets.GITHUB_TOKEN }}
3843

44+
- name: Attach to master branch locally
45+
run: git checkout -B master HEAD
46+
3947
- name: Validate hotfix is based on stable
4048
run: |
4149
# Get the stable tag (moving tag that points to latest stable)

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
<!-- version list -->
44

55

6+
## v7.4.1 (2026-05-02)
7+
8+
### Fixed
9+
10+
- **addon**: Propagate `BUILD_VERSION` to runtime so the production add-on
11+
reports the correct version in startup logs instead of the stale value
12+
from `pyproject.toml` at build time
13+
([#1090](https://github.com/homeassistant-ai/ha-mcp/pull/1090)).
14+
- **ci**: Unbreak `hotfix-release.yml` semantic-release run; the previous
15+
detached-HEAD checkout silently no-op'd every hotfix merge
16+
([#1091](https://github.com/homeassistant-ai/ha-mcp/pull/1091)).
17+
18+
619
## v7.4.0 (2026-04-29)
720

821
### Added

homeassistant-addon-dev/DOCS.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,41 @@ The dev add-on uses the same configuration as the stable version. See the main a
1414
|--------|-------------|---------|
1515
| `backup_hint` | Backup strength preference | `normal` |
1616
| `secret_path` | Custom secret path (optional) | auto-generated |
17+
| `enable_skills` | Serve bundled HA best-practice skills as MCP resources | `true` |
18+
| `enable_skills_as_tools` | Expose skills via list_resources/read_resource tools | `true` |
19+
| `enable_tool_search` | Replace full tool catalog with search-based discovery (~46K → ~5K tokens) | `false` |
1720
| `enable_yaml_config_editing` *(beta)* | Enables `ha_config_set_yaml` for editing `configuration.yaml` directly. Requires `ha_mcp_tools` custom component. | `false` |
1821
| `enable_filesystem_tools` *(beta)* | Enables file read/write tools (`ha_list_files`, `ha_read_file`, `ha_write_file`, `ha_delete_file`). Requires `ha_mcp_tools` custom component. | `false` |
1922
| `enable_custom_component_integration` *(beta)* | Enables `ha_install_mcp_tools` installer tool for the `ha_mcp_tools` custom component. | `false` |
23+
| `tool_search_max_results` | Max results from `ha_search_tools` (range 2-10) | `5` |
24+
| `disabled_tools` | Comma-separated list of tool names to disable (seed value; web UI is primary) | empty |
25+
| `pinned_tools` | Comma-separated list of tool names to pin when tool search is enabled (seed value; web UI is primary) | empty |
2026

2127
Beta options are hidden under "Show unused optional configuration options" in the add-on Configuration tab. See [beta.md](https://github.com/homeassistant-ai/ha-mcp/blob/master/docs/beta.md) for details.
2228

29+
## Tool Settings Web UI
30+
31+
The add-on exposes a web-based settings page for managing which tools are available to AI assistants. Click **"Open Web UI"** on the add-on info page to access it.
32+
33+
Features:
34+
- **Enable/disable individual tools** — toggle each tool on or off
35+
- **Pin tools** — keep tools always visible when `enable_tool_search` is on
36+
- **Per-group master toggle** — enable/disable all tools in a group (HACS, System, etc.) with one click
37+
- **Search** — filter tools by name or title
38+
- **Mandatory tools**`ha_search_entities`, `ha_get_overview`, `ha_get_state`, `ha_report_issue` are always enabled and cannot be disabled
39+
- **Feature-gated tools**`ha_config_set_yaml` (requires `enable_yaml_config_editing`), filesystem tools (require `enable_filesystem_tools`), and `ha_install_mcp_tools` (requires `enable_custom_component_integration`) appear in the list with a note if their feature flag is off
40+
- **In-UI restart** — a "Restart Add-on" button appears after saving to apply changes with one click
41+
42+
**Important:** Tool configuration changes require an add-on restart to take effect. The UI will prompt you to restart after saving.
43+
44+
### Non-add-on installations
45+
46+
In Docker (`ha-mcp-web`) and standalone HTTP installations, the settings UI is mounted under your MCP secret path. Open `http://<host>:<port>/<secret_path>/settings` (the same URL prefix that protects your MCP endpoint). This keeps the auth posture consistent — anyone who can reach your MCP endpoint can also use the settings UI; anyone who can't, can't.
47+
48+
### Text-field fallback
49+
50+
If you prefer not to use the web UI (or want to set these before first start), the `disabled_tools` and `pinned_tools` options accept comma-separated tool names as seed values. On first start, the add-on creates `/data/tool_config.json` from these values. After that, the web UI is the source of truth.
51+
2352
## Updates
2453

2554
The dev channel updates automatically with every commit to master. You may receive multiple updates per day.

homeassistant-addon-dev/config.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: "Home Assistant MCP Server (Dev)"
22
description: "Development channel - AI assistant integration via MCP (unstable)"
3-
version: "7.4.0.dev241"
3+
version: "7.4.1.dev246"
44
slug: "ha_mcp_dev"
55
url: "https://github.com/homeassistant-ai/ha-mcp"
66
stage: experimental
@@ -10,6 +10,9 @@ arch:
1010
init: false
1111
startup: application
1212
boot: manual
13+
ingress: true
14+
ingress_port: 9583
15+
ingress_stream: true
1316
hassio_api: true
1417
hassio_role: default
1518
homeassistant_api: true
@@ -21,6 +24,9 @@ options:
2124
enable_skills_as_tools: true
2225
enable_tool_search: false
2326
enable_yaml_config_editing: false
27+
tool_search_max_results: 5
28+
disabled_tools: ""
29+
pinned_tools: ""
2430
schema:
2531
backup_hint: list(strong|normal|weak|auto)
2632
secret_path: str?
@@ -30,5 +36,8 @@ schema:
3036
enable_yaml_config_editing: bool?
3137
enable_filesystem_tools: bool?
3238
enable_custom_component_integration: bool?
39+
tool_search_max_results: int(2,10)?
40+
disabled_tools: str?
41+
pinned_tools: str?
3342
ports:
3443
9583/tcp: 9583

homeassistant-addon-dev/translations/en.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,22 @@ configuration:
5656
required for filesystem tools to function. Only enable if you want to
5757
allow the AI assistant to use the installer tool. Requires restart to
5858
take effect.
59+
tool_search_max_results:
60+
name: Tool search max results
61+
description: >-
62+
Maximum number of tools returned by ha_search_tools when tool
63+
search is enabled. Lower values (2-3) save context tokens but
64+
may miss relevant tools. Range: 2-10. Requires restart.
65+
disabled_tools:
66+
name: Disabled tools (text fallback)
67+
description: >-
68+
Comma-separated tool names to disable. For a visual interface,
69+
click "Open Web UI" on the addon info page. This field seeds the initial config
70+
when the web UI hasn't been used yet. Requires restart.
71+
pinned_tools:
72+
name: Pinned tools (text fallback)
73+
description: >-
74+
Comma-separated tool names to pin (always visible in tool search).
75+
For a visual interface, click "Open Web UI" on the addon info page. This field
76+
seeds the initial config when the web UI hasn't been used yet.
77+
Requires restart.

homeassistant-addon/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
<!-- version list -->
44

55

6+
## v7.4.1 (2026-05-02)
7+
8+
### Fixed
9+
10+
- **addon**: Propagate `BUILD_VERSION` to runtime so the production add-on
11+
reports the correct version in startup logs instead of the stale value
12+
from `pyproject.toml` at build time
13+
([#1090](https://github.com/homeassistant-ai/ha-mcp/pull/1090)).
14+
- **ci**: Unbreak `hotfix-release.yml` semantic-release run; the previous
15+
detached-HEAD checkout silently no-op'd every hotfix merge
16+
([#1091](https://github.com/homeassistant-ai/ha-mcp/pull/1091)).
17+
18+
619
## v7.4.0 (2026-04-29)
720

821
### Added

homeassistant-addon/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: "Home Assistant MCP Server"
22
description: "AI assistant integration for Home Assistant via Model Context Protocol (MCP)"
3-
version: "7.4.0"
3+
version: "7.4.1"
44
slug: "ha_mcp"
55
url: "https://github.com/homeassistant-ai/ha-mcp"
66
arch:

homeassistant-addon/start.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ def main() -> int:
263263
enable_yaml_config_editing = False # default
264264
enable_filesystem_tools = False # default
265265
enable_custom_component_integration = False # default
266+
tool_search_max_results = 5 # default
267+
disabled_tools_raw = "" # default
268+
pinned_tools_raw = "" # default
266269
config_read_ok = True
267270

268271
if config_file.exists():
@@ -283,6 +286,12 @@ def main() -> int:
283286
enable_filesystem_tools = raw_filesystem_tools if isinstance(raw_filesystem_tools, bool) else False
284287
raw_custom_component = config.get("enable_custom_component_integration", False)
285288
enable_custom_component_integration = raw_custom_component if isinstance(raw_custom_component, bool) else False
289+
raw_max_results = config.get("tool_search_max_results", 5)
290+
tool_search_max_results = raw_max_results if isinstance(raw_max_results, int) else 5
291+
raw_disabled = config.get("disabled_tools", "")
292+
disabled_tools_raw = raw_disabled if isinstance(raw_disabled, str) else ""
293+
raw_pinned = config.get("pinned_tools", "")
294+
pinned_tools_raw = raw_pinned if isinstance(raw_pinned, str) else ""
286295
except Exception as e:
287296
log_error(f"Failed to read config: {e}, using defaults")
288297
config_read_ok = False
@@ -323,6 +332,9 @@ def main() -> int:
323332
os.environ["ENABLE_YAML_CONFIG_EDITING"] = str(enable_yaml_config_editing).lower()
324333
os.environ["HAMCP_ENABLE_FILESYSTEM_TOOLS"] = str(enable_filesystem_tools).lower()
325334
os.environ["HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION"] = str(enable_custom_component_integration).lower()
335+
os.environ["TOOL_SEARCH_MAX_RESULTS"] = str(tool_search_max_results)
336+
os.environ["DISABLED_TOOLS"] = disabled_tools_raw
337+
os.environ["PINNED_TOOLS"] = pinned_tools_raw
326338

327339
os.environ["HOMEASSISTANT_TOKEN"] = supervisor_token
328340

@@ -351,12 +363,21 @@ def main() -> int:
351363
log_info("Importing ha_mcp module...")
352364
from ha_mcp.__main__ import (
353365
StatelessSessionLogFilter,
366+
_get_server,
354367
_get_timestamped_uvicorn_log_config,
355368
mcp,
356369
register_browser_landing,
357370
)
371+
from ha_mcp.settings_ui import register_settings_routes
358372

359373
register_browser_landing(mcp, secret_path)
374+
# Mount settings UI routes both at root (for HA ingress proxy) and
375+
# under the secret path (for direct port access). See
376+
# register_settings_routes docstring for the auth model. Use the
377+
# server's actual FastMCP instance (not the _DeferredMCP wrapper)
378+
# so mypy doesn't trip over the duck-typed __getattr__ forwarding.
379+
server_instance = _get_server()
380+
register_settings_routes(server_instance.mcp, server_instance, secret_path=secret_path)
360381
logging.getLogger("mcp.server.streamable_http").addFilter(
361382
StatelessSessionLogFilter()
362383
)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "ha-mcp"
7-
version = "7.4.0"
7+
version = "7.4.1"
88
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
99
readme = "README.md"
1010
requires-python = ">=3.13,<3.14"

0 commit comments

Comments
 (0)