ha-mcp-dev 7.5.0.dev593__tar.gz → 7.5.0.dev594__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.5.0.dev593/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.5.0.dev594}/PKG-INFO +2 -2
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/README.md +1 -1
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/pyproject.toml +1 -1
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/value_sources.py +0 -1
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_code.py +115 -115
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_registry.py +9 -9
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594/src/ha_mcp_dev.egg-info}/PKG-INFO +2 -2
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/LICENSE +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/setup.cfg +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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.5.0.
|
|
3
|
+
Version: 7.5.0.dev594
|
|
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
|
|
@@ -193,7 +193,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
193
193
|
| **Calendar** | `ha_config_get_calendar_events`, `ha_config_remove_calendar_event`, `ha_config_set_calendar_event` |
|
|
194
194
|
| **Camera** | `ha_get_camera_image` |
|
|
195
195
|
| **Dashboards** | `ha_config_delete_dashboard_resource`, `ha_config_delete_dashboard`, `ha_config_get_dashboard`, `ha_config_list_dashboard_resources`, `ha_config_set_dashboard_resource`, `ha_config_set_dashboard` |
|
|
196
|
-
| **Device Registry** | `ha_get_device`, `ha_remove_device`, `
|
|
196
|
+
| **Device Registry** | `ha_get_device`, `ha_remove_device`, `ha_set_device` |
|
|
197
197
|
| **Energy** | `ha_manage_energy_prefs` |
|
|
198
198
|
| **Entity Registry** | `ha_get_entity_exposure`, `ha_get_entity`, `ha_remove_entity`, `ha_set_entity` |
|
|
199
199
|
| **Files** | `ha_delete_file` *(beta)*, `ha_list_files` *(beta)*, `ha_read_file` *(beta)*, `ha_write_file` *(beta)* |
|
|
@@ -163,7 +163,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
163
163
|
| **Calendar** | `ha_config_get_calendar_events`, `ha_config_remove_calendar_event`, `ha_config_set_calendar_event` |
|
|
164
164
|
| **Camera** | `ha_get_camera_image` |
|
|
165
165
|
| **Dashboards** | `ha_config_delete_dashboard_resource`, `ha_config_delete_dashboard`, `ha_config_get_dashboard`, `ha_config_list_dashboard_resources`, `ha_config_set_dashboard_resource`, `ha_config_set_dashboard` |
|
|
166
|
-
| **Device Registry** | `ha_get_device`, `ha_remove_device`, `
|
|
166
|
+
| **Device Registry** | `ha_get_device`, `ha_remove_device`, `ha_set_device` |
|
|
167
167
|
| **Energy** | `ha_manage_energy_prefs` |
|
|
168
168
|
| **Entity Registry** | `ha_get_entity_exposure`, `ha_get_entity`, `ha_remove_entity`, `ha_set_entity` |
|
|
169
169
|
| **Files** | `ha_delete_file` *(beta)*, `ha_list_files` *(beta)*, `ha_read_file` *(beta)*, `ha_write_file` *(beta)* |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.5.0.
|
|
7
|
+
version = "7.5.0.dev594"
|
|
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"
|
|
@@ -39,7 +39,6 @@ VALUE_SOURCE_REGISTRY: dict[tuple[str, str], str] = {
|
|
|
39
39
|
("ha_get_entity", "args.entity_id"): "ha_entities",
|
|
40
40
|
("ha_get_history", "args.entity_ids"): "ha_entities",
|
|
41
41
|
("ha_remove_entity", "args.entity_id"): "ha_entities",
|
|
42
|
-
("ha_update_device", "args.entity_id"): "ha_entities",
|
|
43
42
|
("ha_get_entity_exposure", "args.entity_id"): "ha_entities",
|
|
44
43
|
("ha_set_integration_enabled", "args.entity_id"): "ha_entities",
|
|
45
44
|
}
|
|
@@ -67,13 +67,15 @@ _saved_tools: dict[str, dict[str, str]] = {}
|
|
|
67
67
|
# ``CategorizedSearchTransform`` (excludes pinned tools from category sets
|
|
68
68
|
# when code mode is on); this set is the defense-in-depth that closes the
|
|
69
69
|
# inner-call path even if the proxy is reachable some other way.
|
|
70
|
-
_BLOCKED_TOOLS = frozenset(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
_BLOCKED_TOOLS = frozenset(
|
|
71
|
+
{
|
|
72
|
+
"ha_manage_custom_tool",
|
|
73
|
+
"ha_search_tools",
|
|
74
|
+
"ha_call_read_tool",
|
|
75
|
+
"ha_call_write_tool",
|
|
76
|
+
"ha_call_delete_tool",
|
|
77
|
+
}
|
|
78
|
+
)
|
|
77
79
|
|
|
78
80
|
# Validation for save_as names
|
|
79
81
|
_SAVE_NAME_PATTERN = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$")
|
|
@@ -119,83 +121,87 @@ _API_POST_BLOCKED_PREFIXES: tuple[tuple[str, str, str], ...] = (
|
|
|
119
121
|
# listening for ``state_changed`` / ``automation_reloaded`` / etc. without
|
|
120
122
|
# the real subsystem ever having fired. Custom event types stay allowed —
|
|
121
123
|
# only the names HA Core itself emits are blocked.
|
|
122
|
-
_BLOCKED_HA_INTERNAL_EVENTS: frozenset[str] = frozenset(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
124
|
+
_BLOCKED_HA_INTERNAL_EVENTS: frozenset[str] = frozenset(
|
|
125
|
+
{
|
|
126
|
+
"state_changed",
|
|
127
|
+
"service_registered",
|
|
128
|
+
"service_removed",
|
|
129
|
+
"service_executed",
|
|
130
|
+
"automation_reloaded",
|
|
131
|
+
"script_started",
|
|
132
|
+
"script_finished",
|
|
133
|
+
"homeassistant_start",
|
|
134
|
+
"homeassistant_started",
|
|
135
|
+
"homeassistant_stop",
|
|
136
|
+
"homeassistant_close",
|
|
137
|
+
"homeassistant_final_write",
|
|
138
|
+
"core_config_updated",
|
|
139
|
+
"device_registry_updated",
|
|
140
|
+
"entity_registry_updated",
|
|
141
|
+
"area_registry_updated",
|
|
142
|
+
"category_registry_updated",
|
|
143
|
+
"floor_registry_updated",
|
|
144
|
+
"label_registry_updated",
|
|
145
|
+
# ``logbook_entry`` is the documented logbook write API — the Logbook
|
|
146
|
+
# integration consumes it to render rows. Sandbox code firing this
|
|
147
|
+
# event would inject attacker-fabricated rows directly into the
|
|
148
|
+
# user's primary investigation tool, which is a data-integrity issue.
|
|
149
|
+
"logbook_entry",
|
|
150
|
+
"lovelace_updated",
|
|
151
|
+
"panels_updated",
|
|
152
|
+
"themes_updated",
|
|
153
|
+
"component_loaded",
|
|
154
|
+
"recorder_5min_statistics_generated",
|
|
155
|
+
"recorder_hourly_statistics_generated",
|
|
156
|
+
}
|
|
157
|
+
)
|
|
154
158
|
|
|
155
159
|
# WebSocket commands the sandbox must not send. Each one either changes
|
|
156
160
|
# persistent state in a way that bypasses a wrapping tool's validation
|
|
157
161
|
# (lovelace, registry mutations) or has no sandbox-appropriate use case
|
|
158
162
|
# at all (``config/core/update`` rewrites the HA installation's location/
|
|
159
163
|
# timezone/currency/lat-long).
|
|
160
|
-
_BLOCKED_WS_COMMANDS: frozenset[str] = frozenset(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
164
|
+
_BLOCKED_WS_COMMANDS: frozenset[str] = frozenset(
|
|
165
|
+
{
|
|
166
|
+
"config/core/update",
|
|
167
|
+
"lovelace/config/save",
|
|
168
|
+
"lovelace/dashboards/create",
|
|
169
|
+
"lovelace/dashboards/delete",
|
|
170
|
+
"lovelace/dashboards/update",
|
|
171
|
+
"config/area_registry/delete",
|
|
172
|
+
"config/area_registry/disable",
|
|
173
|
+
"config/area_registry/update",
|
|
174
|
+
"config/device_registry/delete",
|
|
175
|
+
"config/device_registry/disable",
|
|
176
|
+
"config/device_registry/update",
|
|
177
|
+
# Device registry deletion is registered as ``remove_config_entry`` on
|
|
178
|
+
# HA Core, not ``delete`` — see ``tools_registry.py:753`` for the
|
|
179
|
+
# actually-emitted command. ``ha_remove_device`` wraps it; raw
|
|
180
|
+
# ``ws_send`` would skip those checks.
|
|
181
|
+
"config/device_registry/remove_config_entry",
|
|
182
|
+
"config/entity_registry/delete",
|
|
183
|
+
"config/entity_registry/disable",
|
|
184
|
+
"config/entity_registry/update",
|
|
185
|
+
# Entity registry deletion is registered as ``remove`` on HA Core,
|
|
186
|
+
# not ``delete`` — see ``tools_entities.py:1130`` for the
|
|
187
|
+
# actually-emitted command. ``ha_remove_entity`` wraps it.
|
|
188
|
+
"config/entity_registry/remove",
|
|
189
|
+
# Floor / label / category registries follow the same rationale as
|
|
190
|
+
# area / device / entity above: each has a wrapping MCP tool
|
|
191
|
+
# (``ha_set_area_or_floor``, ``ha_config_set_label``,
|
|
192
|
+
# ``ha_config_set_category``) that performs invariant checks the
|
|
193
|
+
# raw WS command skips.
|
|
194
|
+
"config/floor_registry/create",
|
|
195
|
+
"config/floor_registry/delete",
|
|
196
|
+
"config/floor_registry/update",
|
|
197
|
+
"config/label_registry/create",
|
|
198
|
+
"config/label_registry/delete",
|
|
199
|
+
"config/label_registry/update",
|
|
200
|
+
"config/category_registry/create",
|
|
201
|
+
"config/category_registry/delete",
|
|
202
|
+
"config/category_registry/update",
|
|
203
|
+
}
|
|
204
|
+
)
|
|
199
205
|
|
|
200
206
|
|
|
201
207
|
def _classify_sandbox_error(exc: Exception) -> tuple[ErrorCode, str, list[str]]:
|
|
@@ -297,10 +303,8 @@ def _classify_sandbox_error(exc: Exception) -> tuple[ErrorCode, str, list[str]]:
|
|
|
297
303
|
f"Exception type: {exc_type}",
|
|
298
304
|
"Some Python builtins behave differently in Monty (e.g. "
|
|
299
305
|
"next() requires an iterator, not a list).",
|
|
300
|
-
"Check the values you're passing to api_get/api_post/"
|
|
301
|
-
"ws_send/call_tool.",
|
|
302
|
-
"Use 'await' before any call to api_get/api_post/ws_send/"
|
|
303
|
-
"call_tool.",
|
|
306
|
+
"Check the values you're passing to api_get/api_post/ws_send/call_tool.",
|
|
307
|
+
"Use 'await' before any call to api_get/api_post/ws_send/call_tool.",
|
|
304
308
|
],
|
|
305
309
|
)
|
|
306
310
|
|
|
@@ -317,7 +321,7 @@ def _check_api_post_blocked(normalized: str) -> str | None:
|
|
|
317
321
|
if normalized.startswith(prefix) or normalized == prefix.rstrip("/"):
|
|
318
322
|
return f"{what} are blocked from the sandbox; {alternative}."
|
|
319
323
|
if normalized.startswith("events/"):
|
|
320
|
-
event_name = normalized[len("events/"):]
|
|
324
|
+
event_name = normalized[len("events/") :]
|
|
321
325
|
if event_name in _BLOCKED_HA_INTERNAL_EVENTS:
|
|
322
326
|
return (
|
|
323
327
|
f"Firing HA-internal event {event_name!r} from the sandbox "
|
|
@@ -327,6 +331,7 @@ def _check_api_post_blocked(normalized: str) -> str | None:
|
|
|
327
331
|
)
|
|
328
332
|
return None
|
|
329
333
|
|
|
334
|
+
|
|
330
335
|
# Cap on the number of saved tools to prevent runaway growth. A buggy
|
|
331
336
|
# LLM loop could otherwise fill the on-disk file with unique save_as
|
|
332
337
|
# names. Enforced both at load (truncate-with-warning) and at save
|
|
@@ -444,9 +449,7 @@ def _load_saved_tools(path_str: str) -> dict[str, dict[str, str]]:
|
|
|
444
449
|
valid: dict[str, dict[str, str]] = {}
|
|
445
450
|
for name, info in tools_raw.items():
|
|
446
451
|
if not (isinstance(name, str) and _SAVE_NAME_PATTERN.match(name)):
|
|
447
|
-
logger.warning(
|
|
448
|
-
"Skipping saved tool with invalid name %r in %s", name, path
|
|
449
|
-
)
|
|
452
|
+
logger.warning("Skipping saved tool with invalid name %r in %s", name, path)
|
|
450
453
|
continue
|
|
451
454
|
if not isinstance(info, dict):
|
|
452
455
|
logger.warning(
|
|
@@ -477,9 +480,7 @@ def _load_saved_tools(path_str: str) -> dict[str, dict[str, str]]:
|
|
|
477
480
|
return valid
|
|
478
481
|
|
|
479
482
|
|
|
480
|
-
def _save_saved_tools(
|
|
481
|
-
path_str: str, tools: dict[str, dict[str, str]]
|
|
482
|
-
) -> bool:
|
|
483
|
+
def _save_saved_tools(path_str: str, tools: dict[str, dict[str, str]]) -> bool:
|
|
483
484
|
"""Persist the saved-tools cache to a JSON file atomically.
|
|
484
485
|
|
|
485
486
|
Returns ``True`` if persistence succeeded (or was disabled because
|
|
@@ -594,9 +595,7 @@ def _extract_tool_result(result: Any) -> Any:
|
|
|
594
595
|
except (json.JSONDecodeError, TypeError):
|
|
595
596
|
payload = combined
|
|
596
597
|
if is_error:
|
|
597
|
-
message = (
|
|
598
|
-
payload if isinstance(payload, str) else json.dumps(payload)
|
|
599
|
-
)
|
|
598
|
+
message = payload if isinstance(payload, str) else json.dumps(payload)
|
|
600
599
|
return {"error": message}
|
|
601
600
|
return payload
|
|
602
601
|
|
|
@@ -690,9 +689,7 @@ async def _run_sandboxed_code(
|
|
|
690
689
|
)
|
|
691
690
|
first_slash = endpoint.find("/")
|
|
692
691
|
userinfo_marker = endpoint.find("@")
|
|
693
|
-
if userinfo_marker >= 0 and (
|
|
694
|
-
first_slash < 0 or userinfo_marker < first_slash
|
|
695
|
-
):
|
|
692
|
+
if userinfo_marker >= 0 and (first_slash < 0 or userinfo_marker < first_slash):
|
|
696
693
|
raise ValueError("endpoint must not contain userinfo")
|
|
697
694
|
ep = endpoint.lstrip("/")
|
|
698
695
|
if ep.startswith("api/"):
|
|
@@ -716,7 +713,9 @@ async def _run_sandboxed_code(
|
|
|
716
713
|
nonlocal call_count
|
|
717
714
|
call_count += 1
|
|
718
715
|
if call_count > settings.code_mode_max_invocations:
|
|
719
|
-
return {
|
|
716
|
+
return {
|
|
717
|
+
"error": f"API call limit exceeded ({settings.code_mode_max_invocations})"
|
|
718
|
+
}
|
|
720
719
|
try:
|
|
721
720
|
normalized = _normalize_endpoint(endpoint)
|
|
722
721
|
except ValueError as exc:
|
|
@@ -737,7 +736,9 @@ async def _run_sandboxed_code(
|
|
|
737
736
|
nonlocal call_count
|
|
738
737
|
call_count += 1
|
|
739
738
|
if call_count > settings.code_mode_max_invocations:
|
|
740
|
-
return {
|
|
739
|
+
return {
|
|
740
|
+
"error": f"API call limit exceeded ({settings.code_mode_max_invocations})"
|
|
741
|
+
}
|
|
741
742
|
try:
|
|
742
743
|
normalized = _normalize_endpoint(endpoint)
|
|
743
744
|
except ValueError as exc:
|
|
@@ -770,7 +771,9 @@ async def _run_sandboxed_code(
|
|
|
770
771
|
post_kwargs: dict[str, Any] = {}
|
|
771
772
|
if data is not None:
|
|
772
773
|
post_kwargs["json"] = data
|
|
773
|
-
response = await client.httpx_client.request(
|
|
774
|
+
response = await client.httpx_client.request(
|
|
775
|
+
"POST", normalized, **post_kwargs
|
|
776
|
+
)
|
|
774
777
|
try:
|
|
775
778
|
return response.json()
|
|
776
779
|
except json.JSONDecodeError:
|
|
@@ -800,7 +803,9 @@ async def _run_sandboxed_code(
|
|
|
800
803
|
nonlocal call_count
|
|
801
804
|
call_count += 1
|
|
802
805
|
if call_count > settings.code_mode_max_invocations:
|
|
803
|
-
return {
|
|
806
|
+
return {
|
|
807
|
+
"error": f"WebSocket call limit exceeded ({settings.code_mode_max_invocations})"
|
|
808
|
+
}
|
|
804
809
|
if not isinstance(message, dict):
|
|
805
810
|
return {"error": "ws_send(message) requires a dict with a 'type' field"}
|
|
806
811
|
msg_type = message.get("type")
|
|
@@ -813,7 +818,7 @@ async def _run_sandboxed_code(
|
|
|
813
818
|
f"WebSocket command {msg_type!r} is blocked from the "
|
|
814
819
|
"sandbox. Use the corresponding wrapping tool via "
|
|
815
820
|
"call_tool (e.g. ha_config_set_dashboard, "
|
|
816
|
-
"ha_set_area_or_floor,
|
|
821
|
+
"ha_set_area_or_floor, ha_set_device, ha_set_entity) "
|
|
817
822
|
"so validation runs."
|
|
818
823
|
)
|
|
819
824
|
}
|
|
@@ -821,9 +826,7 @@ async def _run_sandboxed_code(
|
|
|
821
826
|
try:
|
|
822
827
|
return await client.send_websocket_message(message)
|
|
823
828
|
except Exception as exc:
|
|
824
|
-
logger.warning(
|
|
825
|
-
"ws_send(type=%r) failed", msg_type, exc_info=True
|
|
826
|
-
)
|
|
829
|
+
logger.warning("ws_send(type=%r) failed", msg_type, exc_info=True)
|
|
827
830
|
return {"error": str(exc)[:200]}
|
|
828
831
|
|
|
829
832
|
async def _call_tool(tool_name: str, arguments: dict[str, Any]) -> Any:
|
|
@@ -855,9 +858,7 @@ async def _run_sandboxed_code(
|
|
|
855
858
|
except (json.JSONDecodeError, TypeError):
|
|
856
859
|
return _sandbox_error(ErrorCode.INTERNAL_ERROR, str(te))
|
|
857
860
|
except Exception as exc:
|
|
858
|
-
logger.warning(
|
|
859
|
-
"call_tool(%r) failed", tool_name, exc_info=True
|
|
860
|
-
)
|
|
861
|
+
logger.warning("call_tool(%r) failed", tool_name, exc_info=True)
|
|
861
862
|
return _sandbox_error(
|
|
862
863
|
ErrorCode.INTERNAL_ERROR,
|
|
863
864
|
f"Tool call failed: {str(exc)[:200]}",
|
|
@@ -894,9 +895,7 @@ async def _run_sandboxed_code(
|
|
|
894
895
|
# entry the LLM already saw "deleted").
|
|
895
896
|
previous = _saved_tools[name]
|
|
896
897
|
del _saved_tools[name]
|
|
897
|
-
if not _save_saved_tools(
|
|
898
|
-
settings.code_mode_saved_tools_path, _saved_tools
|
|
899
|
-
):
|
|
898
|
+
if not _save_saved_tools(settings.code_mode_saved_tools_path, _saved_tools):
|
|
900
899
|
_saved_tools[name] = previous
|
|
901
900
|
return {
|
|
902
901
|
"error": (
|
|
@@ -1077,7 +1076,8 @@ def register_code_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
1077
1076
|
# ``save_as`` and ``justification`` are modifiers for the ``code``
|
|
1078
1077
|
# mode and don't count as a "mode" on their own.
|
|
1079
1078
|
modes_active = sum(
|
|
1080
|
-
1
|
|
1079
|
+
1
|
|
1080
|
+
for v in (
|
|
1081
1081
|
bool(code and code.strip()),
|
|
1082
1082
|
bool(run_saved is not None),
|
|
1083
1083
|
bool(list_saved),
|
|
@@ -1166,7 +1166,10 @@ def register_code_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
1166
1166
|
)
|
|
1167
1167
|
)
|
|
1168
1168
|
|
|
1169
|
-
return {
|
|
1169
|
+
return {
|
|
1170
|
+
"success": True,
|
|
1171
|
+
"data": {"result": result, "saved_tool": run_saved},
|
|
1172
|
+
}
|
|
1170
1173
|
|
|
1171
1174
|
# --- Mode: execute code ---
|
|
1172
1175
|
if not code or not code.strip():
|
|
@@ -1247,10 +1250,7 @@ def register_code_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
1247
1250
|
}
|
|
1248
1251
|
|
|
1249
1252
|
if save_as:
|
|
1250
|
-
if (
|
|
1251
|
-
save_as not in _saved_tools
|
|
1252
|
-
and len(_saved_tools) >= _MAX_SAVED_TOOLS
|
|
1253
|
-
):
|
|
1253
|
+
if save_as not in _saved_tools and len(_saved_tools) >= _MAX_SAVED_TOOLS:
|
|
1254
1254
|
raise_tool_error(
|
|
1255
1255
|
create_error_response(
|
|
1256
1256
|
ErrorCode.VALIDATION_FAILED,
|
|
@@ -593,10 +593,10 @@ def register_registry_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
593
593
|
|
|
594
594
|
@mcp.tool(
|
|
595
595
|
tags={"Device Registry"},
|
|
596
|
-
annotations={"destructiveHint": True, "title": "
|
|
596
|
+
annotations={"destructiveHint": True, "title": "Set Device"},
|
|
597
597
|
)
|
|
598
598
|
@log_tool_usage
|
|
599
|
-
async def
|
|
599
|
+
async def ha_set_device(
|
|
600
600
|
device_id: Annotated[
|
|
601
601
|
str,
|
|
602
602
|
Field(description="Device ID to update"),
|
|
@@ -637,7 +637,7 @@ def register_registry_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
637
637
|
Device and entity names are independent. To rename entities, use ha_set_entity(new_entity_id=...).
|
|
638
638
|
|
|
639
639
|
Common workflow for full rename:
|
|
640
|
-
1.
|
|
640
|
+
1. ha_set_device(device_id="abc", name="Living Room Sensor") # Rename device
|
|
641
641
|
2. ha_set_entity("sensor.old", new_entity_id="sensor.living_room") # Rename entities separately
|
|
642
642
|
|
|
643
643
|
PARAMETERS:
|
|
@@ -647,11 +647,11 @@ def register_registry_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
647
647
|
- labels: List of labels (replaces existing labels)
|
|
648
648
|
|
|
649
649
|
EXAMPLES:
|
|
650
|
-
- Rename device:
|
|
651
|
-
- Move to area:
|
|
652
|
-
- Disable device:
|
|
653
|
-
- Enable device:
|
|
654
|
-
- Add labels:
|
|
650
|
+
- Rename device: ha_set_device("abc123", name="Living Room Hub")
|
|
651
|
+
- Move to area: ha_set_device("abc123", area_id="living_room")
|
|
652
|
+
- Disable device: ha_set_device("abc123", disabled_by="user")
|
|
653
|
+
- Enable device: ha_set_device("abc123", disabled_by="")
|
|
654
|
+
- Add labels: ha_set_device("abc123", labels=["important", "sensor"])
|
|
655
655
|
"""
|
|
656
656
|
# Parse labels if provided as string
|
|
657
657
|
parsed_labels = None
|
|
@@ -717,7 +717,7 @@ def register_registry_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
|
|
|
717
717
|
- Remove orphaned device: ha_remove_device("abc123def456")
|
|
718
718
|
|
|
719
719
|
NOTE: For most use cases, consider disabling the device instead:
|
|
720
|
-
|
|
720
|
+
ha_set_device(device_id="abc123", disabled_by="user")
|
|
721
721
|
"""
|
|
722
722
|
try:
|
|
723
723
|
# Empty/whitespace device_id would slip past the local-filter
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ha-mcp-dev
|
|
3
|
-
Version: 7.5.0.
|
|
3
|
+
Version: 7.5.0.dev594
|
|
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
|
|
@@ -193,7 +193,7 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
193
193
|
| **Calendar** | `ha_config_get_calendar_events`, `ha_config_remove_calendar_event`, `ha_config_set_calendar_event` |
|
|
194
194
|
| **Camera** | `ha_get_camera_image` |
|
|
195
195
|
| **Dashboards** | `ha_config_delete_dashboard_resource`, `ha_config_delete_dashboard`, `ha_config_get_dashboard`, `ha_config_list_dashboard_resources`, `ha_config_set_dashboard_resource`, `ha_config_set_dashboard` |
|
|
196
|
-
| **Device Registry** | `ha_get_device`, `ha_remove_device`, `
|
|
196
|
+
| **Device Registry** | `ha_get_device`, `ha_remove_device`, `ha_set_device` |
|
|
197
197
|
| **Energy** | `ha_manage_energy_prefs` |
|
|
198
198
|
| **Entity Registry** | `ha_get_entity_exposure`, `ha_get_entity`, `ha_remove_entity`, `ha_set_entity` |
|
|
199
199
|
| **Files** | `ha_delete_file` *(beta)*, `ha_list_files` *(beta)*, `ha_read_file` *(beta)*, `ha_write_file` *(beta)* |
|
|
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
|
|
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.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp/transforms/lite_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.5.0.dev593 → ha_mcp_dev-7.5.0.dev594}/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
|