ha-mcp-dev 7.4.1.dev446__tar.gz → 7.4.1.dev447__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ha_mcp_dev-7.4.1.dev446/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.4.1.dev447}/PKG-INFO +4 -4
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/README.md +3 -3
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/pyproject.toml +1 -1
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_resources.py +233 -83
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447/src/ha_mcp_dev.egg-info}/PKG-INFO +4 -4
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/LICENSE +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/setup.cfg +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/tests/test_env_manager.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ha-mcp-dev
|
|
3
|
-
Version: 7.4.1.
|
|
3
|
+
Version: 7.4.1.dev447
|
|
4
4
|
Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
|
|
5
5
|
Author-email: Julien <github@qc-h.net>
|
|
6
6
|
License: MIT
|
|
@@ -38,7 +38,7 @@ Dynamic: license-file
|
|
|
38
38
|
<!-- mcp-name: io.github.homeassistant-ai/ha-mcp -->
|
|
39
39
|
|
|
40
40
|
<p align="center">
|
|
41
|
-
<img src="https://img.shields.io/badge/tools-
|
|
41
|
+
<img src="https://img.shields.io/badge/tools-87-blue" alt="95+ Tools">
|
|
42
42
|
<a href="https://github.com/homeassistant-ai/ha-mcp/releases"><img src="https://img.shields.io/github/v/release/homeassistant-ai/ha-mcp" alt="Release"></a>
|
|
43
43
|
<a href="https://github.com/homeassistant-ai/ha-mcp/actions/workflows/e2e-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/homeassistant-ai/ha-mcp/e2e-tests.yml?branch=master&label=E2E%20Tests" alt="E2E Tests"></a>
|
|
44
44
|
<a href="LICENSE.md"><img src="https://img.shields.io/github/license/homeassistant-ai/ha-mcp.svg" alt="License"></a>
|
|
@@ -181,7 +181,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
181
181
|
<details>
|
|
182
182
|
<!-- TOOLS_TABLE_START -->
|
|
183
183
|
|
|
184
|
-
<summary><b>Complete Tool List (
|
|
184
|
+
<summary><b>Complete Tool List (87 tools)</b></summary>
|
|
185
185
|
|
|
186
186
|
| Category | Tools |
|
|
187
187
|
|----------|-------|
|
|
@@ -205,7 +205,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
205
205
|
| **Scripts** | `ha_config_get_script`, `ha_config_remove_script`, `ha_config_set_script` |
|
|
206
206
|
| **Search & Discovery** | `ha_deep_search`, `ha_get_overview`, `ha_get_state`, `ha_search_entities` |
|
|
207
207
|
| **Service & Device Control** | `ha_bulk_control`, `ha_call_service`, `ha_get_operation_status`, `ha_list_services` |
|
|
208
|
-
| **System** | `ha_backup_create`, `ha_backup_restore`, `ha_check_config`, `ha_config_set_yaml` *(beta)*, `ha_get_system_health`, `ha_get_updates`, `ha_reload_core`, `ha_restart` |
|
|
208
|
+
| **System** | `ha_backup_create`, `ha_backup_restore`, `ha_check_config`, `ha_config_set_yaml` *(beta)*, `ha_get_system_health`, `ha_get_updates`, `ha_manage_custom_tool` *(beta)*, `ha_reload_core`, `ha_restart` |
|
|
209
209
|
| **Todo Lists** | `ha_get_todo`, `ha_remove_todo_item`, `ha_set_todo_item` |
|
|
210
210
|
| **Utilities** | `ha_eval_template`, `ha_install_mcp_tools` *(beta)*, `ha_report_issue` |
|
|
211
211
|
| **Zones** | `ha_get_zone`, `ha_remove_zone`, `ha_set_zone` |
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<!-- mcp-name: io.github.homeassistant-ai/ha-mcp -->
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<img src="https://img.shields.io/badge/tools-
|
|
11
|
+
<img src="https://img.shields.io/badge/tools-87-blue" alt="95+ Tools">
|
|
12
12
|
<a href="https://github.com/homeassistant-ai/ha-mcp/releases"><img src="https://img.shields.io/github/v/release/homeassistant-ai/ha-mcp" alt="Release"></a>
|
|
13
13
|
<a href="https://github.com/homeassistant-ai/ha-mcp/actions/workflows/e2e-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/homeassistant-ai/ha-mcp/e2e-tests.yml?branch=master&label=E2E%20Tests" alt="E2E Tests"></a>
|
|
14
14
|
<a href="LICENSE.md"><img src="https://img.shields.io/github/license/homeassistant-ai/ha-mcp.svg" alt="License"></a>
|
|
@@ -151,7 +151,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
151
151
|
<details>
|
|
152
152
|
<!-- TOOLS_TABLE_START -->
|
|
153
153
|
|
|
154
|
-
<summary><b>Complete Tool List (
|
|
154
|
+
<summary><b>Complete Tool List (87 tools)</b></summary>
|
|
155
155
|
|
|
156
156
|
| Category | Tools |
|
|
157
157
|
|----------|-------|
|
|
@@ -175,7 +175,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
175
175
|
| **Scripts** | `ha_config_get_script`, `ha_config_remove_script`, `ha_config_set_script` |
|
|
176
176
|
| **Search & Discovery** | `ha_deep_search`, `ha_get_overview`, `ha_get_state`, `ha_search_entities` |
|
|
177
177
|
| **Service & Device Control** | `ha_bulk_control`, `ha_call_service`, `ha_get_operation_status`, `ha_list_services` |
|
|
178
|
-
| **System** | `ha_backup_create`, `ha_backup_restore`, `ha_check_config`, `ha_config_set_yaml` *(beta)*, `ha_get_system_health`, `ha_get_updates`, `ha_reload_core`, `ha_restart` |
|
|
178
|
+
| **System** | `ha_backup_create`, `ha_backup_restore`, `ha_check_config`, `ha_config_set_yaml` *(beta)*, `ha_get_system_health`, `ha_get_updates`, `ha_manage_custom_tool` *(beta)*, `ha_reload_core`, `ha_restart` |
|
|
179
179
|
| **Todo Lists** | `ha_get_todo`, `ha_remove_todo_item`, `ha_set_todo_item` |
|
|
180
180
|
| **Utilities** | `ha_eval_template`, `ha_install_mcp_tools` *(beta)*, `ha_report_issue` |
|
|
181
181
|
| **Zones** | `ha_get_zone`, `ha_remove_zone`, `ha_set_zone` |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.4.1.
|
|
7
|
+
version = "7.4.1.dev447"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
|
@@ -36,6 +36,79 @@ MAX_ENCODED_LENGTH = 32000
|
|
|
36
36
|
# Base64 encoding increases size by ~33%, so 24KB * 1.33 ≈ 32KB
|
|
37
37
|
MAX_CONTENT_SIZE = 24000
|
|
38
38
|
|
|
39
|
+
# Top-level HA-config YAML keys that LLMs sometimes emit when they pick this
|
|
40
|
+
# tool (`ha_config_set_dashboard_resource`) to "create a scene/automation/...".
|
|
41
|
+
# This tool only stores Lovelace JS/CSS resources — the YAML payload would land
|
|
42
|
+
# as a Lovelace module, creating orphaned, unreachable HA entities (see #1072).
|
|
43
|
+
# Map: top-level key → suggested replacement tool (None where no direct tool
|
|
44
|
+
# exists yet — e.g. scenes are tracked in #995).
|
|
45
|
+
_HA_CONFIG_YAML_MARKERS: dict[str, str | None] = {
|
|
46
|
+
"automation": "ha_config_set_automation",
|
|
47
|
+
"script": "ha_config_set_script",
|
|
48
|
+
"scene": None, # Tracked in #995 — scene CRUD tools not yet shipped
|
|
49
|
+
"group": "ha_config_set_group",
|
|
50
|
+
"input_boolean": "ha_config_set_helper(helper_type='input_boolean', ...)",
|
|
51
|
+
"input_number": "ha_config_set_helper(helper_type='input_number', ...)",
|
|
52
|
+
"input_select": "ha_config_set_helper(helper_type='input_select', ...)",
|
|
53
|
+
"input_text": "ha_config_set_helper(helper_type='input_text', ...)",
|
|
54
|
+
"input_datetime": "ha_config_set_helper(helper_type='input_datetime', ...)",
|
|
55
|
+
"input_button": "ha_config_set_helper(helper_type='input_button', ...)",
|
|
56
|
+
"template": None,
|
|
57
|
+
"homeassistant": None,
|
|
58
|
+
"sensor": None,
|
|
59
|
+
"binary_sensor": None,
|
|
60
|
+
"light": None,
|
|
61
|
+
"switch": None,
|
|
62
|
+
"cover": None,
|
|
63
|
+
"climate": None,
|
|
64
|
+
"media_player": None,
|
|
65
|
+
"notify": None,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _detect_ha_config_yaml(content: str) -> str | None:
|
|
70
|
+
"""Detect HA-config YAML at the start of inline-resource content.
|
|
71
|
+
|
|
72
|
+
Returns the matching top-level key (without the colon) when content's
|
|
73
|
+
first significant line opens an HA-config block, else None. Plain JS/CSS
|
|
74
|
+
never starts with ``<word>:`` followed by whitespace/EOL/YAML-marker —
|
|
75
|
+
JS opens with ``import``/``export``/``const``/``//``/``/*``/``function``
|
|
76
|
+
or similar, CSS with selectors/at-rules/``/*``. False-positive surface
|
|
77
|
+
is therefore narrow.
|
|
78
|
+
|
|
79
|
+
Skips a leading BOM (``\\ufeff``), blank lines, full-line ``#`` comments,
|
|
80
|
+
and YAML doc-start markers (``---``) before reading the first content
|
|
81
|
+
line — these decorations are common in real-world HA YAML files and
|
|
82
|
+
would otherwise let misrouted content slip past the first-line check.
|
|
83
|
+
|
|
84
|
+
See #1072 for the misroute pattern this guards against.
|
|
85
|
+
"""
|
|
86
|
+
# `str.strip()` does not remove U+FEFF (BOM) — it is not Unicode-whitespace.
|
|
87
|
+
stripped = content.lstrip("\ufeff")
|
|
88
|
+
first_line = ""
|
|
89
|
+
for raw_line in stripped.splitlines():
|
|
90
|
+
bare = raw_line.strip()
|
|
91
|
+
if not bare or bare == "---" or bare.startswith("#"):
|
|
92
|
+
continue
|
|
93
|
+
first_line = bare
|
|
94
|
+
break
|
|
95
|
+
if not first_line:
|
|
96
|
+
return None
|
|
97
|
+
for domain in _HA_CONFIG_YAML_MARKERS:
|
|
98
|
+
prefix = f"{domain}:"
|
|
99
|
+
if first_line == prefix:
|
|
100
|
+
# Block-form `automation:` exactly — unambiguous.
|
|
101
|
+
return domain
|
|
102
|
+
if first_line.startswith(prefix):
|
|
103
|
+
# `automation: <something>` — only count it as YAML if the char
|
|
104
|
+
# after the colon is whitespace, EOL, or a YAML marker. CSS
|
|
105
|
+
# selectors like `automation:hover` (hypothetical) would have
|
|
106
|
+
# an alpha char after the colon and not match.
|
|
107
|
+
sep = first_line[len(prefix)]
|
|
108
|
+
if sep in (" ", "\t", "|", ">", "-", "[", "{", "#"):
|
|
109
|
+
return domain
|
|
110
|
+
return None
|
|
111
|
+
|
|
39
112
|
|
|
40
113
|
def _encode_content(content: str) -> tuple[str, int, int]:
|
|
41
114
|
"""Encode content to URL-safe base64. Returns (encoded, content_size, encoded_size)."""
|
|
@@ -113,7 +186,9 @@ class ResourceTools:
|
|
|
113
186
|
management through the UI, but API access works regardless.
|
|
114
187
|
"""
|
|
115
188
|
try:
|
|
116
|
-
result = await self._client.send_websocket_message(
|
|
189
|
+
result = await self._client.send_websocket_message(
|
|
190
|
+
{"type": "lovelace/resources"}
|
|
191
|
+
)
|
|
117
192
|
|
|
118
193
|
# Handle WebSocket response format
|
|
119
194
|
if isinstance(result, dict) and "result" in result:
|
|
@@ -270,24 +345,28 @@ class ResourceTools:
|
|
|
270
345
|
"""
|
|
271
346
|
# Validate: exactly one of content or url must be provided
|
|
272
347
|
if content is not None and url is not None:
|
|
273
|
-
raise_tool_error(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
348
|
+
raise_tool_error(
|
|
349
|
+
create_error_response(
|
|
350
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
351
|
+
message="Provide either 'content' (inline code) or 'url' (external), not both",
|
|
352
|
+
suggestions=[
|
|
353
|
+
"Use content= for inline JavaScript/CSS code",
|
|
354
|
+
"Use url= for /local/, /hacsfiles/, or https:// resources",
|
|
355
|
+
],
|
|
356
|
+
)
|
|
357
|
+
)
|
|
281
358
|
|
|
282
359
|
if content is None and url is None:
|
|
283
|
-
raise_tool_error(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
360
|
+
raise_tool_error(
|
|
361
|
+
create_error_response(
|
|
362
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
363
|
+
message="Either 'content' (inline code) or 'url' (external) is required",
|
|
364
|
+
suggestions=[
|
|
365
|
+
"Use content= for inline JavaScript/CSS code",
|
|
366
|
+
"Use url= for /local/, /hacsfiles/, or https:// resources",
|
|
367
|
+
],
|
|
368
|
+
)
|
|
369
|
+
)
|
|
291
370
|
|
|
292
371
|
if content is not None:
|
|
293
372
|
return await self._set_inline_resource(content, resource_type, resource_id)
|
|
@@ -301,57 +380,111 @@ class ResourceTools:
|
|
|
301
380
|
) -> dict[str, Any]:
|
|
302
381
|
"""Create or update an inline dashboard resource."""
|
|
303
382
|
if not content.strip():
|
|
304
|
-
raise_tool_error(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
383
|
+
raise_tool_error(
|
|
384
|
+
create_error_response(
|
|
385
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
386
|
+
message="Content cannot be empty",
|
|
387
|
+
)
|
|
388
|
+
)
|
|
308
389
|
|
|
309
390
|
if resource_type == "js":
|
|
310
|
-
raise_tool_error(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
391
|
+
raise_tool_error(
|
|
392
|
+
create_error_response(
|
|
393
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
394
|
+
message="Inline content does not support resource_type='js'",
|
|
395
|
+
suggestions=[
|
|
396
|
+
"Use resource_type='module' for ES6 JavaScript (recommended)",
|
|
397
|
+
"Use url= mode with resource_type='js' for legacy files",
|
|
398
|
+
],
|
|
399
|
+
)
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
# Catch the misroute where LLMs pick this tool to create a scene /
|
|
403
|
+
# automation / helper / ... by passing HA-config YAML as `content`.
|
|
404
|
+
# The tool only stores Lovelace JS/CSS — YAML lands as a Lovelace
|
|
405
|
+
# module, creating orphaned, unreachable entities. See #1072.
|
|
406
|
+
detected_yaml = _detect_ha_config_yaml(content)
|
|
407
|
+
if detected_yaml is not None:
|
|
408
|
+
right_tool = _HA_CONFIG_YAML_MARKERS[detected_yaml]
|
|
409
|
+
suggestions = ["This tool stores Lovelace JavaScript/CSS resources only"]
|
|
410
|
+
if right_tool:
|
|
411
|
+
suggestions.insert(
|
|
412
|
+
0,
|
|
413
|
+
f"For `{detected_yaml}:` configuration, use {right_tool} instead",
|
|
414
|
+
)
|
|
415
|
+
elif detected_yaml == "scene":
|
|
416
|
+
suggestions.insert(
|
|
417
|
+
0,
|
|
418
|
+
"Scene configuration tools are tracked in #995; "
|
|
419
|
+
"until they ship, scenes can only be created via the HA UI",
|
|
420
|
+
)
|
|
421
|
+
else:
|
|
422
|
+
suggestions.insert(
|
|
423
|
+
0,
|
|
424
|
+
f"No direct tool exists for `{detected_yaml}:` config; "
|
|
425
|
+
"configure it via the HA UI or YAML packages",
|
|
426
|
+
)
|
|
427
|
+
raise_tool_error(
|
|
428
|
+
create_error_response(
|
|
429
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
430
|
+
message=(
|
|
431
|
+
f"Content starts with HA-configuration YAML "
|
|
432
|
+
f"(`{detected_yaml}:`) — this tool only accepts Lovelace "
|
|
433
|
+
f"JavaScript or CSS resources, not Home Assistant config "
|
|
434
|
+
f"(see issue #1072)."
|
|
435
|
+
),
|
|
436
|
+
context={
|
|
437
|
+
"detected_marker": f"{detected_yaml}:",
|
|
438
|
+
"resource_type": resource_type,
|
|
439
|
+
},
|
|
440
|
+
suggestions=suggestions,
|
|
441
|
+
)
|
|
442
|
+
)
|
|
318
443
|
|
|
319
444
|
content_bytes = content.encode("utf-8")
|
|
320
445
|
content_size = len(content_bytes)
|
|
321
446
|
|
|
322
447
|
if content_size > MAX_CONTENT_SIZE:
|
|
323
|
-
raise_tool_error(
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
448
|
+
raise_tool_error(
|
|
449
|
+
create_error_response(
|
|
450
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
451
|
+
message=f"Content too large: {content_size:,} bytes (max {MAX_CONTENT_SIZE:,})",
|
|
452
|
+
context={"size": content_size},
|
|
453
|
+
suggestions=[
|
|
454
|
+
"Minify the code to reduce size",
|
|
455
|
+
"Split into multiple smaller modules",
|
|
456
|
+
"Use url= with a /local/ path for larger files",
|
|
457
|
+
],
|
|
458
|
+
)
|
|
459
|
+
)
|
|
333
460
|
|
|
334
461
|
encoded, _, encoded_size = _encode_content(content)
|
|
335
462
|
|
|
336
463
|
if encoded_size > MAX_ENCODED_LENGTH:
|
|
337
|
-
raise_tool_error(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
464
|
+
raise_tool_error(
|
|
465
|
+
create_error_response(
|
|
466
|
+
code=ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
467
|
+
message=f"Encoded content too large: {encoded_size:,} chars (max {MAX_ENCODED_LENGTH:,})",
|
|
468
|
+
context={"size": content_size},
|
|
469
|
+
)
|
|
470
|
+
)
|
|
342
471
|
|
|
343
472
|
resource_url = f"{WORKER_BASE_URL}/{encoded}?type={resource_type}"
|
|
344
473
|
|
|
345
474
|
try:
|
|
346
|
-
result, action = await self._upsert_resource(
|
|
475
|
+
result, action = await self._upsert_resource(
|
|
476
|
+
resource_id, resource_url, resource_type
|
|
477
|
+
)
|
|
347
478
|
|
|
348
479
|
error_msg = _check_ws_error(result)
|
|
349
480
|
if error_msg:
|
|
350
|
-
raise_tool_error(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
481
|
+
raise_tool_error(
|
|
482
|
+
create_error_response(
|
|
483
|
+
code=ErrorCode.SERVICE_CALL_FAILED,
|
|
484
|
+
message=str(error_msg),
|
|
485
|
+
context={"action": action},
|
|
486
|
+
)
|
|
487
|
+
)
|
|
355
488
|
|
|
356
489
|
new_resource_id = _extract_resource_id(result, resource_id)
|
|
357
490
|
|
|
@@ -374,7 +507,10 @@ class ResourceTools:
|
|
|
374
507
|
logger.error(f"Error setting inline dashboard resource: {e}")
|
|
375
508
|
exception_to_structured_error(
|
|
376
509
|
e,
|
|
377
|
-
context={
|
|
510
|
+
context={
|
|
511
|
+
"tool": "ha_config_set_dashboard_resource",
|
|
512
|
+
"action": "update" if resource_id else "create",
|
|
513
|
+
},
|
|
378
514
|
suggestions=[
|
|
379
515
|
"Ensure Home Assistant is running and accessible",
|
|
380
516
|
"Check that you have admin permissions",
|
|
@@ -389,26 +525,32 @@ class ResourceTools:
|
|
|
389
525
|
) -> dict[str, Any]:
|
|
390
526
|
"""Create or update an external URL dashboard resource."""
|
|
391
527
|
try:
|
|
392
|
-
result, action = await self._upsert_resource(
|
|
528
|
+
result, action = await self._upsert_resource(
|
|
529
|
+
resource_id, url, resource_type
|
|
530
|
+
)
|
|
393
531
|
|
|
394
532
|
error_msg = _check_ws_error(result)
|
|
395
533
|
if error_msg:
|
|
396
534
|
error_str = str(error_msg).lower()
|
|
397
535
|
if "already exists" in error_str or "duplicate" in error_str:
|
|
398
|
-
raise_tool_error(
|
|
536
|
+
raise_tool_error(
|
|
537
|
+
create_error_response(
|
|
538
|
+
code=ErrorCode.SERVICE_CALL_FAILED,
|
|
539
|
+
message="Resource with this URL already exists",
|
|
540
|
+
context={"action": action, "url": url},
|
|
541
|
+
suggestions=[
|
|
542
|
+
"Use ha_config_list_dashboard_resources() to find existing resource",
|
|
543
|
+
"Provide resource_id to update the existing resource",
|
|
544
|
+
],
|
|
545
|
+
)
|
|
546
|
+
)
|
|
547
|
+
raise_tool_error(
|
|
548
|
+
create_error_response(
|
|
399
549
|
code=ErrorCode.SERVICE_CALL_FAILED,
|
|
400
|
-
message=
|
|
550
|
+
message=str(error_msg),
|
|
401
551
|
context={"action": action, "url": url},
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
"Provide resource_id to update the existing resource",
|
|
405
|
-
],
|
|
406
|
-
))
|
|
407
|
-
raise_tool_error(create_error_response(
|
|
408
|
-
code=ErrorCode.SERVICE_CALL_FAILED,
|
|
409
|
-
message=str(error_msg),
|
|
410
|
-
context={"action": action, "url": url},
|
|
411
|
-
))
|
|
552
|
+
)
|
|
553
|
+
)
|
|
412
554
|
|
|
413
555
|
new_resource_id = _extract_resource_id(result, resource_id)
|
|
414
556
|
|
|
@@ -431,7 +573,11 @@ class ResourceTools:
|
|
|
431
573
|
logger.error(f"Error setting dashboard resource: {e}")
|
|
432
574
|
exception_to_structured_error(
|
|
433
575
|
e,
|
|
434
|
-
context={
|
|
576
|
+
context={
|
|
577
|
+
"tool": "ha_config_set_dashboard_resource",
|
|
578
|
+
"action": "update" if resource_id else "create",
|
|
579
|
+
"url": url,
|
|
580
|
+
},
|
|
435
581
|
suggestions=[
|
|
436
582
|
"Ensure Home Assistant is running and accessible",
|
|
437
583
|
"Check that you have admin permissions",
|
|
@@ -512,24 +658,28 @@ class ResourceTools:
|
|
|
512
658
|
if error_msg:
|
|
513
659
|
error_str = str(error_msg).lower()
|
|
514
660
|
if "not found" in error_str or "unable to find" in error_str:
|
|
515
|
-
raise_tool_error(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
"
|
|
530
|
-
"
|
|
531
|
-
|
|
532
|
-
|
|
661
|
+
raise_tool_error(
|
|
662
|
+
create_resource_not_found_error(
|
|
663
|
+
"Dashboard resource",
|
|
664
|
+
resource_id,
|
|
665
|
+
details=(
|
|
666
|
+
f"Resource '{resource_id}' not found. "
|
|
667
|
+
"Use ha_config_list_dashboard_resources() to see available resources."
|
|
668
|
+
),
|
|
669
|
+
)
|
|
670
|
+
)
|
|
671
|
+
|
|
672
|
+
raise_tool_error(
|
|
673
|
+
create_error_response(
|
|
674
|
+
code=ErrorCode.SERVICE_CALL_FAILED,
|
|
675
|
+
message=f"Failed to delete dashboard resource: {error_msg}",
|
|
676
|
+
context={"action": "delete", "resource_id": resource_id},
|
|
677
|
+
suggestions=[
|
|
678
|
+
"Verify resource ID using ha_config_list_dashboard_resources()",
|
|
679
|
+
"Check that you have admin permissions",
|
|
680
|
+
],
|
|
681
|
+
)
|
|
682
|
+
)
|
|
533
683
|
|
|
534
684
|
logger.info(f"Dashboard resource deleted: id={resource_id}")
|
|
535
685
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ha-mcp-dev
|
|
3
|
-
Version: 7.4.1.
|
|
3
|
+
Version: 7.4.1.dev447
|
|
4
4
|
Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
|
|
5
5
|
Author-email: Julien <github@qc-h.net>
|
|
6
6
|
License: MIT
|
|
@@ -38,7 +38,7 @@ Dynamic: license-file
|
|
|
38
38
|
<!-- mcp-name: io.github.homeassistant-ai/ha-mcp -->
|
|
39
39
|
|
|
40
40
|
<p align="center">
|
|
41
|
-
<img src="https://img.shields.io/badge/tools-
|
|
41
|
+
<img src="https://img.shields.io/badge/tools-87-blue" alt="95+ Tools">
|
|
42
42
|
<a href="https://github.com/homeassistant-ai/ha-mcp/releases"><img src="https://img.shields.io/github/v/release/homeassistant-ai/ha-mcp" alt="Release"></a>
|
|
43
43
|
<a href="https://github.com/homeassistant-ai/ha-mcp/actions/workflows/e2e-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/homeassistant-ai/ha-mcp/e2e-tests.yml?branch=master&label=E2E%20Tests" alt="E2E Tests"></a>
|
|
44
44
|
<a href="LICENSE.md"><img src="https://img.shields.io/github/license/homeassistant-ai/ha-mcp.svg" alt="License"></a>
|
|
@@ -181,7 +181,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
181
181
|
<details>
|
|
182
182
|
<!-- TOOLS_TABLE_START -->
|
|
183
183
|
|
|
184
|
-
<summary><b>Complete Tool List (
|
|
184
|
+
<summary><b>Complete Tool List (87 tools)</b></summary>
|
|
185
185
|
|
|
186
186
|
| Category | Tools |
|
|
187
187
|
|----------|-------|
|
|
@@ -205,7 +205,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
205
205
|
| **Scripts** | `ha_config_get_script`, `ha_config_remove_script`, `ha_config_set_script` |
|
|
206
206
|
| **Search & Discovery** | `ha_deep_search`, `ha_get_overview`, `ha_get_state`, `ha_search_entities` |
|
|
207
207
|
| **Service & Device Control** | `ha_bulk_control`, `ha_call_service`, `ha_get_operation_status`, `ha_list_services` |
|
|
208
|
-
| **System** | `ha_backup_create`, `ha_backup_restore`, `ha_check_config`, `ha_config_set_yaml` *(beta)*, `ha_get_system_health`, `ha_get_updates`, `ha_reload_core`, `ha_restart` |
|
|
208
|
+
| **System** | `ha_backup_create`, `ha_backup_restore`, `ha_check_config`, `ha_config_set_yaml` *(beta)*, `ha_get_system_health`, `ha_get_updates`, `ha_manage_custom_tool` *(beta)*, `ha_reload_core`, `ha_restart` |
|
|
209
209
|
| **Todo Lists** | `ha_get_todo`, `ha_remove_todo_item`, `ha_set_todo_item` |
|
|
210
210
|
| **Utilities** | `ha_eval_template`, `ha_install_mcp_tools` *(beta)*, `ha_report_issue` |
|
|
211
211
|
| **Zones** | `ha_get_zone`, `ha_remove_zone`, `ha_set_zone` |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/resources/skills-vendor/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/best_practice_checker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev446 → ha_mcp_dev-7.4.1.dev447}/src/ha_mcp_dev.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|