ha-mcp-dev 7.9.0.dev742__tar.gz → 7.9.0.dev743__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.9.0.dev742/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.9.0.dev743}/PKG-INFO +1 -1
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/pyproject.toml +1 -1
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/errors.py +42 -2
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_bug_report.py +87 -1
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/LICENSE +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/README.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/setup.cfg +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/settings.js +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.9.0.
|
|
7
|
+
version = "7.9.0.dev743"
|
|
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"
|
|
@@ -298,15 +298,55 @@ def create_connection_error(
|
|
|
298
298
|
return create_error_response(code, message, details, context=context)
|
|
299
299
|
|
|
300
300
|
|
|
301
|
+
# Authentication-error suggestions for Home Assistant add-on installs. On the
|
|
302
|
+
# add-on the token is managed by the Supervisor, not a user-editable
|
|
303
|
+
# HOMEASSISTANT_TOKEN, so the default "verify your token / create a long-lived
|
|
304
|
+
# token" guidance is a dead end. We deliberately do NOT assert a cause — issue
|
|
305
|
+
# #1694's underlying cause was never reproduced or confirmed — so this points at
|
|
306
|
+
# practical first steps and at where an auth problem actually surfaces
|
|
307
|
+
# (home-assistant.log), without claiming to know why it happened.
|
|
308
|
+
_ADDON_AUTH_INVALID_SUGGESTIONS: list[str] = [
|
|
309
|
+
"On a Home Assistant add-on install the access token is managed by the "
|
|
310
|
+
+ "Supervisor, not a HOMEASSISTANT_TOKEN you can change",
|
|
311
|
+
"A Home Assistant Core restart (Settings -> System -> Restart) often "
|
|
312
|
+
+ "clears transient WebSocket authentication failures — try that first",
|
|
313
|
+
"Check home-assistant.log for 'invalid authentication' or "
|
|
314
|
+
+ "'InsecureKeyLengthWarning' around the time of the failure; if those "
|
|
315
|
+
+ "appear, the problem is likely in Home Assistant's auth handling rather "
|
|
316
|
+
+ "than ha-mcp's request — capture those lines when reporting",
|
|
317
|
+
]
|
|
318
|
+
|
|
319
|
+
|
|
301
320
|
def create_auth_error(
|
|
302
321
|
message: str,
|
|
303
322
|
details: str | None = None,
|
|
304
323
|
expired: bool = False,
|
|
305
324
|
context: dict[str, Any] | None = None,
|
|
306
325
|
) -> dict[str, Any]:
|
|
307
|
-
"""Create an authentication error response.
|
|
326
|
+
"""Create an authentication error response.
|
|
327
|
+
|
|
328
|
+
On a Home Assistant add-on install (Supervisor-managed) the token is the
|
|
329
|
+
Supervisor token rather than a user-editable HOMEASSISTANT_TOKEN, so the
|
|
330
|
+
default token-centric suggestions don't apply. Substitute add-on-specific
|
|
331
|
+
guidance for an invalid token in that case (see issue #1694). Expired-token
|
|
332
|
+
errors keep the default guidance — token expiry is not the Supervisor-token
|
|
333
|
+
failure mode this swap targets.
|
|
334
|
+
"""
|
|
308
335
|
code = ErrorCode.AUTH_EXPIRED if expired else ErrorCode.AUTH_INVALID_TOKEN
|
|
309
|
-
|
|
336
|
+
|
|
337
|
+
suggestions: list[str] | None = None
|
|
338
|
+
if code is ErrorCode.AUTH_INVALID_TOKEN:
|
|
339
|
+
# Lazy import keeps this low-level module free of an import-time
|
|
340
|
+
# dependency on ._version; is_running_in_addon reads SUPERVISOR_TOKEN
|
|
341
|
+
# live so it reflects the current environment.
|
|
342
|
+
from ._version import is_running_in_addon
|
|
343
|
+
|
|
344
|
+
if is_running_in_addon():
|
|
345
|
+
suggestions = _ADDON_AUTH_INVALID_SUGGESTIONS
|
|
346
|
+
|
|
347
|
+
return create_error_response(
|
|
348
|
+
code, message, details, suggestions=suggestions, context=context
|
|
349
|
+
)
|
|
310
350
|
|
|
311
351
|
|
|
312
352
|
def create_entity_not_found_error(
|
|
@@ -47,6 +47,12 @@ AGENT_BEHAVIOR_URL = (
|
|
|
47
47
|
# while still capturing enough recent output to diagnose most issues.
|
|
48
48
|
_ADDON_LOG_MAX_CHARS = 3000
|
|
49
49
|
|
|
50
|
+
# Max characters to include from the Home Assistant error log (home-assistant.log).
|
|
51
|
+
# Slightly larger than the addon cap: this log carries the highest-value
|
|
52
|
+
# diagnostic lines (auth failures, integration tracebacks) and the recent tail
|
|
53
|
+
# is where they land. ~5000 chars ≈ 1250 LLM tokens.
|
|
54
|
+
_CORE_LOG_MAX_CHARS = 5000
|
|
55
|
+
|
|
50
56
|
# IPv4 sanitization: only redact addresses with strong network context so that
|
|
51
57
|
# four-segment version strings (e.g. "ha-mcp version 1.2.3.4") are preserved.
|
|
52
58
|
_IPV4_OCTET = r"(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)"
|
|
@@ -408,6 +414,49 @@ async def _fetch_addon_logs() -> str:
|
|
|
408
414
|
return ""
|
|
409
415
|
|
|
410
416
|
|
|
417
|
+
async def _fetch_core_error_log(client: Any) -> str:
|
|
418
|
+
"""Fetch the Home Assistant error log (home-assistant.log) via the client.
|
|
419
|
+
|
|
420
|
+
Works on every install type — ``HomeAssistantClient.get_error_log`` routes
|
|
421
|
+
add-on installs to the Supervisor, supervised/HAOS to the hassio proxy, and
|
|
422
|
+
container/pip to ``/api/error_log``. Captured over REST, which stays up even
|
|
423
|
+
when the WebSocket path is failing; that is exactly the failure mode in
|
|
424
|
+
issue #1694, where the high-value auth lines
|
|
425
|
+
(``InsecureKeyLengthWarning``, "invalid authentication") only appeared in
|
|
426
|
+
home-assistant.log, not in the add-on log this tool already captured.
|
|
427
|
+
|
|
428
|
+
Best-effort: returns sanitized text (last ``_CORE_LOG_MAX_CHARS`` chars,
|
|
429
|
+
with a truncation marker prepended) or an empty string on any failure, so a
|
|
430
|
+
log-fetch problem never breaks the bug-report path.
|
|
431
|
+
"""
|
|
432
|
+
try:
|
|
433
|
+
raw = await client.get_error_log()
|
|
434
|
+
except Exception as e:
|
|
435
|
+
# Broad by design — the bug-report path must stay robust whatever the
|
|
436
|
+
# client raises (auth, role, connection, transport). Logged at INFO so
|
|
437
|
+
# a missing error log is visible without alarming on a routine 403.
|
|
438
|
+
logger.info(
|
|
439
|
+
"Could not fetch HA error log for bug report: %s (%s)",
|
|
440
|
+
e,
|
|
441
|
+
type(e).__name__,
|
|
442
|
+
)
|
|
443
|
+
return ""
|
|
444
|
+
|
|
445
|
+
if not raw:
|
|
446
|
+
return ""
|
|
447
|
+
|
|
448
|
+
# Strip ANSI, then sanitize, then truncate — sanitizing before truncating
|
|
449
|
+
# keeps a secret straddling the cut boundary from leaking through.
|
|
450
|
+
sanitized = _sanitize_log_text(ANSI_ESCAPE_RE.sub("", raw))
|
|
451
|
+
if len(sanitized) > _CORE_LOG_MAX_CHARS:
|
|
452
|
+
marker = (
|
|
453
|
+
f"[...truncated, showing last {_CORE_LOG_MAX_CHARS} of "
|
|
454
|
+
f"{len(sanitized)} chars...]\n"
|
|
455
|
+
)
|
|
456
|
+
return marker + sanitized[-_CORE_LOG_MAX_CHARS:]
|
|
457
|
+
return sanitized
|
|
458
|
+
|
|
459
|
+
|
|
411
460
|
def _build_formatted_report(
|
|
412
461
|
diagnostic_info: dict[str, Any],
|
|
413
462
|
mcp_transport: str,
|
|
@@ -419,6 +468,7 @@ def _build_formatted_report(
|
|
|
419
468
|
recent_logs: list[dict[str, Any]],
|
|
420
469
|
log_summary: str,
|
|
421
470
|
addon_logs: str,
|
|
471
|
+
core_error_log: str,
|
|
422
472
|
) -> str:
|
|
423
473
|
report_lines = [
|
|
424
474
|
"=== ha-mcp Bug Report Info ===",
|
|
@@ -459,6 +509,8 @@ def _build_formatted_report(
|
|
|
459
509
|
)
|
|
460
510
|
if addon_logs:
|
|
461
511
|
report_lines.extend(["", "=== Add-on Container Logs ===", addon_logs])
|
|
512
|
+
if core_error_log:
|
|
513
|
+
report_lines.extend(["", "=== Home Assistant Error Log ===", core_error_log])
|
|
462
514
|
return "\n".join(report_lines)
|
|
463
515
|
|
|
464
516
|
|
|
@@ -530,6 +582,8 @@ class BugReportTools:
|
|
|
530
582
|
- `recent_logs`, `startup_logs` — captured ha-mcp tool/server log entries
|
|
531
583
|
- `addon_logs` — addon container stdout/stderr (HA add-on installs only;
|
|
532
584
|
empty string otherwise)
|
|
585
|
+
- `core_error_log` — Home Assistant error log (home-assistant.log) over
|
|
586
|
+
REST; carries auth / integration errors that don't show in addon_logs
|
|
533
587
|
- `suggested_title`, `duplicate_check_urls`, `anonymization_guide`
|
|
534
588
|
"""
|
|
535
589
|
# Detect installation method, platform, and runtime config.
|
|
@@ -583,6 +637,12 @@ class BugReportTools:
|
|
|
583
637
|
if install_method == "addon":
|
|
584
638
|
addon_logs = await _fetch_addon_logs()
|
|
585
639
|
|
|
640
|
+
# Fetch the Home Assistant error log (home-assistant.log) on every
|
|
641
|
+
# install type. It's pulled over REST — which stays up even when the
|
|
642
|
+
# WebSocket path is failing — so the report captures auth / integration
|
|
643
|
+
# errors (issue #1694) that never appear in the add-on log above.
|
|
644
|
+
core_error_log = await _fetch_core_error_log(self._client)
|
|
645
|
+
|
|
586
646
|
# Format logs for inclusion (sanitized summary)
|
|
587
647
|
log_summary = _format_logs_for_report(recent_logs)
|
|
588
648
|
startup_log_summary = _format_startup_logs(startup_logs)
|
|
@@ -599,6 +659,7 @@ class BugReportTools:
|
|
|
599
659
|
recent_logs,
|
|
600
660
|
log_summary,
|
|
601
661
|
addon_logs,
|
|
662
|
+
core_error_log,
|
|
602
663
|
)
|
|
603
664
|
|
|
604
665
|
# Generate suggested title up-front so it can be folded into the
|
|
@@ -618,6 +679,7 @@ class BugReportTools:
|
|
|
618
679
|
recent_logs,
|
|
619
680
|
startup_logs,
|
|
620
681
|
addon_logs=addon_logs,
|
|
682
|
+
core_error_log=core_error_log,
|
|
621
683
|
submit_url=runtime_bug_submit_url,
|
|
622
684
|
)
|
|
623
685
|
|
|
@@ -655,6 +717,8 @@ class BugReportTools:
|
|
|
655
717
|
for entry in startup_logs
|
|
656
718
|
],
|
|
657
719
|
"addon_logs": addon_logs,
|
|
720
|
+
# Already sanitized + truncated by _fetch_core_error_log.
|
|
721
|
+
"core_error_log": core_error_log,
|
|
658
722
|
"log_count": len(recent_logs),
|
|
659
723
|
"startup_log_count": len(startup_logs),
|
|
660
724
|
"formatted_report": formatted_report,
|
|
@@ -714,6 +778,7 @@ class BugReportTools:
|
|
|
714
778
|
" - Agent behavior: see agent_behavior_submit_url\n"
|
|
715
779
|
" d. Ask them to fill in the description sections\n"
|
|
716
780
|
" e. For HA add-on installs, the runtime bug template includes a collapsible '📦 Add-on Container Logs' section auto-filled from addon_logs — keep it as-is\n"
|
|
781
|
+
" e2. When present, the template also includes a collapsible 'Home Assistant Error Log' section auto-filled from core_error_log (auth / integration errors) — keep it as-is\n"
|
|
717
782
|
" f. Remind them to review for any remaining personal information before submitting\n\n"
|
|
718
783
|
"CRITICAL: Always ANONYMIZE the report BEFORE presenting it in markdown code blocks!"
|
|
719
784
|
),
|
|
@@ -894,6 +959,7 @@ def _generate_runtime_bug_template(
|
|
|
894
959
|
startup_logs: list[dict[str, Any]],
|
|
895
960
|
*,
|
|
896
961
|
addon_logs: str = "",
|
|
962
|
+
core_error_log: str = "",
|
|
897
963
|
submit_url: str = RUNTIME_BUG_URL,
|
|
898
964
|
) -> str:
|
|
899
965
|
"""
|
|
@@ -950,6 +1016,26 @@ def _generate_runtime_bug_template(
|
|
|
950
1016
|
{addon_logs}
|
|
951
1017
|
```
|
|
952
1018
|
|
|
1019
|
+
</details>
|
|
1020
|
+
"""
|
|
1021
|
+
|
|
1022
|
+
# Show the Home Assistant error log section when available (all install
|
|
1023
|
+
# types). This carries the auth / integration errors that diagnose issues
|
|
1024
|
+
# like #1694 and don't appear in the add-on container log above.
|
|
1025
|
+
core_log_section = ""
|
|
1026
|
+
if core_error_log:
|
|
1027
|
+
core_log_section = f"""
|
|
1028
|
+
---
|
|
1029
|
+
|
|
1030
|
+
## Home Assistant Error Log
|
|
1031
|
+
|
|
1032
|
+
<details>
|
|
1033
|
+
<summary>Click to expand home-assistant.log (auth / integration errors)</summary>
|
|
1034
|
+
|
|
1035
|
+
```
|
|
1036
|
+
{core_error_log}
|
|
1037
|
+
```
|
|
1038
|
+
|
|
953
1039
|
</details>
|
|
954
1040
|
"""
|
|
955
1041
|
|
|
@@ -1048,7 +1134,7 @@ server:
|
|
|
1048
1134
|
```
|
|
1049
1135
|
|
|
1050
1136
|
</details>
|
|
1051
|
-
{startup_section}{addon_section}
|
|
1137
|
+
{startup_section}{addon_section}{core_log_section}
|
|
1052
1138
|
---
|
|
1053
1139
|
|
|
1054
1140
|
## 💡 Additional Context
|
|
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.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/__init__.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/capture.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/provision.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
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/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
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_entities.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_overview.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_scenes.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_scoring.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tool_search_hint_middleware.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
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_dashboard_screenshot.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/validation_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/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
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/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
|