ha-mcp-dev 7.12.3.dev1937__tar.gz → 7.12.3.dev1942__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.12.3.dev1937/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.12.3.dev1942}/PKG-INFO +9 -8
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/README.md +8 -7
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/pyproject.toml +1 -1
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/config.py +3 -17
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/server.py +11 -11
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_tools_meta.py +1 -9
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/settings.js +0 -4
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_bug_report.py +3 -5
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_config_helpers.py +112 -8
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_dev.py +2 -1
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_filesystem.py +16 -5
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_groups.py +42 -10
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_hacs.py +10 -22
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_resources.py +30 -5
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942/src/ha_mcp_dev.egg-info}/PKG-INFO +9 -8
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -1
- ha_mcp_dev-7.12.3.dev1937/src/ha_mcp/tools/tools_mcp_component.py +0 -410
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/LICENSE +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/setup.cfg +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/browser_landing.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/llm_exposure.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_persistence.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_theme.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/strict_bps.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/component_api.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/transport_security.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/visibility/resolver.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/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.12.3.
|
|
3
|
+
Version: 7.12.3.dev1942
|
|
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
|
|
@@ -83,12 +83,13 @@ The recommended way to run ha-mcp is the **HA-MCP Custom Component**. It install
|
|
|
83
83
|
|
|
84
84
|
**Connect URL.** The Configure screen gives you a Home Assistant webhook URL for remote clients — `https://<your-ha-domain>/api/webhook/<webhook-id>` through Nabu Casa or any reverse proxy already pointed at Home Assistant (locally, `http://<ha-host>:8123/api/webhook/<webhook-id>`). For clients on the same network, the server is also reachable directly at `http://<ha-ip>:9584/private_<random>`.
|
|
85
85
|
|
|
86
|
+
- **Replaces other install methods:** the in-process server is a complete, standalone ha-mcp install — it takes the place of the add-on, Docker, and uvx/PyPI (stdio) methods. Run only one; do not run the in-process server alongside another install.
|
|
86
87
|
- **Local only?** Turn off **Remote access via webhook** in the entry options — no webhook is registered at all, while the direct port and sidebar panel keep working.
|
|
87
88
|
- **Settings panel:** while the server runs, an admin-only **HA-MCP** panel appears in the Home Assistant sidebar for managing tools, feature flags, backups, and themes.
|
|
88
89
|
- **Optional authentication:** set **Webhook authentication** to `ha_auth` to require a Home Assistant account sign-in instead of using the secret URL as the credential.
|
|
89
90
|
- **Manual install (no HACS):** copy `custom_components/ha_mcp_tools/` from this repository into your Home Assistant `config/custom_components/` directory, then restart and add the integration as above.
|
|
90
91
|
|
|
91
|
-
The component's second entry type, **HA
|
|
92
|
+
The component's second entry type, the **File & YAML services entry** (**HA-MCP File & YAML Tools**), is only needed if you enable ha-mcp's opt-in file and YAML editing tools (feature flags, off by default) — skip it otherwise; you can add it later at any time. It works with any server type (in-process, add-on, Docker, or stdio).
|
|
92
93
|
|
|
93
94
|
[Full in-process server documentation →](docs/in-process-server.md) · [Setup Wizard for client-specific config →](https://homeassistant-ai.github.io/ha-mcp/setup/)
|
|
94
95
|
|
|
@@ -275,9 +276,9 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
275
276
|
| **Scripts** | `ha_config_get_script`, `ha_config_remove_script`, `ha_config_set_script` |
|
|
276
277
|
| **Search & Discovery** | `ha_get_overview`, `ha_get_state`, `ha_search` |
|
|
277
278
|
| **Service & Device Control** | `ha_bulk_control`, `ha_call_event`, `ha_call_service`, `ha_get_operation_status`, `ha_list_services` |
|
|
278
|
-
| **System** | `ha_config_set_yaml` *(beta)*, `ha_manage_backup`, `ha_manage_custom_tool` *(beta)*, `ha_manage_theme`, `ha_manage_updates`, `ha_reload_core`, `ha_restart` |
|
|
279
|
+
| **System** | `ha_config_get_yaml` *(beta)*, `ha_config_set_yaml` *(beta)*, `ha_manage_backup`, `ha_manage_custom_tool` *(beta)*, `ha_manage_theme`, `ha_manage_updates`, `ha_reload_core`, `ha_restart` |
|
|
279
280
|
| **Todo Lists** | `ha_get_todo`, `ha_remove_todo_item`, `ha_set_todo_item` |
|
|
280
|
-
| **Utilities** | `ha_eval_template`, `
|
|
281
|
+
| **Utilities** | `ha_eval_template`, `ha_report_issue` |
|
|
281
282
|
| **Zones** | `ha_get_zone`, `ha_remove_zone`, `ha_set_zone` |
|
|
282
283
|
|
|
283
284
|
<!-- TOOLS_TABLE_END -->
|
|
@@ -307,7 +308,7 @@ ha-mcp is a standalone server built for **configuring, building, and debugging**
|
|
|
307
308
|
|
|
308
309
|
## 🔌 Custom Component (ha_mcp_tools) — File & YAML Services
|
|
309
310
|
|
|
310
|
-
The **HA-MCP Custom Component** also powers a set of privileged tools that standard Home Assistant APIs can't provide: file system access and YAML config editing. (The same component runs the full server in-process — that's the recommended install in the **Get Started** section at the top.) Its **
|
|
311
|
+
The **HA-MCP Custom Component** also powers a set of privileged tools that standard Home Assistant APIs can't provide: file system access and YAML config editing. (The same component runs the full server in-process — that's the recommended install in the **Get Started** section at the top.) Its **File & YAML services entry** (**HA-MCP File & YAML Tools**) enables the tools below.
|
|
311
312
|
|
|
312
313
|
**Tools that require the component:**
|
|
313
314
|
|
|
@@ -325,13 +326,13 @@ These tools also require beta feature flags. See **[Beta Features](docs/beta.md)
|
|
|
325
326
|
|
|
326
327
|
### Install
|
|
327
328
|
|
|
328
|
-
Install the **HA
|
|
329
|
+
Install the **HA-MCP File & YAML Tools** entry from the same **HA-MCP Custom Component**:
|
|
329
330
|
|
|
330
331
|
[](https://my.home-assistant.io/redirect/hacs_repository/?owner=homeassistant-ai&repository=ha-mcp-integration&category=integration)
|
|
331
332
|
|
|
332
333
|
To add manually: open **HACS** > **Integrations** > three-dot menu > **Custom repositories** > add `https://github.com/homeassistant-ai/ha-mcp-integration` (category: Integration) > **Download**. Or copy `custom_components/ha_mcp_tools/` from this repository into your HA `config/custom_components/` directory.
|
|
333
334
|
|
|
334
|
-
After installing, restart Home Assistant, then open **Settings** > **Devices & Services** > **Add Integration**, search for **HA-MCP Custom Component**, and add the **HA
|
|
335
|
+
After installing, restart Home Assistant, then open **Settings** > **Devices & Services** > **Add Integration**, search for **HA-MCP Custom Component**, and add the **HA-MCP File & YAML Tools** entry.
|
|
335
336
|
|
|
336
337
|
To run the full ha-mcp server in-process through this same component, see the **Get Started** section at the top and the [full in-process server documentation →](docs/in-process-server.md).
|
|
337
338
|
|
|
@@ -477,7 +478,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
477
478
|
- **[@TomasDJo](https://github.com/TomasDJo)** — Category support for automations, scripts, and scenes.
|
|
478
479
|
- **[@bzelch](https://github.com/bzelch)** — `python_transform` support for automations and scripts.
|
|
479
480
|
- **[@gcormier](https://github.com/gcormier)** — Windows installer improvements: removed unused variable and fixed terminal closing after install.
|
|
480
|
-
- **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the add-on config, with beta tagging in source and docs.
|
|
481
|
+
- **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and the (since removed) `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the add-on config, with beta tagging in source and docs.
|
|
481
482
|
- **[@w3z315](https://github.com/w3z315)** — Financial support via [GitHub Sponsors](https://github.com/sponsors/julienld). Thank you! ☕
|
|
482
483
|
- **[@griffinmartin](https://github.com/griffinmartin)** — Added OpenCode (by Anomaly) as a selectable AI client in the setup wizard, with both stdio and streamable HTTP support.
|
|
483
484
|
- **[@hhopke](https://github.com/hhopke)** — Fixed addon API calls to route through HA Core ingress proxy instead of direct container connections, fixing `ha_manage_addon` proxy mode on addon installs.
|
|
@@ -50,12 +50,13 @@ The recommended way to run ha-mcp is the **HA-MCP Custom Component**. It install
|
|
|
50
50
|
|
|
51
51
|
**Connect URL.** The Configure screen gives you a Home Assistant webhook URL for remote clients — `https://<your-ha-domain>/api/webhook/<webhook-id>` through Nabu Casa or any reverse proxy already pointed at Home Assistant (locally, `http://<ha-host>:8123/api/webhook/<webhook-id>`). For clients on the same network, the server is also reachable directly at `http://<ha-ip>:9584/private_<random>`.
|
|
52
52
|
|
|
53
|
+
- **Replaces other install methods:** the in-process server is a complete, standalone ha-mcp install — it takes the place of the add-on, Docker, and uvx/PyPI (stdio) methods. Run only one; do not run the in-process server alongside another install.
|
|
53
54
|
- **Local only?** Turn off **Remote access via webhook** in the entry options — no webhook is registered at all, while the direct port and sidebar panel keep working.
|
|
54
55
|
- **Settings panel:** while the server runs, an admin-only **HA-MCP** panel appears in the Home Assistant sidebar for managing tools, feature flags, backups, and themes.
|
|
55
56
|
- **Optional authentication:** set **Webhook authentication** to `ha_auth` to require a Home Assistant account sign-in instead of using the secret URL as the credential.
|
|
56
57
|
- **Manual install (no HACS):** copy `custom_components/ha_mcp_tools/` from this repository into your Home Assistant `config/custom_components/` directory, then restart and add the integration as above.
|
|
57
58
|
|
|
58
|
-
The component's second entry type, **HA
|
|
59
|
+
The component's second entry type, the **File & YAML services entry** (**HA-MCP File & YAML Tools**), is only needed if you enable ha-mcp's opt-in file and YAML editing tools (feature flags, off by default) — skip it otherwise; you can add it later at any time. It works with any server type (in-process, add-on, Docker, or stdio).
|
|
59
60
|
|
|
60
61
|
[Full in-process server documentation →](docs/in-process-server.md) · [Setup Wizard for client-specific config →](https://homeassistant-ai.github.io/ha-mcp/setup/)
|
|
61
62
|
|
|
@@ -242,9 +243,9 @@ Spend less time configuring, more time enjoying your smart home.
|
|
|
242
243
|
| **Scripts** | `ha_config_get_script`, `ha_config_remove_script`, `ha_config_set_script` |
|
|
243
244
|
| **Search & Discovery** | `ha_get_overview`, `ha_get_state`, `ha_search` |
|
|
244
245
|
| **Service & Device Control** | `ha_bulk_control`, `ha_call_event`, `ha_call_service`, `ha_get_operation_status`, `ha_list_services` |
|
|
245
|
-
| **System** | `ha_config_set_yaml` *(beta)*, `ha_manage_backup`, `ha_manage_custom_tool` *(beta)*, `ha_manage_theme`, `ha_manage_updates`, `ha_reload_core`, `ha_restart` |
|
|
246
|
+
| **System** | `ha_config_get_yaml` *(beta)*, `ha_config_set_yaml` *(beta)*, `ha_manage_backup`, `ha_manage_custom_tool` *(beta)*, `ha_manage_theme`, `ha_manage_updates`, `ha_reload_core`, `ha_restart` |
|
|
246
247
|
| **Todo Lists** | `ha_get_todo`, `ha_remove_todo_item`, `ha_set_todo_item` |
|
|
247
|
-
| **Utilities** | `ha_eval_template`, `
|
|
248
|
+
| **Utilities** | `ha_eval_template`, `ha_report_issue` |
|
|
248
249
|
| **Zones** | `ha_get_zone`, `ha_remove_zone`, `ha_set_zone` |
|
|
249
250
|
|
|
250
251
|
<!-- TOOLS_TABLE_END -->
|
|
@@ -274,7 +275,7 @@ ha-mcp is a standalone server built for **configuring, building, and debugging**
|
|
|
274
275
|
|
|
275
276
|
## 🔌 Custom Component (ha_mcp_tools) — File & YAML Services
|
|
276
277
|
|
|
277
|
-
The **HA-MCP Custom Component** also powers a set of privileged tools that standard Home Assistant APIs can't provide: file system access and YAML config editing. (The same component runs the full server in-process — that's the recommended install in the **Get Started** section at the top.) Its **
|
|
278
|
+
The **HA-MCP Custom Component** also powers a set of privileged tools that standard Home Assistant APIs can't provide: file system access and YAML config editing. (The same component runs the full server in-process — that's the recommended install in the **Get Started** section at the top.) Its **File & YAML services entry** (**HA-MCP File & YAML Tools**) enables the tools below.
|
|
278
279
|
|
|
279
280
|
**Tools that require the component:**
|
|
280
281
|
|
|
@@ -292,13 +293,13 @@ These tools also require beta feature flags. See **[Beta Features](docs/beta.md)
|
|
|
292
293
|
|
|
293
294
|
### Install
|
|
294
295
|
|
|
295
|
-
Install the **HA
|
|
296
|
+
Install the **HA-MCP File & YAML Tools** entry from the same **HA-MCP Custom Component**:
|
|
296
297
|
|
|
297
298
|
[](https://my.home-assistant.io/redirect/hacs_repository/?owner=homeassistant-ai&repository=ha-mcp-integration&category=integration)
|
|
298
299
|
|
|
299
300
|
To add manually: open **HACS** > **Integrations** > three-dot menu > **Custom repositories** > add `https://github.com/homeassistant-ai/ha-mcp-integration` (category: Integration) > **Download**. Or copy `custom_components/ha_mcp_tools/` from this repository into your HA `config/custom_components/` directory.
|
|
300
301
|
|
|
301
|
-
After installing, restart Home Assistant, then open **Settings** > **Devices & Services** > **Add Integration**, search for **HA-MCP Custom Component**, and add the **HA
|
|
302
|
+
After installing, restart Home Assistant, then open **Settings** > **Devices & Services** > **Add Integration**, search for **HA-MCP Custom Component**, and add the **HA-MCP File & YAML Tools** entry.
|
|
302
303
|
|
|
303
304
|
To run the full ha-mcp server in-process through this same component, see the **Get Started** section at the top and the [full in-process server documentation →](docs/in-process-server.md).
|
|
304
305
|
|
|
@@ -444,7 +445,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
444
445
|
- **[@TomasDJo](https://github.com/TomasDJo)** — Category support for automations, scripts, and scenes.
|
|
445
446
|
- **[@bzelch](https://github.com/bzelch)** — `python_transform` support for automations and scripts.
|
|
446
447
|
- **[@gcormier](https://github.com/gcormier)** — Windows installer improvements: removed unused variable and fixed terminal closing after install.
|
|
447
|
-
- **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the add-on config, with beta tagging in source and docs.
|
|
448
|
+
- **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and the (since removed) `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the add-on config, with beta tagging in source and docs.
|
|
448
449
|
- **[@w3z315](https://github.com/w3z315)** — Financial support via [GitHub Sponsors](https://github.com/sponsors/julienld). Thank you! ☕
|
|
449
450
|
- **[@griffinmartin](https://github.com/griffinmartin)** — Added OpenCode (by Anomaly) as a selectable AI client in the setup wizard, with both stdio and streamable HTTP support.
|
|
450
451
|
- **[@hhopke](https://github.com/hhopke)** — Fixed addon API calls to route through HA Core ingress proxy instead of direct container connections, fixing `ha_manage_addon` proxy mode on addon installs.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.12.3.
|
|
7
|
+
version = "7.12.3.dev1942"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# Upper bound widened to <3.15 so the package installs on Home Assistant's
|
|
@@ -257,14 +257,6 @@ class Settings(BaseSettings):
|
|
|
257
257
|
# other gated capability.
|
|
258
258
|
enable_filesystem_tools: bool = Field(False, alias="HAMCP_ENABLE_FILESYSTEM_TOOLS")
|
|
259
259
|
|
|
260
|
-
# Custom-component installer (``ha_install_mcp_tools``) — pulls the
|
|
261
|
-
# ``ha_mcp_tools`` integration into HACS. Same env-var-direct
|
|
262
|
-
# background as ``enable_filesystem_tools``; promoted for the same
|
|
263
|
-
# reason.
|
|
264
|
-
enable_custom_component_integration: bool = Field(
|
|
265
|
-
False, alias="HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION"
|
|
266
|
-
)
|
|
267
|
-
|
|
268
260
|
# Dashboard screenshot mode — the ``ha_get_dashboard_screenshot`` tool
|
|
269
261
|
# plus the ``include_screenshot`` / ``return_screenshot`` params on the
|
|
270
262
|
# dashboard get/set tools. Renders responsive Lovelace images via a
|
|
@@ -356,15 +348,15 @@ class Settings(BaseSettings):
|
|
|
356
348
|
)
|
|
357
349
|
|
|
358
350
|
# Mirror the legacy ``os.getenv("FLAG", "").lower() in ("true", ...)``
|
|
359
|
-
# semantics for the
|
|
360
|
-
#
|
|
351
|
+
# semantics for the ex-direct-getenv ``enable_filesystem_tools`` flag (and
|
|
352
|
+
# its sibling toggles listed above): an empty env var value MUST be treated
|
|
353
|
+
# as False rather than raising
|
|
361
354
|
# ``ValidationError``. Pydantic v2's bool parser raises on ``""``
|
|
362
355
|
# which broke ``test_tools_filesystem.py::TestFeatureFlag::
|
|
363
356
|
# test_disabled_with_empty_string`` after the migration; this
|
|
364
357
|
# validator restores the contract callers rely on.
|
|
365
358
|
@field_validator(
|
|
366
359
|
"enable_filesystem_tools",
|
|
367
|
-
"enable_custom_component_integration",
|
|
368
360
|
"enable_dashboard_screenshot",
|
|
369
361
|
mode="before",
|
|
370
362
|
)
|
|
@@ -693,11 +685,6 @@ FEATURE_FLAG_FIELDS: tuple[FeatureFlagField, ...] = (
|
|
|
693
685
|
FeatureFlagField("enable_yaml_packages_scene", "ENABLE_YAML_PACKAGES_SCENE", bool),
|
|
694
686
|
FeatureFlagField("enable_lite_docstrings", "ENABLE_LITE_DOCSTRINGS", bool),
|
|
695
687
|
FeatureFlagField("enable_filesystem_tools", "HAMCP_ENABLE_FILESYSTEM_TOOLS", bool),
|
|
696
|
-
FeatureFlagField(
|
|
697
|
-
"enable_custom_component_integration",
|
|
698
|
-
"HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION",
|
|
699
|
-
bool,
|
|
700
|
-
),
|
|
701
688
|
# ``enable_code_mode`` lives in this tuple so the override file (and
|
|
702
689
|
# the web UI Server Settings tab) can write the flag. Without this
|
|
703
690
|
# entry, the UI save logic would have nowhere to land the value.
|
|
@@ -744,7 +731,6 @@ BETA_FEATURE_FIELDS: tuple[str, ...] = (
|
|
|
744
731
|
"enable_yaml_packages_script",
|
|
745
732
|
"enable_yaml_packages_scene",
|
|
746
733
|
"enable_filesystem_tools",
|
|
747
|
-
"enable_custom_component_integration",
|
|
748
734
|
"enable_code_mode",
|
|
749
735
|
"enable_lite_docstrings",
|
|
750
736
|
"enable_dashboard_screenshot",
|
|
@@ -632,9 +632,8 @@ class HomeAssistantSmartMCPServer(EnhancedToolsMixin):
|
|
|
632
632
|
"Create or update a Home Assistant script.\n\n"
|
|
633
633
|
"Supports two modes: full `config` replacement, or surgical "
|
|
634
634
|
"`python_transform` on an existing script (requires "
|
|
635
|
-
"`
|
|
636
|
-
"
|
|
637
|
-
"script.\n\n"
|
|
635
|
+
"`config_hash` from ha_config_get_script). `script_id` names "
|
|
636
|
+
"the script in both modes.\n\n"
|
|
638
637
|
"For schema details and examples, see "
|
|
639
638
|
"ha_get_skill_guide."
|
|
640
639
|
),
|
|
@@ -650,19 +649,20 @@ class HomeAssistantSmartMCPServer(EnhancedToolsMixin):
|
|
|
650
649
|
"Create or update a Home Assistant scene.\n\n"
|
|
651
650
|
"Supports two modes: full `config` replacement, or surgical "
|
|
652
651
|
"`python_transform` on an existing scene (requires "
|
|
653
|
-
"`
|
|
652
|
+
"`config_hash`). `scene_id` names the scene in both modes.\n\n"
|
|
654
653
|
"For schema details and examples, see "
|
|
655
654
|
"ha_get_skill_guide."
|
|
656
655
|
),
|
|
657
656
|
"ha_config_list_helpers": (
|
|
658
|
-
"List Home Assistant helpers of a given
|
|
659
|
-
"
|
|
660
|
-
"
|
|
657
|
+
"List Home Assistant helpers of a given type, one page per "
|
|
658
|
+
"call (`limit`/`offset`; `total_count` and `has_more` "
|
|
659
|
+
"describe the full set). The 12 storage-backed types "
|
|
660
|
+
"(input_button, input_boolean, input_select, input_number, "
|
|
661
661
|
"input_text, input_datetime, counter, timer, schedule, "
|
|
662
|
-
"zone, person, tag. Flow-based
|
|
663
|
-
"
|
|
664
|
-
"
|
|
665
|
-
"
|
|
662
|
+
"zone, person, tag) are listed on every install. Flow-based "
|
|
663
|
+
"types (template, group, utility_meter, derivative, and the "
|
|
664
|
+
"rest) and `helper_type='all'` are served only through the "
|
|
665
|
+
"ha_mcp_tools custom component.\n\n"
|
|
666
666
|
"For per-type schemas and decision guidance, see "
|
|
667
667
|
"ha_get_skill_guide."
|
|
668
668
|
),
|
{ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/settings_ui/_tools_meta.py
RENAMED
|
@@ -90,8 +90,7 @@ TRANSFORM_GENERATED_TOOLS: dict[str, ToolStub] = {}
|
|
|
90
90
|
# into the settings UI so users discover the tool exists and how to enable
|
|
91
91
|
# it. Keep this dict in sync with the ``"beta"`` tag added to each tool's
|
|
92
92
|
# source file (tools_yaml_config.py, tools_yaml_read.py, tools_filesystem.py,
|
|
93
|
-
#
|
|
94
|
-
# land in both places.
|
|
93
|
+
# tools_code.py) — a future rename or removal needs to land in both places.
|
|
95
94
|
FEATURE_GATED_TOOLS: dict[str, ToolStub] = {
|
|
96
95
|
"ha_config_set_yaml": {
|
|
97
96
|
"title": "Set YAML Config",
|
|
@@ -142,13 +141,6 @@ FEATURE_GATED_TOOLS: dict[str, ToolStub] = {
|
|
|
142
141
|
"disabled_by": "enable_filesystem_tools",
|
|
143
142
|
"destructiveHint": True,
|
|
144
143
|
},
|
|
145
|
-
"ha_install_mcp_tools": {
|
|
146
|
-
"title": "Install MCP Tools Component",
|
|
147
|
-
"primary_tag": "Utilities",
|
|
148
|
-
"description": "Install the ha_mcp_tools custom component via HACS.",
|
|
149
|
-
"disabled_by": "enable_custom_component_integration",
|
|
150
|
-
"destructiveHint": True,
|
|
151
|
-
},
|
|
152
144
|
}
|
|
153
145
|
|
|
154
146
|
|
|
@@ -1616,10 +1616,6 @@ const FEATURE_META = {
|
|
|
1616
1616
|
label: "Enable filesystem tools (beta)",
|
|
1617
1617
|
help: "Sets HAMCP_ENABLE_FILESYSTEM_TOOLS=true. Enables direct file read/write access to your Home Assistant filesystem. WARNING: This gives the MCP server sensitive direct file access to your system. Only enable if you trust the AI assistant with file operations. Requires restart to take effect.",
|
|
1618
1618
|
},
|
|
1619
|
-
enable_custom_component_integration: {
|
|
1620
|
-
label: "Enable custom component integration (beta)",
|
|
1621
|
-
help: "Sets HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION=true. Enables the ha_install_mcp_tools installer tool, which can help install the ha_mcp_tools custom component. This setting does not control whether the MCP server loads or interacts with the custom component, and it is not required for filesystem tools to function. Only enable if you want to allow the AI assistant to use the installer tool. Requires restart to take effect.",
|
|
1622
|
-
},
|
|
1623
1619
|
enable_code_mode: {
|
|
1624
1620
|
label: "Enable code-mode sandbox (beta)",
|
|
1625
1621
|
help: "Beta feature, disabled by default. Enables ha_manage_custom_tool, a sandboxed Python interpreter (pydantic-monty) that lets AI assistants write/run/save/delete custom tools when no built-in tool covers the request. Sandbox cannot touch the filesystem or arbitrary network, but CAN call any registered MCP tool, hit the HA REST API, or send HA WebSocket commands, effectively 'do whatever existing tools allow you to do, in any combination'. Saved tools persist and are visible to any client that can connect to ha-mcp. See docs/beta.md for known limitations. Requires restart to take effect.",
|
{ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_bug_report.py
RENAMED
|
@@ -211,10 +211,9 @@ def _detect_platform() -> dict[str, str]:
|
|
|
211
211
|
# ``enable_beta_features`` leads the list because it is the master gate: when
|
|
212
212
|
# off it force-disables every beta sub-flag (filesystem tools, code mode, YAML
|
|
213
213
|
# editing, ...) regardless of the sub-flag's own value, so a "missing tool"
|
|
214
|
-
# report is meaningless without it. ``enable_filesystem_tools``
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
# the user couldn't find was even enabled server-side.
|
|
214
|
+
# report is meaningless without it. ``enable_filesystem_tools`` is a beta-gated
|
|
215
|
+
# tool family from issue #1804 — surfacing it lets triage see at a glance whether
|
|
216
|
+
# the tool the user couldn't find was even enabled server-side.
|
|
218
217
|
_CONFIG_TOGGLE_FIELDS: tuple[str, ...] = (
|
|
219
218
|
"enable_beta_features",
|
|
220
219
|
"enable_websocket",
|
|
@@ -223,7 +222,6 @@ _CONFIG_TOGGLE_FIELDS: tuple[str, ...] = (
|
|
|
223
222
|
"tool_search_max_results",
|
|
224
223
|
"enable_yaml_config_editing",
|
|
225
224
|
"enable_filesystem_tools",
|
|
226
|
-
"enable_custom_component_integration",
|
|
227
225
|
"enable_code_mode",
|
|
228
226
|
"enabled_tool_modules",
|
|
229
227
|
)
|
{ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
@@ -53,6 +53,7 @@ from .util_helpers import (
|
|
|
53
53
|
attach_skill_content,
|
|
54
54
|
augment_error_dict_with_skill_content,
|
|
55
55
|
augment_tool_error_with_skill_content,
|
|
56
|
+
build_pagination_metadata,
|
|
56
57
|
parse_json_param,
|
|
57
58
|
parse_string_list_param,
|
|
58
59
|
wait_for_entity_registered,
|
|
@@ -1356,21 +1357,36 @@ def _flatten_helper_list_result(result: Any) -> list[Any]:
|
|
|
1356
1357
|
"""Flatten a {type}/list WS response into a flat list of helper dicts.
|
|
1357
1358
|
|
|
1358
1359
|
Handles the person/list shape ({"storage": [...], "config": [...]}) and
|
|
1359
|
-
the standard list shape ([...]).
|
|
1360
|
+
the standard list shape ([...]). An unrecognised shape yields an empty
|
|
1361
|
+
list, which downstream is indistinguishable from a helper type that has no
|
|
1362
|
+
entries, so it is logged rather than dropped in silence.
|
|
1360
1363
|
"""
|
|
1361
1364
|
if isinstance(result, dict):
|
|
1362
1365
|
inner = result.get("result", [])
|
|
1363
1366
|
if isinstance(inner, dict):
|
|
1364
1367
|
items: list[Any] = []
|
|
1368
|
+
matched = False
|
|
1365
1369
|
for key in ("storage", "config"):
|
|
1366
1370
|
sub = inner.get(key)
|
|
1367
1371
|
if isinstance(sub, list):
|
|
1372
|
+
matched = True
|
|
1368
1373
|
items.extend(sub)
|
|
1374
|
+
if not matched:
|
|
1375
|
+
logger.warning(
|
|
1376
|
+
"Helper listing has neither a 'storage' nor a 'config' list "
|
|
1377
|
+
"(keys: %s); treating it as empty",
|
|
1378
|
+
sorted(inner),
|
|
1379
|
+
)
|
|
1369
1380
|
return items
|
|
1370
1381
|
if isinstance(inner, list):
|
|
1371
1382
|
return inner
|
|
1372
1383
|
if isinstance(result, list):
|
|
1373
1384
|
return result
|
|
1385
|
+
logger.warning(
|
|
1386
|
+
"Cannot flatten a helper listing: expected a list or a storage/config "
|
|
1387
|
+
"split, got %s; treating it as empty",
|
|
1388
|
+
type(result).__name__,
|
|
1389
|
+
)
|
|
1374
1390
|
return []
|
|
1375
1391
|
|
|
1376
1392
|
|
|
@@ -3508,6 +3524,53 @@ def _shape_flow_helper_record(rec: dict[str, Any]) -> dict[str, Any]:
|
|
|
3508
3524
|
return out
|
|
3509
3525
|
|
|
3510
3526
|
|
|
3527
|
+
def _paginate_helpers_response(
|
|
3528
|
+
response: dict[str, Any], offset: int, limit: int
|
|
3529
|
+
) -> dict[str, Any]:
|
|
3530
|
+
"""Slice a helper listing envelope down to one page.
|
|
3531
|
+
|
|
3532
|
+
The single normalization point for every ``ha_config_list_helpers`` route
|
|
3533
|
+
(all-types, component, legacy): each builds the same
|
|
3534
|
+
``success``/``helper_type``/``count``/``helpers``/``message`` envelope, so
|
|
3535
|
+
the slice is applied once here instead of in each builder. ``count`` becomes
|
|
3536
|
+
the page size and ``total_count`` carries the full size, matching
|
|
3537
|
+
``ha_list_services``.
|
|
3538
|
+
"""
|
|
3539
|
+
helpers = response.get("helpers")
|
|
3540
|
+
if not isinstance(helpers, list):
|
|
3541
|
+
# Every builder owes this function a flat list; anything else is a bug in
|
|
3542
|
+
# the caller (a {type}/list shape that escaped _flatten_helper_list_result).
|
|
3543
|
+
# The records are still usable, so return them unpaginated rather than
|
|
3544
|
+
# raising -- but say so in warnings[], not just the log: the caller is an
|
|
3545
|
+
# agent that never sees server logs, and absent metadata otherwise reads
|
|
3546
|
+
# as "the collection fits on one page".
|
|
3547
|
+
shape = type(helpers).__name__
|
|
3548
|
+
logger.warning(
|
|
3549
|
+
"Cannot paginate %r listing: expected a list of helpers, got %s; "
|
|
3550
|
+
"returning the envelope unpaginated",
|
|
3551
|
+
response.get("helper_type"),
|
|
3552
|
+
shape,
|
|
3553
|
+
)
|
|
3554
|
+
warning = (
|
|
3555
|
+
f"Listing could not be paginated (expected a list of helpers, got "
|
|
3556
|
+
f"{shape}); returned in full, without pagination metadata."
|
|
3557
|
+
)
|
|
3558
|
+
existing = response.get("warnings")
|
|
3559
|
+
return {
|
|
3560
|
+
**response,
|
|
3561
|
+
"warnings": [*existing, warning]
|
|
3562
|
+
if isinstance(existing, list)
|
|
3563
|
+
else [warning],
|
|
3564
|
+
}
|
|
3565
|
+
total_count = len(helpers)
|
|
3566
|
+
page = helpers[offset : offset + limit]
|
|
3567
|
+
return {
|
|
3568
|
+
**response,
|
|
3569
|
+
"helpers": page,
|
|
3570
|
+
**build_pagination_metadata(total_count, offset, limit, len(page)),
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3573
|
+
|
|
3511
3574
|
def _shape_component_helpers_response(
|
|
3512
3575
|
helper_type: str, result: dict[str, Any]
|
|
3513
3576
|
) -> dict[str, Any]:
|
|
@@ -3643,11 +3706,30 @@ class HelperConfigTools:
|
|
|
3643
3706
|
)
|
|
3644
3707
|
),
|
|
3645
3708
|
],
|
|
3709
|
+
limit: Annotated[
|
|
3710
|
+
int,
|
|
3711
|
+
Field(
|
|
3712
|
+
default=100,
|
|
3713
|
+
ge=1,
|
|
3714
|
+
le=500,
|
|
3715
|
+
description="Max helpers to return per page (default: 100)",
|
|
3716
|
+
),
|
|
3717
|
+
] = 100,
|
|
3718
|
+
offset: Annotated[
|
|
3719
|
+
int,
|
|
3720
|
+
Field(
|
|
3721
|
+
default=0,
|
|
3722
|
+
ge=0,
|
|
3723
|
+
description="Number of helpers to skip for pagination (default: 0)",
|
|
3724
|
+
),
|
|
3725
|
+
] = 0,
|
|
3646
3726
|
) -> dict[str, Any]:
|
|
3647
3727
|
"""
|
|
3648
|
-
List
|
|
3728
|
+
List Home Assistant helpers of a specific type with their configurations.
|
|
3649
3729
|
|
|
3650
|
-
Returns
|
|
3730
|
+
Returns one page of helpers; `total_count` and `has_more` report the full
|
|
3731
|
+
set. Each record carries the complete configuration for its helper,
|
|
3732
|
+
including:
|
|
3651
3733
|
- id (immutable storage key), entity_id (current — address the helper by
|
|
3652
3734
|
this, where available), name (current display name), original_name
|
|
3653
3735
|
(creation-time name), icon
|
|
@@ -3682,8 +3764,12 @@ class HelperConfigTools:
|
|
|
3682
3764
|
- List all persons: ha_config_list_helpers("person")
|
|
3683
3765
|
- List all tags: ha_config_list_helpers("tag")
|
|
3684
3766
|
- List every helper type at once: ha_config_list_helpers("all")
|
|
3767
|
+
- Next page: ha_config_list_helpers("input_boolean", offset=100)
|
|
3685
3768
|
|
|
3686
|
-
**NOTE:**
|
|
3769
|
+
**NOTE:** Storage types list what HA's ``{type}/list`` command returns:
|
|
3770
|
+
the storage-backed helpers (created via UI/API), not the YAML-defined
|
|
3771
|
+
ones. ``person`` is the exception — HA lists its YAML-configured persons
|
|
3772
|
+
alongside the storage ones, so both appear here.
|
|
3687
3773
|
|
|
3688
3774
|
Flow-based types (template / group / utility_meter / derivative / etc.)
|
|
3689
3775
|
require the ha_mcp_tools custom component (>= 1.1.0) and are served only
|
|
@@ -3702,7 +3788,9 @@ class HelperConfigTools:
|
|
|
3702
3788
|
# No legacy equivalent exists (no single WS command enumerates all
|
|
3703
3789
|
# types), so it is component-only — see ``_list_all_helpers``.
|
|
3704
3790
|
if helper_type == "all":
|
|
3705
|
-
return
|
|
3791
|
+
return _paginate_helpers_response(
|
|
3792
|
+
await self._list_all_helpers(), offset, limit
|
|
3793
|
+
)
|
|
3706
3794
|
|
|
3707
3795
|
# Flow-based helper types have no ``{type}/list`` command, so only the
|
|
3708
3796
|
# component's ``helpers_list`` can enumerate them: they are served
|
|
@@ -3723,7 +3811,7 @@ class HelperConfigTools:
|
|
|
3723
3811
|
helper_type, is_flow=is_flow
|
|
3724
3812
|
)
|
|
3725
3813
|
if component_response is not None:
|
|
3726
|
-
return component_response
|
|
3814
|
+
return _paginate_helpers_response(component_response, offset, limit)
|
|
3727
3815
|
if is_flow:
|
|
3728
3816
|
# No usable component path and the legacy body cannot serve flow
|
|
3729
3817
|
# helpers: hard error rather than an empty or misleading list.
|
|
@@ -3751,7 +3839,7 @@ class HelperConfigTools:
|
|
|
3751
3839
|
}
|
|
3752
3840
|
if warnings:
|
|
3753
3841
|
response["warnings"] = warnings
|
|
3754
|
-
return response
|
|
3842
|
+
return _paginate_helpers_response(response, offset, limit)
|
|
3755
3843
|
raise_tool_error(
|
|
3756
3844
|
create_error_response(
|
|
3757
3845
|
ErrorCode.SERVICE_CALL_FAILED,
|
|
@@ -3880,7 +3968,11 @@ class HelperConfigTools:
|
|
|
3880
3968
|
context={"helper_type": helper_type},
|
|
3881
3969
|
)
|
|
3882
3970
|
)
|
|
3883
|
-
|
|
3971
|
+
# Flatten like the inline body: person/list returns {"storage": [...],
|
|
3972
|
+
# "config": [...]} rather than a flat list, so a raw result["result"]
|
|
3973
|
+
# would be a dict here — breaking count, the pagination slice and the
|
|
3974
|
+
# all-types merge, which all expect a list of records.
|
|
3975
|
+
items = _flatten_helper_list_result(result)
|
|
3884
3976
|
return {
|
|
3885
3977
|
"success": True,
|
|
3886
3978
|
"helper_type": helper_type,
|
|
@@ -4005,11 +4097,23 @@ class HelperConfigTools:
|
|
|
4005
4097
|
)
|
|
4006
4098
|
for helper_type in sorted(SIMPLE_HELPER_TYPES - covered_set):
|
|
4007
4099
|
legacy = await self._legacy_helper_list(helper_type)
|
|
4100
|
+
skipped = 0
|
|
4008
4101
|
for item in legacy.get("helpers", []):
|
|
4009
4102
|
if isinstance(item, dict):
|
|
4010
4103
|
row = dict(item)
|
|
4011
4104
|
row.setdefault("helper_type", helper_type)
|
|
4012
4105
|
helpers.append(row)
|
|
4106
|
+
else:
|
|
4107
|
+
skipped += 1
|
|
4108
|
+
if skipped:
|
|
4109
|
+
# This is how the unflattened person/list dict used to vanish:
|
|
4110
|
+
# iterating it yielded its keys, and each failed the check here.
|
|
4111
|
+
logger.warning(
|
|
4112
|
+
"Dropped %d unrecognised item(s) from the %s listing while "
|
|
4113
|
+
"merging all types; the merged listing is incomplete",
|
|
4114
|
+
skipped,
|
|
4115
|
+
helper_type,
|
|
4116
|
+
)
|
|
4013
4117
|
|
|
4014
4118
|
return {
|
|
4015
4119
|
"success": True,
|
|
@@ -126,7 +126,8 @@ async def find_server_config_entry(
|
|
|
126
126
|
|
|
127
127
|
Probes each ``ha_mcp_tools`` entry's options flow: the server entry's
|
|
128
128
|
flow is a form whose schema carries the ``pip_spec`` field; the tools
|
|
129
|
-
(services) entry's flow
|
|
129
|
+
(services) entry's flow is an informational form with no ``pip_spec``
|
|
130
|
+
field, so it never matches. Returns
|
|
130
131
|
``(entry_id, open_flow, current_options)`` with the options flow left
|
|
131
132
|
OPEN (callers must submit or abort it), or ``None`` when no server
|
|
132
133
|
entry exists. ``current_options`` maps schema field names to their current
|
{ha_mcp_dev-7.12.3.dev1937 → ha_mcp_dev-7.12.3.dev1942}/src/ha_mcp/tools/tools_filesystem.py
RENAMED
|
@@ -7,8 +7,10 @@ configuration directory, enabling AI assistants to:
|
|
|
7
7
|
- List files in allowed directories
|
|
8
8
|
- Write/delete files in restricted directories (www/, themes/, custom_templates/)
|
|
9
9
|
|
|
10
|
-
**Dependency:** Requires the ha_mcp_tools custom component
|
|
11
|
-
|
|
10
|
+
**Dependency:** Requires the ha_mcp_tools custom component, added in HA via its
|
|
11
|
+
"HA-MCP File & YAML Tools" config entry (NOT the "HA-MCP Server" entry, which
|
|
12
|
+
starts a redundant in-process server). The tools will gracefully fail with
|
|
13
|
+
installation instructions if the component is not available.
|
|
12
14
|
|
|
13
15
|
Feature Flag: Set HAMCP_ENABLE_FILESYSTEM_TOOLS=true to enable these tools.
|
|
14
16
|
"""
|
|
@@ -141,7 +143,7 @@ def _raise_component_too_old(detail: str) -> NoReturn:
|
|
|
141
143
|
f"This ha-mcp release requires >= {MIN_COMPONENT_VERSION}. "
|
|
142
144
|
"Update via HACS and restart Home Assistant.",
|
|
143
145
|
suggestions=[
|
|
144
|
-
"HACS → Integrations → HA
|
|
146
|
+
"HACS → Integrations → HA-MCP Custom Component → Update",
|
|
145
147
|
"Restart Home Assistant after update completes",
|
|
146
148
|
"Then retry the operation",
|
|
147
149
|
],
|
|
@@ -362,8 +364,17 @@ async def _assert_mcp_tools_available(client: Any) -> None:
|
|
|
362
364
|
raise_tool_error(
|
|
363
365
|
create_error_response(
|
|
364
366
|
ErrorCode.COMPONENT_NOT_INSTALLED,
|
|
365
|
-
f"The {MCP_TOOLS_DOMAIN} custom component is not installed.
|
|
366
|
-
|
|
367
|
+
f"The {MCP_TOOLS_DOMAIN} custom component is not installed.",
|
|
368
|
+
suggestions=[
|
|
369
|
+
'Add the repository to HACS: ha_manage_hacs(action="add_repository",'
|
|
370
|
+
+ ' repository="homeassistant-ai/ha-mcp-integration", category="integration")',
|
|
371
|
+
'Download the component: ha_manage_hacs(action="download",'
|
|
372
|
+
+ ' repository_id="homeassistant-ai/ha-mcp-integration")',
|
|
373
|
+
"Restart Home Assistant (ha_restart) so the integration loads",
|
|
374
|
+
'In HA, add the "HA-MCP Custom Component" integration and choose the'
|
|
375
|
+
+ ' "HA-MCP File & YAML Tools" entry — NOT "HA-MCP Server", which starts'
|
|
376
|
+
+ " a second in-process server this ha-mcp server does not need",
|
|
377
|
+
],
|
|
367
378
|
)
|
|
368
379
|
)
|
|
369
380
|
|