ha-mcp-dev 7.9.0.dev767__tar.gz → 7.9.0.dev768__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.dev767/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.9.0.dev768}/PKG-INFO +1 -1
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/pyproject.toml +1 -1
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/__main__.py +17 -2
- ha_mcp_dev-7.9.0.dev768/src/ha_mcp/transport_security.py +90 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/SOURCES.txt +1 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/LICENSE +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/README.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/setup.cfg +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/settings.js +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/resolver.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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.dev768"
|
|
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
|
|
@@ -318,6 +318,15 @@ def _create_server() -> "HomeAssistantSmartMCPServer":
|
|
|
318
318
|
"""Create server instance (deferred to avoid import during smoke test)."""
|
|
319
319
|
from pydantic import ValidationError
|
|
320
320
|
|
|
321
|
+
# Every deferred-``mcp`` entry point funnels through here before its
|
|
322
|
+
# Streamable-HTTP app is built -- ha-mcp-web, the add-on, and the
|
|
323
|
+
# ``fastmcp run fastmcp-http.json`` container path -- so default fastmcp's
|
|
324
|
+
# DNS-rebinding guard off once, here, for all of them. Direct-construction
|
|
325
|
+
# paths (_run_oauth_server, the in-process component server) call it themselves.
|
|
326
|
+
from ha_mcp.transport_security import ensure_host_origin_guard_default_off
|
|
327
|
+
|
|
328
|
+
ensure_host_origin_guard_default_off()
|
|
329
|
+
|
|
321
330
|
try:
|
|
322
331
|
from ha_mcp.server import HomeAssistantSmartMCPServer
|
|
323
332
|
|
|
@@ -823,8 +832,6 @@ def _maybe_spawn_settings_sidecar() -> None:
|
|
|
823
832
|
|
|
824
833
|
def main_dev() -> None:
|
|
825
834
|
"""Run server with DEBUG logging enabled (for ha-mcp-dev package)."""
|
|
826
|
-
import os
|
|
827
|
-
|
|
828
835
|
os.environ["LOG_LEVEL"] = "DEBUG"
|
|
829
836
|
main()
|
|
830
837
|
|
|
@@ -1094,6 +1101,8 @@ def _run_http_server(transport: str, default_port: int = 8086) -> None:
|
|
|
1094
1101
|
"""
|
|
1095
1102
|
from ha_mcp.settings_ui import register_settings_routes
|
|
1096
1103
|
|
|
1104
|
+
# The DNS-rebinding guard is defaulted off in _create_server (reached here via
|
|
1105
|
+
# _get_mcp below, before the app is built) -- see transport_security.
|
|
1097
1106
|
host, port, path = _get_http_runtime(default_port)
|
|
1098
1107
|
_warn_if_default_path_exposed(host, port, path)
|
|
1099
1108
|
# SSE transport answers GET with 200 (the event stream), so a GET->405 there
|
|
@@ -1224,6 +1233,12 @@ async def _run_oauth_server(
|
|
|
1224
1233
|
"""
|
|
1225
1234
|
from ha_mcp.auth import HomeAssistantOAuthProvider
|
|
1226
1235
|
from ha_mcp.server import HomeAssistantSmartMCPServer
|
|
1236
|
+
from ha_mcp.transport_security import ensure_host_origin_guard_default_off
|
|
1237
|
+
|
|
1238
|
+
# Browser OAuth clients (Claude.ai / ChatGPT) reach the discovery endpoints
|
|
1239
|
+
# cross-origin, and users front this server with proxies/tunnels on arbitrary
|
|
1240
|
+
# hosts; default fastmcp's DNS-rebinding guard off so it does not 403/421 them.
|
|
1241
|
+
ensure_host_origin_guard_default_off()
|
|
1227
1242
|
|
|
1228
1243
|
# Create OAuth provider
|
|
1229
1244
|
auth_provider = HomeAssistantOAuthProvider(
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Transport-security defaults for ha-mcp's Streamable-HTTP servers.
|
|
2
|
+
|
|
3
|
+
fastmcp >= 3.4.3 ships ``HostOriginGuardMiddleware`` (a DNS-rebinding guard) that
|
|
4
|
+
is **on by default**. Inserted at the front of the Streamable-HTTP ASGI stack, it
|
|
5
|
+
rejects any request whose ``Host`` header is not loopback / an explicitly-allowed
|
|
6
|
+
host with ``421 Misdirected Request``, and any browser ``Origin`` that is not
|
|
7
|
+
same-origin / loopback / explicitly allowed with ``403 Forbidden`` -- before the
|
|
8
|
+
request reaches any route.
|
|
9
|
+
|
|
10
|
+
That default is wrong for ha-mcp. We are *designed* to be reached through
|
|
11
|
+
operator-chosen reverse proxies and tunnels (Cloudflare Tunnel, nginx, Traefik,
|
|
12
|
+
Nabu Casa Remote UI) and via direct LAN IPs, whose ``Host`` values we cannot
|
|
13
|
+
enumerate. Leaving the guard on would ``421`` the majority of real deployments --
|
|
14
|
+
including the plain browser landing page, which is a no-``Origin`` navigation
|
|
15
|
+
that still trips the ``Host`` check.
|
|
16
|
+
|
|
17
|
+
Our security boundary is the high-entropy secret path (and, in OAuth mode, the
|
|
18
|
+
per-user token), not the ``Host`` header. The loopback settings sidecar enforces
|
|
19
|
+
its *own* Host/Origin allow-list (see ``stdio_settings_sidecar``), independent of
|
|
20
|
+
this setting. So defaulting fastmcp's guard off on the main server restores
|
|
21
|
+
exactly the pre-3.4.3 behaviour without giving up the protection that matters.
|
|
22
|
+
|
|
23
|
+
Operators who front ha-mcp differently can re-enable the guard (and pin their
|
|
24
|
+
own allow-lists) via ``FASTMCP_HTTP_HOST_ORIGIN_PROTECTION=true`` plus
|
|
25
|
+
``FASTMCP_HTTP_ALLOWED_HOSTS`` / ``FASTMCP_HTTP_ALLOWED_ORIGINS``.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import logging
|
|
31
|
+
import os
|
|
32
|
+
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
#: fastmcp's env var for the Host/Origin (DNS-rebinding) guard. Present as a
|
|
36
|
+
#: field on fastmcp's Settings only from 3.4.3 onward.
|
|
37
|
+
HOST_ORIGIN_PROTECTION_ENV = "FASTMCP_HTTP_HOST_ORIGIN_PROTECTION"
|
|
38
|
+
|
|
39
|
+
#: fastmcp Settings attribute backing the env var above.
|
|
40
|
+
_HOST_ORIGIN_PROTECTION_ATTR = "http_host_origin_protection"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def ensure_host_origin_guard_default_off() -> None:
|
|
44
|
+
"""Default fastmcp's Host/Origin guard off for ha-mcp's Streamable-HTTP servers.
|
|
45
|
+
|
|
46
|
+
Idempotent and safe to call from every server-creation path. Call before the
|
|
47
|
+
Streamable-HTTP app is built (``mcp.http_app()`` / ``mcp.run(transport="http")``
|
|
48
|
+
/ ``mcp.run_async(...)``): ``http_app`` reads
|
|
49
|
+
``fastmcp.settings.http_host_origin_protection`` at build time, so mutating
|
|
50
|
+
that singleton beforehand deterministically neutralises the guard.
|
|
51
|
+
|
|
52
|
+
Does nothing when the running fastmcp predates the guard (the setting field is
|
|
53
|
+
absent, i.e. < 3.4.3) or when the operator set the env var explicitly (their
|
|
54
|
+
choice wins). A failed mutation is logged at WARNING and left retryable -- it
|
|
55
|
+
is not recorded as done -- so a later reload re-attempts it.
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
import fastmcp
|
|
59
|
+
except Exception: # pragma: no cover - fastmcp is a hard dependency
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
settings = getattr(fastmcp, "settings", None)
|
|
63
|
+
if settings is None or not hasattr(settings, _HOST_ORIGIN_PROTECTION_ATTR):
|
|
64
|
+
# fastmcp < 3.4.3: no guard exists, nothing to disable.
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
if getattr(settings, _HOST_ORIGIN_PROTECTION_ATTR) is False:
|
|
68
|
+
# Already off -- a prior call, or the operator's own default. Idempotent.
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
if HOST_ORIGIN_PROTECTION_ENV in os.environ:
|
|
72
|
+
# Operator explicitly opted in (guard on); honour their choice.
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
setattr(settings, _HOST_ORIGIN_PROTECTION_ATTR, False)
|
|
77
|
+
except Exception:
|
|
78
|
+
logger.warning(
|
|
79
|
+
"Could not disable fastmcp's Host/Origin (DNS-rebinding) guard; MCP "
|
|
80
|
+
"reached through a reverse proxy, tunnel, or LAN IP -- and the browser "
|
|
81
|
+
"landing page -- may fail with 421/403. Set %s=false, or pin "
|
|
82
|
+
"FASTMCP_HTTP_ALLOWED_HOSTS / FASTMCP_HTTP_ALLOWED_ORIGINS.",
|
|
83
|
+
HOST_ORIGIN_PROTECTION_ENV,
|
|
84
|
+
exc_info=True,
|
|
85
|
+
)
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
# Belt: honoured by any fresh ``Settings()`` read and by child processes. Set
|
|
89
|
+
# only after a confirmed mutation so a failed attempt stays retryable.
|
|
90
|
+
os.environ.setdefault(HOST_ORIGIN_PROTECTION_ENV, "false")
|
|
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.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/__init__.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/capture.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_entities.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_overview.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_scenes.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_scoring.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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.dev767 → ha_mcp_dev-7.9.0.dev768}/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.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/validation_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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.dev767 → ha_mcp_dev-7.9.0.dev768}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.9.0.dev767 → ha_mcp_dev-7.9.0.dev768}/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
|